aboutsummaryrefslogtreecommitdiffstats
path: root/lib/wx/api_gen
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
committerErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
commit84adefa331c4159d432d22840663c38f155cd4c1 (patch)
treebff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/wx/api_gen
downloadotp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz
otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2
otp-84adefa331c4159d432d22840663c38f155cd4c1.zip
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/wx/api_gen')
-rw-r--r--lib/wx/api_gen/Makefile74
-rw-r--r--lib/wx/api_gen/README26
-rw-r--r--lib/wx/api_gen/gen_util.erl246
-rw-r--r--lib/wx/api_gen/gl_doxygen.conf228
-rw-r--r--lib/wx/api_gen/gl_gen.erl687
-rw-r--r--lib/wx/api_gen/gl_gen.hrl41
-rw-r--r--lib/wx/api_gen/gl_gen_c.erl596
-rw-r--r--lib/wx/api_gen/gl_gen_erl.erl603
-rw-r--r--lib/wx/api_gen/gl_xml/.gitignore0
-rw-r--r--lib/wx/api_gen/glapi.conf333
-rw-r--r--lib/wx/api_gen/wx_doxygen.conf299
-rw-r--r--lib/wx/api_gen/wx_extra/bugs.h36
-rw-r--r--lib/wx/api_gen/wx_extra/wxEvtHandler.c_src66
-rw-r--r--lib/wx/api_gen/wx_extra/wxEvtHandler.erl183
-rw-r--r--lib/wx/api_gen/wx_extra/wxListCtrl.c_src24
-rw-r--r--lib/wx/api_gen/wx_extra/wxListCtrl.erl39
-rw-r--r--lib/wx/api_gen/wx_extra/wxPrintout.c_src30
-rw-r--r--lib/wx/api_gen/wx_extra/wxPrintout.erl102
-rw-r--r--lib/wx/api_gen/wx_extra/wxXmlResource.c_src3
-rw-r--r--lib/wx/api_gen/wx_extra/wxXmlResource.erl43
-rw-r--r--lib/wx/api_gen/wx_extra/wxe_evth.h25
-rw-r--r--lib/wx/api_gen/wx_gen.erl1443
-rw-r--r--lib/wx/api_gen/wx_gen.hrl88
-rw-r--r--lib/wx/api_gen/wx_gen_cpp.erl1220
-rw-r--r--lib/wx/api_gen/wx_gen_erl.erl1272
-rw-r--r--lib/wx/api_gen/wx_xml/.gitignore0
-rw-r--r--lib/wx/api_gen/wxapi.conf1777
27 files changed, 9484 insertions, 0 deletions
diff --git a/lib/wx/api_gen/Makefile b/lib/wx/api_gen/Makefile
new file mode 100644
index 0000000000..c6b65b60bc
--- /dev/null
+++ b/lib/wx/api_gen/Makefile
@@ -0,0 +1,74 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2008-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+ERLC = erlc
+ERL = erl
+EBIN = .
+
+# make WXGTK_DIR=/wxWidgets-2.8.5/include
+WXGTK_DIR = /usr/include/wx-2.8
+#WXGTK_DIR = /opt/wxgtk2.8.9/include/wx-2.8
+GL_DIR = /usr/include/GL
+
+ERL_COMPILE_FLAGS=+debug_info +warn_unused_vars
+
+COMPILER = gen_util wx_gen wx_gen_erl wx_gen_cpp
+COMPILER_T = $(COMPILER:%=$(EBIN)/%.beam)
+
+GL_COMP = gl_gen gl_gen_erl gl_gen_c
+GL_COMP_T = $(GL_COMP:%=$(EBIN)/%.beam)
+
+TARGET_EDIR = ../src/gen
+TARGET_CDIR = ../c_src/gen
+
+C_TARGETS = wxe_funcs.cpp
+GL_C_TARGETS = gl_funcs.cpp
+
+WX = $(TARGET_CDIR)/$(C_TARGETS)
+
+GL = $(TARGET_CDIR)/$(GL_C_TARGETS)
+
+opt: $(WX) $(GL)
+
+$(WX): wxxml_generated $(COMPILER_T) wxapi.conf $(wildcard wx_extra/wx*.c_src) $(wildcard wx_extra/wx*.erl)
+ erl -noshell -run wx_gen code
+
+wxxml_generated: wx_doxygen.conf wx_extra/bugs.h wx_extra/wxe_evth.h
+ sed -e 's|@WXGTK_DIR@|$(WXGTK_DIR)|g' wx_doxygen.conf > wx_doxygen
+ doxygen wx_doxygen && touch wxxml_generated
+
+glxml_generated: gl_doxygen.conf
+ sed -e 's|@GL_DIR@|$(GL_DIR)|g' gl_doxygen.conf > gl_doxygen
+ doxygen gl_doxygen && touch glxml_generated
+
+
+$(GL): glxml_generated $(GL_COMP_T) glapi.conf
+ erl -noshell -run gl_gen code
+
+%.beam: %.erl wx_gen.hrl gl_gen.hrl
+ $(ERLC) -W $(ERL_FLAGS) $(ERL_COMPILE_FLAGS) $< -o$(EBIN)
+
+# TODO split cleans into separate targets?
+complete_clean:
+ rm -f gl_doxygen wx_doxygen wx_xml/*.x* gl_xml/*.x*
+ rm -f glxml_generated wxxml_generated
+ $(MAKE) clean
+clean:
+ rm -f *~
+ rm -f $(COMPILER_T) $(GL_COMP_T)
+ rm -f wx_extra/*~
diff --git a/lib/wx/api_gen/README b/lib/wx/api_gen/README
new file mode 100644
index 0000000000..3c49f7b2a5
--- /dev/null
+++ b/lib/wx/api_gen/README
@@ -0,0 +1,26 @@
+API GENERATION:
+ Most of the code in wx is generated.
+ Users of wxErlang should not normally need to regenerate the generated code,
+ as it is checked in by wxErlang developers, when changes are made.
+ 2008-09-29 Code checked in is currently generated from wxwidgets 2.8.7.
+
+REQUIREMENTS:
+ The code generation requires doxygen (1.4.6) which is
+ used to parse wxWidgets c++ headers and generate xml files (in
+ wx_xml/).
+
+ (2008-09-29 doxygen 1.4.6 is required.
+ Later versions of Doxygen - up to 1.5.6 at least - have a bug in the xml generation
+ which causes us problems. This has been logged and we are waiting for a fix.)
+
+CONFIGURATION:
+ wxapi.conf contains the specification to the code generator. The code
+ generator reads the specification and parses the xml files and
+ produces the erlang and the 'C' code.
+
+ Adding/changing stuff/classes should be done by updating wxapi.conf
+ and running make. Sometimes the code generator will require changes,
+ I havn't thought of everything yet.
+
+CONTRIBUTION:
+ Send me patches or update the svn version.
diff --git a/lib/wx/api_gen/gen_util.erl b/lib/wx/api_gen/gen_util.erl
new file mode 100644
index 0000000000..d47fd579a5
--- /dev/null
+++ b/lib/wx/api_gen/gen_util.erl
@@ -0,0 +1,246 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%% Some utilities
+
+-module(gen_util).
+-compile(export_all).
+
+lowercase([F|R]) when F >= $A, F =< $Z -> [F+($a-$A)|R];
+lowercase(Str) when is_list(Str) -> Str.
+
+lowercase_all([F|R]) when F >= $A, F =< $Z -> [F+($a-$A)|lowercase_all(R)];
+lowercase_all([F|R]) -> [F|lowercase_all(R)];
+lowercase_all([]) -> [].
+
+uppercase([F|R]) when F >= $a, F =< $z -> [F+($A-$a)|R];
+uppercase(Str) when is_list(Str) -> Str.
+
+uppercase_all([F|R]) when F >= $a, F =< $z -> [F+($A-$a)|uppercase_all(R)];
+uppercase_all([A|R]) -> [A|uppercase_all(R)];
+uppercase_all([]) -> [].
+
+
+strip_name([H|R1],[H|R2]) ->
+ strip_name(R1,R2);
+strip_name(String,[]) -> String.
+
+open_write(File) ->
+ %% io:format("Generating ~s~n",[File]),
+ {ok, Fd} = file:open(File++".temp", [write]),
+ put(current_file, {Fd,File}).
+
+
+close() ->
+ case get(current_file) of
+ undefined ->
+ ok;
+ {closed, File} ->
+ io:format("Closing twice ~s~n",[File]);
+ {Fd,File} ->
+ file:close(Fd),
+ case os:cmd("diff " ++ File ++ " " ++ File ++ ".temp" ++ "| head -30") of
+ [] ->
+ ok = file:delete(File ++ ".temp"),
+ %% So that make understands that we have made this
+ case os:getenv("CLEARCASE_ROOT") of
+ false -> os:cmd("touch " ++ File);
+ _ -> ignore
+ end,
+ ok;
+ Diff ->
+ case check_diff(Diff) of
+ copyright -> %% We ignore copyright changes only
+ ok = file:delete(File ++ ".temp");
+ _ ->
+ io:format("Diff in ~s~n~s ~n", [File, Diff]),
+ case file:rename(File ++ ".temp", File) of
+ ok -> ok;
+ _ ->
+ io:format("***** Failed to save file ~p ~n",[File])
+ end
+ end
+ end,
+ put(current_file, {closed, File})
+ end.
+
+
+check_diff(Diff) ->
+ try
+ [_,D1,_,D2|Tail] = re:split(Diff, "\n"),
+ case Tail of
+ [] -> ok;
+ [<<>>] -> ok;
+ _ -> throw(diff)
+ end,
+ <<_, _, "%% Copyright", _/binary>> = D1,
+ <<_, _, "%% Copyright", _/binary>> = D2,
+ copyright
+ catch
+ throw:_ -> diff;
+ error:{badmatch,_} ->
+ diff;
+ _:What ->
+ io:format("~p:~p: ~p ~p~n", [?MODULE,?LINE, What, erlang:get_stacktrace()]),
+ diff
+ end.
+
+w(Str) ->
+ w(Str, []).
+w(Str,Args) ->
+ {Fd,_} = get(current_file),
+ io:format(Fd, Str, Args).
+
+args(Fun, Limit, List) ->
+ args(Fun, Limit, List, infinity, 0).
+
+args(Fun, Limit, List, Max) ->
+ args(Fun, Limit, List, Max, 0).
+
+args(_Fun, _Limit, [], _Max, _) -> ""; %% No args
+args(Fun, _Limit, [Last], _Max, _Pos) ->
+ case Fun(Last) of
+ skip -> ""; %% FIXME bug if last skips
+ Str -> Str
+ end;
+args(Fun, Limit, [H|R], Max, Pos) ->
+ case Fun(H) of
+ skip -> args(Fun,Limit,R, Max, Pos);
+ Str ->
+ {NL, NewPos} =
+ case length(Str) + Pos of
+ Curr when Curr > Max ->
+ {"\n ", 0};
+ Curr ->
+ {"", Curr}
+ end,
+ case args(Fun,Limit,R, Max, NewPos) of
+ "" -> Str;
+ End -> Str ++ Limit ++ NL ++ End
+ end
+ end.
+
+
+
+
+tokens(S) ->
+ tokens1(S, " \t\r\n(){}*;,@", []).
+tokens(S,Seps) ->
+ tokens1(S, Seps, []).
+
+tokens1([C|S], Seps, Toks) ->
+ case lists:member(C, Seps) of
+ true -> tokens1(S, Seps, [C|Toks]);
+ false -> tokens2(S, Seps, Toks, [C])
+ end;
+tokens1([], _Seps, Toks) ->
+ replace_and_remove(Toks, []).
+
+tokens2([C|S], Seps, Toks, Cs) ->
+ case lists:member(C, Seps) of
+ true -> tokens1(S, Seps, [C, lists:reverse(Cs) |Toks]);
+ false -> tokens2(S, Seps, Toks, [C|Cs])
+ end;
+tokens2([], _Seps, Toks, Cs) ->
+ replace_and_remove([lists:reverse(Cs)|Toks], []).
+
+replace_and_remove([E|R], Acc) when is_list(E) -> %% Keep everything that is a word
+ replace_and_remove(R, [E|Acc]);
+replace_and_remove([$\n | R], Acc) -> %% It is semi line oriented so keep eol
+ replace_and_remove(R, [eol|Acc]);
+replace_and_remove([$( | R], Acc) ->
+ replace_and_remove(R, ["("|Acc]);
+replace_and_remove([$) | R], Acc) ->
+ replace_and_remove(R, [")"|Acc]);
+replace_and_remove([${ | R], Acc) ->
+ replace_and_remove(R, ["{"|Acc]);
+replace_and_remove([$} | R], Acc) ->
+ replace_and_remove(R, ["}"|Acc]);
+replace_and_remove([$| | R], Acc) ->
+ replace_and_remove(R, ["|"|Acc]);
+replace_and_remove([$* | R], Acc) ->
+ replace_and_remove(R, ["*"|Acc]);
+replace_and_remove([$& | R], Acc) ->
+ replace_and_remove(R, [$&|Acc]);
+replace_and_remove([$<,$< | R], Acc) ->
+ replace_and_remove(R, ["<<"|Acc]);
+replace_and_remove([$, | R], Acc) ->
+ replace_and_remove(R, [cont|Acc]);
+replace_and_remove([$; | R], Acc) ->
+ replace_and_remove(R, [eoe|Acc]);
+replace_and_remove([$@ | R], Acc) ->
+ replace_and_remove(R, [directive|Acc]);
+
+replace_and_remove([_E|R], Acc) -> %% Ignore everthing else
+ replace_and_remove(R, Acc);
+replace_and_remove([], Acc) ->
+ Acc.
+
+halt(Reason) ->
+ case process_info(group_leader(), status) of
+ {_,waiting} ->
+ %% Now all output data is down in the driver.
+ %% Give the driver some extra time before halting.
+ receive after 10 -> ok end,
+ erlang:halt(Reason);
+ _ ->
+ %% Probably still processing I/O requests.
+ receive after 20 -> ok end,
+ gen_util:halt(Reason)
+ end.
+
+erl_copyright() ->
+ w("%%~n",[]),
+ w("%% %CopyrightBegin%~n",[]),
+ w("%% ~n",[]),
+ w("%% Copyright Ericsson AB 2008-2009. All Rights Reserved.~n",[]),
+ w("%% ~n",[]),
+ w("%% The contents of this file are subject to the Erlang Public License,~n",[]),
+ w("%% Version 1.1, (the \"License\"); you may not use this file except in~n",[]),
+ w("%% compliance with the License. You should have received a copy of the~n",[]),
+ w("%% Erlang Public License along with this software. If not, it can be~n",[]),
+ w("%% retrieved online at http://www.erlang.org/.~n",[]),
+ w("%% ~n",[]),
+ w("%% Software distributed under the License is distributed on an \"AS IS\"~n",[]),
+ w("%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See~n",[]),
+ w("%% the License for the specific language governing rights and limitations~n",[]),
+ w("%% under the License.~n",[]),
+ w("%% ~n",[]),
+ w("%% %CopyrightEnd%~n",[]).
+
+c_copyright() ->
+ w("/*~n",[]),
+ w(" * %CopyrightBegin%~n",[]),
+ w(" * ~n",[]),
+ w(" * Copyright Ericsson AB 2008-2009. All Rights Reserved.~n",[]),
+ w(" * ~n",[]),
+ w(" * The contents of this file are subject to the Erlang Public License,~n",[]),
+ w(" * Version 1.1, (the \"License\"); you may not use this file except in~n",[]),
+ w(" * compliance with the License. You should have received a copy of the~n",[]),
+ w(" * Erlang Public License along with this software. If not, it can be~n",[]),
+ w(" * retrieved online at http://www.erlang.org/.~n",[]),
+ w(" * ~n",[]),
+ w(" * Software distributed under the License is distributed on an \"AS IS\"~n",[]),
+ w(" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See~n",[]),
+ w(" * the License for the specific language governing rights and limitations~n",[]),
+ w(" * under the License.~n",[]),
+ w(" * ~n",[]),
+ w(" * %CopyrightEnd% ~n",[]),
+ w("*/~n",[]).
+
+
diff --git a/lib/wx/api_gen/gl_doxygen.conf b/lib/wx/api_gen/gl_doxygen.conf
new file mode 100644
index 0000000000..e29a3654b5
--- /dev/null
+++ b/lib/wx/api_gen/gl_doxygen.conf
@@ -0,0 +1,228 @@
+# Doxyfile 1.4.3
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = wxe
+PROJECT_NUMBER = 0.1
+OUTPUT_DIRECTORY = ./
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+USE_WINDOWS_ENCODING = NO
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF =
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH =
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP = NO
+INHERIT_DOCS = YES
+DISTRIBUTE_GROUP_DOC = NO
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 8
+ALIASES =
+OPTIMIZE_OUTPUT_FOR_C = YES
+OPTIMIZE_OUTPUT_JAVA = NO
+SUBGROUPING = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = YES
+EXTRACT_STATIC = YES
+EXTRACT_LOCAL_CLASSES = YES
+EXTRACT_LOCAL_METHODS = YES
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = YES
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = NO
+INLINE_INFO = NO
+SORT_MEMBER_DOCS = NO
+SORT_BRIEF_DOCS = NO
+SORT_BY_SCOPE_NAME = NO
+GENERATE_TODOLIST = NO
+GENERATE_TESTLIST = NO
+GENERATE_BUGLIST = NO
+GENERATE_DEPRECATEDLIST= NO
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_DIRECTORIES = YES
+FILE_VERSION_FILTER =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = YES
+WARNINGS = NO
+WARN_IF_UNDOCUMENTED = NO
+WARN_IF_DOC_ERROR = NO
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = @GL_DIR@/gl.h @GL_DIR@/glext.h @GL_DIR@/glu.h
+#INPUT = /usr/include/GL/gl.h /usr/include/GL/glext.h /usr/include/GL/glu.h
+RECURSIVE = YES
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+USE_HTAGS = NO
+VERBATIM_HEADERS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = NO
+HTML_OUTPUT = html
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = NO
+ENUM_VALUES_PER_LINE = 4
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = NO
+USE_PDFLATEX = NO
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = YES
+XML_OUTPUT = ./gl_xml/
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = NO
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED = \
+ APIENTRY="" \
+ WINGDIAPI="" \
+ GLAPI="" \
+ GL_GLEXT_PROTOTYPES="1"
+
+EXPAND_AS_DEFINED = YES
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH = /bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = NO
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = NO
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+TEMPLATE_RELATIONS = NO
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = NO
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+DOT_PATH =
+DOTFILE_DIRS =
+MAX_DOT_GRAPH_WIDTH = 1024
+MAX_DOT_GRAPH_HEIGHT = 1024
+MAX_DOT_GRAPH_DEPTH = 0
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
+
diff --git a/lib/wx/api_gen/gl_gen.erl b/lib/wx/api_gen/gl_gen.erl
new file mode 100644
index 0000000000..91a6a1adbf
--- /dev/null
+++ b/lib/wx/api_gen/gl_gen.erl
@@ -0,0 +1,687 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%%-------------------------------------------------------------------
+%%% File : gl_gen.erl
+%%% Author : Dan Gudmundsson <[email protected]>
+%%% Description :
+%%%
+%%% Created : 16 Apr 2007 by Dan Gudmundsson <[email protected]>
+%%%-------------------------------------------------------------------
+-module(gl_gen).
+
+-export([code/0]).
+
+-include_lib("xmerl/include/xmerl.hrl").
+-include("gl_gen.hrl").
+
+-import(lists, [foldl/3,foldr/3,reverse/1,reverse/2,keysearch/3,map/2,filter/2]).
+-import(proplists, [get_value/2,get_value/3]).
+
+-import(gen_util,[uppercase_all/1]).
+
+-compile(export_all).
+
+code() -> safe(fun gen_code/0,true).
+
+devcode() -> spawn(fun() -> safe(fun gen_code/0,false) end).
+
+safe(What, QuitOnErr) ->
+ try
+ What(),
+ io:format("Completed succesfully~n~n", []),
+ QuitOnErr andalso gen_util:halt(0)
+ catch Err:Reason ->
+ catch gen_util:close(),
+ io:format("Error ~p: ~p:~p~n ~p~n",
+ [get(current_func),Err,Reason,erlang:get_stacktrace()]),
+ timer:sleep(1999),
+ QuitOnErr andalso gen_util:halt(1)
+ end.
+
+gen_code() ->
+ {ok, Opts0} = file:consult("glapi.conf"),
+ erase(func_id),
+ Opts = init_defs(Opts0),
+ GLUDefs = parse_glu_defs(Opts),
+ GLDefs = parse_gl_defs(Opts),
+ {GLUDefines,GLUFuncs} = setup(GLUDefs, Opts),
+ {GLDefines,GLFuncs} = setup(GLDefs, Opts),
+ gl_gen_erl:glu_defines(GLUDefines),
+ gl_gen_erl:glu_api(GLUFuncs),
+
+ gl_gen_erl:gl_defines(GLDefines),
+ gl_gen_erl:gl_api(GLFuncs),
+ gl_gen_erl:gen_debug(GLFuncs,GLUFuncs),
+ gl_gen_c:gen(GLFuncs,GLUFuncs),
+ ok.
+
+init_defs(Opts0) ->
+ Opts0.
+
+parse_glu_defs(Opts0) ->
+ All = foldl(fun(File, Acc) -> load_file(File,Opts0,Acc) end, [], ["glu"]),
+ reverse(All).
+
+parse_gl_defs(Opts0) ->
+ All = foldl(fun(File, Acc) -> load_file(File,Opts0,Acc) end, [], ["gl","glext"]),
+ reverse(All).
+
+load_file(FileName, Opts, Acc) ->
+ File = filename:join(["gl_xml",FileName ++ "_8h.xml"]),
+ put({loaded, FileName}, true),
+ case xmerl_scan:file(File, [{space, normalize}]) of
+ {error, enoent} ->
+ io:format("Skipped File not found ~p ~n", [File]),
+ Acc;
+ {Doc, _} ->
+ io:format("Scanning ~p ~n", [File]),
+ %% It's duplicated in xml get sectiondef only once.
+ Content = find_data(Doc#xmlElement.content),
+ lists:foreach(fun(D) -> extract_argnames(D) end, Content),
+ foldl(fun(Data,Acc0) -> parse_file(Data, Opts, Acc0) end,
+ Acc, Content)
+ end.
+
+extract_argnames(#xmlElement{name=memberdef,attributes=Attr,content=C}) ->
+ case keysearch(kind, #xmlAttribute.name, Attr) of
+ {value, #xmlAttribute{value = "typedef"}} ->
+ parse_typedef(C,undefined);
+ _ ->
+ ok
+ end;
+extract_argnames(_) -> ok.
+
+parse_typedef([#xmlElement{name=argsstring,content=[#xmlText{value=AS}]}|R],_) ->
+ parse_typedef(R,AS);
+parse_typedef([#xmlElement{name=name}|_],undefined) ->
+ skip;
+parse_typedef([#xmlElement{name=name,content=[#xmlText{value=N}]}|_],AS) ->
+ Args0 = string:tokens(AS," ,()*[]"),
+ try
+ Args = get_arg_names(Args0),
+ put({typedef,string:strip(N)},Args)
+ catch _:Where ->
+ io:format("Error ~p: ~p ~p~n", [N,Args0,Where]),
+ ?error(arg_names)
+ end;
+parse_typedef([_|R],AS) ->
+ parse_typedef(R,AS);
+parse_typedef([],_) -> skip.
+
+get_arg_names(As0) ->
+ Args = lists:filter(fun("const") -> false; (_) -> true end, As0),
+ get_arg_names(Args, []).
+
+get_arg_names([_Type,Name|R],Acc) ->
+ get_arg_names(R, [Name|Acc]);
+get_arg_names([],Acc) -> reverse(Acc);
+get_arg_names(["void"],[]) -> [];
+get_arg_names(Error,_Acc) -> exit(Error).
+
+%% Avoid bugs in (old) doxygen..the new one doesn't have 'em
+find_data([#xmlElement{name=compounddef, content=C}|_]) -> find_data(C);
+find_data([#xmlElement{name=sectiondef, attributes=Attr, content=C}|R]) ->
+ case keysearch(kind, #xmlAttribute.name, Attr) of
+ {value, _} -> %% The new one have func define typedef
+ find_data(R) ++ C;
+ false ->
+ C
+ end;
+find_data([_Hmm|R]) ->
+%% case _Hmm of
+%% #xmlElement{} ->
+%% io:format("0 ~p ~n",[_Hmm#xmlElement.name]);
+%% _ ->
+%% ok
+%% end,
+ find_data(R);
+find_data([]) -> [].
+
+parse_file(#xmlElement{name=memberdef,attributes=Attr, content=C}, Opts, Acc) ->
+ case keysearch(kind, #xmlAttribute.name, Attr) of
+ {value, #xmlAttribute{value = "function"}} ->
+ try
+ Def = parse_func(C, Opts),
+ [Def|Acc]
+ catch throw:skip -> Acc
+ after erase(current_func)
+ end;
+ {value, #xmlAttribute{value = "define"}} ->
+ try
+ Def = parse_define(C, #def{}, Opts),
+ [Def|Acc]
+ catch throw:skip -> Acc
+ end;
+ {value, #xmlAttribute{value = "typedef"}} ->
+ Acc;
+ _W ->
+ io:format("Hmm ~p~n",[_W]),
+ Acc
+ end;
+parse_file(_Hmm,_,Acc) ->
+ Acc.
+
+parse_define([#xmlElement{name=name,content=[#xmlText{value="API" ++ _}]}|_],_Def,_Os) ->
+ throw(skip);
+parse_define([#xmlElement{name=name,content=[#xmlText{value="GLAPI"++_}]}|_],_Def,_Os) ->
+ throw(skip);
+parse_define([#xmlElement{name=name,content=[#xmlText{value="WINGDIAPI"++_}]}|_],_Def,_Os) ->
+ throw(skip);
+parse_define([#xmlElement{name=name,content=[#xmlText{value=Name}]}|R], Def, Os) ->
+ parse_define(R, Def#def{name=Name}, Os);
+parse_define([#xmlElement{name=initializer,content=[#xmlText{value=V}]}|_],Def,_Os) ->
+ Val0 = string:strip(V),
+ try
+ case Val0 of
+ "0x" ++ Val1 ->
+ Val = http_util:hexlist_to_integer(Val1),
+ Def#def{val=Val, type=hex};
+ _ ->
+ Val = list_to_integer(Val0),
+ Def#def{val=Val, type=int}
+ end
+ catch _:_ ->
+ Def#def{val=Val0, type=string}
+ end;
+parse_define([_|R], D, Opts) ->
+ parse_define(R, D, Opts);
+parse_define([], D, _Opts) ->
+ D.
+
+parse_func(Xml, Opts) ->
+ {Func,_} = foldl(fun(X,Acc) -> parse_func(X,Acc,Opts) end, {#func{},1}, Xml),
+ #func{params=Args0,type=Type0} = Func,
+ Args = filter(fun(#arg{type=void}) -> false; (_) -> true end, Args0),
+ #arg{type=Type} =
+ patch_param(Func#func.name,#arg{name="result",type=Type0},Opts),
+ Func#func{params=reverse(Args), type=Type}.
+
+parse_func(#xmlElement{name=type, content=C}, {F,AC}, Os) ->
+ Type = parse_type(drop_empty(C), Os),
+ {F#func{type=Type},AC};
+parse_func(#xmlElement{name=name, content=[#xmlText{value=C}]},{F,AC},Os) ->
+ Func = string:strip(C),
+ put(current_func, Func),
+ {F#func{name=name(Func,Os)},AC};
+parse_func(#xmlElement{name=param, content=C},{F,AC},Os) ->
+ Parse = fun(Con, Ac) -> parse_param(Con, Ac, Os) end,
+ Param0 = foldl(Parse, #arg{}, drop_empty(C)),
+ Param = fix_param_name(Param0, F, AC),
+ {add_param(Param, Os, F),AC+1};
+parse_func(_, F,_) ->
+ F.
+
+fix_param_name(A=#arg{name=undefined,type=T},#func{name=Func},Count) ->
+ TDName = "PFN" ++ uppercase_all(Func) ++ "PROC",
+ case get({typedef,TDName}) of
+ undefined when T == void ->
+ A;
+ undefined ->
+ io:format("Didn't find typedef for: ~s~n", [TDName]),
+ exit(aargh);
+ AS ->
+ try A#arg{name = lists:nth(Count, AS)}
+ catch _:_ -> A
+ end
+ end;
+fix_param_name(A,_,_) -> A.
+
+parse_param(#xmlElement{name=type,content=C}, Arg, Os) ->
+ Arg#arg{type=parse_type(drop_empty(C),Os)};
+parse_param(#xmlElement{name=declname,content=[C]},Arg,_Os) ->
+ #xmlText{value=Name} = C,
+ Arg#arg{name=Name};
+parse_param(#xmlElement{name=array,content=[#xmlText{value=C}]},
+ Arg=#arg{type=Type0},_Os) ->
+ try
+ [Int] = string:tokens(C, "[] "),
+ Val = list_to_integer(Int),
+ Arg#arg{type=Type0#type{single={tuple,Val}, by_val=true}}
+ catch _:_ ->
+ ?warning("Undefined Array size ~p in ~p ~p~n",
+ [Arg, get(current_func), C]),
+ Arg#arg{type=Type0#type{single={tuple,undefined}, by_val=true}}
+ end;
+
+%% Skip these
+parse_param(#xmlElement{name=definition}, Arg, _) -> Arg;
+parse_param(#xmlElement{name=argsstring}, Arg,_) -> Arg;
+parse_param(#xmlElement{name=briefdescription}, Arg,_) -> Arg;
+parse_param(#xmlElement{name=detaileddescription}, Arg,_) -> Arg;
+parse_param(#xmlElement{name=inbodydescription}, Arg,_) -> Arg;
+parse_param(#xmlElement{name=location}, Arg,_) -> Arg;
+parse_param(Other, Arg,_) ->
+ io:format("Unhandled Param ~p ~n in ~p~n", [Other,Arg]),
+ ?error(unhandled_param).
+
+add_param(Arg0=#arg{type=T0}, Opts, F=#func{name=Name,params=Args}) ->
+ Arg = case T0 of
+%% #type{mod=[const],ref={pointer,1},name="GLubyte"} ->
+%% Arg0#arg{type=T0#type{base=binary}};
+ #type{mod=[const]} -> Arg0; %% In is true default
+ #type{ref={pointer,_}} -> Arg0#arg{in=false,
+ type=T0#type{single=undefined}};
+ _ -> Arg0
+ end,
+ Patched = patch_param(Name,Arg,Opts),
+ F#func{params=[Patched|Args]}.
+
+patch_param(Method,P = #arg{name=ArgName},AllOpts) ->
+ %%io:format("~p ~n", [Method]),
+ case lookup(Method,AllOpts,undefined) of
+ undefined -> P;
+ What ->
+ %% io:format("~p ~p => ~p~n", [Method, ArgName, What]),
+ case What of
+ {ArgName,Fopt} when is_list(Fopt) ->
+ foldl(fun handle_arg_opt/2,P,Fopt);
+ {ArgName,Fopt} ->
+ handle_arg_opt(Fopt,P);
+ {_,_} -> P;
+ Opts when is_list(Opts) ->
+ case get_value(ArgName, Opts, undefined) of
+ undefined -> P;
+ List when is_list(List) ->
+ foldl(fun handle_arg_opt/2,P,List);
+ Val ->
+ handle_arg_opt(Val,P)
+ end
+ end
+ end.
+
+handle_arg_opt(skip, P) -> P#arg{where=c};
+%%handle_arg_opt(nowhere, P) -> P#arg{where=nowhere};
+%%handle_arg_opt(skip_member, _P) -> throw(skip_member);
+handle_arg_opt(in, P) -> P#arg{in=true};
+handle_arg_opt(out, P) -> P#arg{in=false};
+handle_arg_opt(both, P) -> P#arg{in=both};
+handle_arg_opt(binary, P=#arg{type=T}) ->
+ P#arg{type=T#type{size=undefined,base=binary}};
+handle_arg_opt({binary,Sz}, P=#arg{type=T}) ->
+ P#arg{type=T#type{size=Sz,base=binary}};
+handle_arg_opt({type,Type}, P=#arg{type=T}) -> P#arg{type=T#type{name=Type}};
+handle_arg_opt({single,Opt},P=#arg{type=T}) -> P#arg{type=T#type{single=Opt}};
+handle_arg_opt({base,Opt}, P=#arg{type=T}) -> P#arg{type=T#type{base=Opt}};
+handle_arg_opt({c_only,Opt},P) -> P#arg{where=c, alt=Opt}.
+
+parse_type([], _Os) -> void;
+parse_type(C, Os) ->
+ {Type,_Info} = foldl(fun extract_type_info/2,{[],undefined},C),
+ Empty = #type{},
+ case parse_type2(reverse(Type),Empty,Os) of
+ Empty -> ?error({strange_type, Type});
+ Assert -> Assert
+ end.
+
+extract_type_info(#xmlText{value=Value}, {Acc, Info}) ->
+ {reverse(foldl(fun extract_type_info2/2, [],
+ string:tokens(Value, " "))) ++ Acc, Info};
+extract_type_info(#xmlElement{name=ref,attributes=As,
+ content=[#xmlText{value=V}]},
+ {Acc,undefined}) ->
+ {value, #xmlAttribute{value = Refid}} =
+ keysearch(refid,#xmlAttribute.name,As),
+ {value, #xmlAttribute{value = Kind}} =
+ keysearch(kindref,#xmlAttribute.name,As),
+ {reverse(foldl(fun extract_type_info2/2, [],
+ string:tokens(V, " "))) ++ Acc,
+ {Kind,Refid}};
+extract_type_info(What,Acc) ->
+ ?error({parse_error,What,Acc}).
+
+extract_type_info2("const",Acc) -> [const|Acc];
+extract_type_info2("*", [{by_ref,{pointer,N}}|Acc]) ->
+ [{by_ref,{pointer,N+1}}|Acc];
+extract_type_info2("*", Acc) -> [{by_ref,{pointer,1}}|Acc];
+extract_type_info2("**", Acc) -> [{by_ref,{pointer,2}}|Acc];
+extract_type_info2(Type, Acc) -> [Type|Acc].
+
+parse_type2(["void"], _T, _Opts) -> void;
+parse_type2([N="void"|R], T, Opts) ->
+ parse_type2(R,T#type{name=N},Opts);
+parse_type2([const|R],T=#type{mod=Mod},Opts) ->
+ parse_type2(R,T#type{mod=[const|Mod]},Opts);
+parse_type2(["unsigned"|R],T=#type{mod=Mod},Opts) ->
+ parse_type2(R,T#type{mod=[unsigned|Mod]},Opts);
+parse_type2([N="GLenum"|R],T,Opts) ->
+ parse_type2(R,T#type{name=N, size=4, base=int},Opts);
+parse_type2([N="GLboolean"|R],T,Opts) ->
+ parse_type2(R,T#type{name=N, size=1, base=bool},Opts);
+parse_type2([N="GLbitfield"|R],T,Opts) ->
+ parse_type2(R,T#type{name=N, size=4, base=int},Opts);
+parse_type2([N="GLvoid"|R],T,Opts) ->
+ parse_type2(R,T#type{name=N, base=idx_binary},Opts);
+
+parse_type2([N="GLbyte"|R],T,Opts) ->
+ parse_type2(R,T#type{name=N, size=1, base=int},Opts);
+parse_type2([N="GLubyte"|R],T,Opts) ->
+ parse_type2(R,T#type{name=N, size=1, base=int},Opts);
+parse_type2([N="GLshort"|R],T,Opts) ->
+ parse_type2(R,T#type{name=N, size=2, base=int},Opts);
+parse_type2([N="GLushort"|R],T,Opts) ->
+ parse_type2(R,T#type{name=N, size=2, base=int},Opts);
+parse_type2([N="GLint"|R],T,Opts) ->
+ parse_type2(R,T#type{name=N, size=4, base=int},Opts);
+parse_type2([N="GLuint"|R],T,Opts) ->
+ parse_type2(R,T#type{name=N, size=4, base=int},Opts);
+parse_type2([N="GLsizei"|R],T,Opts) ->
+ parse_type2(R,T#type{name=N, size=4, base=int},Opts);
+
+parse_type2([N="GLfloat"|R],T,Opts) ->
+ parse_type2(R,T#type{name=N, size=4,base=float},Opts);
+parse_type2([N="GLdouble"|R],T,Opts) ->
+ parse_type2(R,T#type{name=N, size=8,base=float},Opts);
+parse_type2([N="GLclampf"|R],T,Opts) ->
+ parse_type2(R,T#type{name=N, size=4,base=float},Opts);
+parse_type2([N="GLclampd"|R],T,Opts) ->
+ parse_type2(R,T#type{name=N, size=8,base=float},Opts);
+parse_type2([N="GLhandleARB"|R],T,Opts) ->
+ parse_type2(R,T#type{name=N, size=8,base=int},Opts);
+parse_type2(["GLchar" ++ _ARB|R],T,Opts) ->
+ parse_type2(R,T#type{name="GLchar",size=1,base=string},Opts);
+parse_type2(["GLUquadric"|R],T,Opts) ->
+ parse_type2(R,T#type{name="GLUquadric",size=8,base=int},Opts);
+parse_type2(["GLintptr" ++ _ARB|R],T,Opts) ->
+ parse_type2(R,T#type{name="GLintptr",size=8,base=int},Opts);
+parse_type2(["GLsizeiptr" ++ _ARB|R],T,Opts) ->
+ parse_type2(R,T#type{name="GLsizeiptr",size=8,base=int},Opts);
+
+parse_type2([{by_ref,Ref}|R],T,Opts) ->
+ parse_type2(R,T#type{ref=Ref,by_val=false},Opts);
+
+%% Let type errors be seen later because we don't know if these unhandled types
+%% will be used.
+parse_type2(_A = [Name|R],T,Opts) ->
+%% io:format("unhandled ~p ~p ~n",[_A,T]),
+ New = T#type{name={unhandled,Name,get(current_func)}},
+ parse_type2(R,New,Opts);
+parse_type2([], T, _) -> T.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Function mangling %%
+
+setup(Defs,Opts) ->
+ {Fs0,Ds0} =
+ foldr(fun(F=#func{name=N},{Fs,Ds}) ->
+ case put(N,F) of
+ undefined ->
+ {[N|Fs],Ds};
+ _ -> %% Duplicate
+ {Fs,Ds}
+ end;
+ (D=#def{}, {Fs,Ds}) ->
+ {Fs,[D|Ds]}
+ end, {[],[]}, Defs),
+ Fs = setup_functions(Fs0,Opts,[]),
+ erase(current_func),
+ %% Remove duplicates but keep order
+ {Ds,_} = foldl(fun(D=#def{name=Name},{Keep,Defined}) ->
+ case gb_sets:is_member(Name,Defined) of
+ true -> {Keep,Defined};
+ false -> {[D|Keep],gb_sets:add(Name,Defined)}
+ end
+ end, {[],gb_sets:empty()}, Ds0),
+ {reverse(Ds),Fs}.
+
+setup_functions([F0|Defs],Opts,Acc) ->
+ put(current_func, F0),
+ {Name, Ext} = get_extension(F0,Opts),
+ %%io:format("~p = ~p + ~p~n", [F0, Name, Ext]),
+ Skip = (not keep(F0,Opts)) andalso (skip(F0,Opts) orelse skip(Ext,Opts)),
+ case Skip of
+ true ->
+ setup_functions(Defs,Opts,Acc);
+ false ->
+ case setup_extension(Name,Ext,Opts) of
+ skip ->
+ setup_functions(Defs,Opts,Acc);
+ New ->
+ setup_functions(Defs,Opts,[New|Acc])
+ end
+ end;
+setup_functions([],_, Acc) -> reverse(Acc).
+
+setup_extension(Name,"",Opts) ->
+ setup_vector_variant(Name,"",Opts);
+setup_extension(Name,Ext,Opts) ->
+ case get(Name) of
+ undefined ->
+ setup_vector_variant(Name,Ext,Opts);
+ OrigF = #func{} ->
+ F = get(Name++Ext),
+ case is_equal(F,OrigF) of
+ true ->
+ put(Name, OrigF#func{ext={ext,Ext}}),
+ skip;
+ _ ->
+ setup_vector_variant(Name,Ext,Opts)
+ end
+ end.
+
+setup_vector_variant(Name,Ext,Opts) ->
+ case reverse(Name) of
+ [$v|NoVec] -> %% Hmm might be a vector version
+ RealName = reverse(NoVec,Ext),
+ case get(RealName) of
+ undefined ->
+ setup_idx_binary(Name,Ext,Opts);
+ Real = #func{} ->
+ verify_args(Name,Ext,Real,RealName,Opts)
+ end;
+ _ ->
+ setup_idx_binary(Name,Ext,Opts)
+ end.
+
+verify_args(Name,Ext,Real = #func{params=RAs},RealName,Opts) ->
+ FuncName = Name ++ Ext,
+ Vector = #func{params=Args} = get(FuncName),
+ case is_vector(Name,Opts) of
+ false ->
+ Check = fun(#arg{type=#type{name=Type}},Acc) ->
+ if Type =:= Acc -> Acc;
+ Acc =:= undefined -> Type;
+ true -> different
+ end
+ end,
+ case foldl(Check,undefined,RAs) of
+ different ->
+ setup_idx_binary(Name,Ext,Opts);
+ undefined ->
+ setup_idx_binary(Name,Ext,Opts);
+ _ when length(Args) =/= 1 ->
+ setup_idx_binary(Name,Ext,Opts);
+ _Type ->
+ put(FuncName,Vector#func{where=erl,alt={vector,0,RealName}}),
+ put(RealName,Real#func{alt={has_vector,0,FuncName}}),
+ Name++Ext
+ end;
+ VecPos ->
+ put(FuncName,Vector#func{where=erl,alt={vector,VecPos,RealName}}),
+ put(RealName,Real#func{alt={has_vector,VecPos,FuncName}}),
+ Name++Ext
+ end.
+
+is_vector(Name, Opts) ->
+ Vecs = get_value(vector, Opts, []),
+ lookup(Name, Vecs, false).
+
+lookup(Name,[{Vector, VecPos}|R],Def) when is_list(Vector) ->
+ case lists:prefix(Vector,Name) of
+ true ->
+ %% VecPos;
+ %%io:format("~s ~s => ~p ~n", [Vector,Name,VecPos]),
+ case Vector == Name of
+ true ->
+ VecPos;
+ false -> %% Look for exactly the correct Name
+ case lookup(Name,R,Def) of
+ Def -> VecPos;
+ Other -> Other
+ end
+ end;
+ false -> lookup(Name,R, Def)
+ end;
+lookup(Name,[_|R],Def) ->
+ lookup(Name,R,Def);
+lookup(_,[], Def) -> Def.
+
+setup_idx_binary(Name,Ext,_Opts) ->
+ FuncName = Name ++ Ext,
+ Func = #func{params=Args} = get(FuncName),
+ Id = next_id(function),
+
+ %% Ok warn if single is undefined
+ lists:foreach(fun(#arg{type=#type{base=memory}}) -> ok;
+ (#arg{type=#type{base=idx_binary}}) -> ok;
+ (#arg{type=#type{name="GLUquadric"}}) -> ok;
+ (A=#arg{type=#type{single=undefined}}) ->
+ ?warning("~p Unknown size of~n ~p~n",
+ [get(current_func),A]),
+ io:format("{~p, {~p, }}.~n",
+ [get(current_func),A#arg.name]),
+ ok;
+ (_) -> ok
+ end, Args),
+
+ case setup_idx_binary(Args, []) of
+ ignore ->
+ put(FuncName, Func#func{id=Id}),
+ Name++Ext;
+ {bin, A1,A2} ->
+ put(FuncName, Func#func{id=Id,params=A1}),
+ Extra = FuncName++"Bin",
+ put(Extra, Func#func{params=A2, id=next_id(function)}),
+ [FuncName,Extra];
+ {matrix, A1,A2} ->
+ put(FuncName, Func#func{id=Id,params=A2}),
+ Extra = FuncName++"Matrix",
+ put(Extra, Func#func{where=erl, params=A1, id=Id}),
+ [FuncName,Extra]
+ end.
+
+setup_idx_binary([A=#arg{in=true,type=T=#type{base=idx_binary}}|R], Acc) ->
+ A1 = A#arg{type=T#type{base=guard_int,size=4}},
+ A2 = A#arg{type=T#type{base=binary}},
+ Head = reverse(Acc),
+ case setup_idx_binary(R, []) of
+ ignore ->
+ {bin, Head ++ [A1|R], Head ++ [A2|R]};
+ {bin, R1,R2} ->
+ {bin, Head ++ [A1|R1], Head ++ [A2|R2]}
+ end;
+setup_idx_binary([A=#arg{in=true,type=T=#type{single={tuple,matrix}}}|R], Acc) ->
+ A1 = A#arg{type=T#type{single={tuple, matrix12}}},
+ A2 = A#arg{type=T#type{single={tuple, 16}}},
+ Head = reverse(Acc),
+ case setup_idx_binary(R, []) of
+ ignore ->
+ {matrix, Head ++ [A1|R], Head ++ [A2|R]};
+ {matrix, R1,R2} ->
+ {matrix, Head ++ [A1|R1], Head ++ [A2|R2]}
+ end;
+setup_idx_binary([H|R],Acc) ->
+ setup_idx_binary(R,[H|Acc]);
+setup_idx_binary([],_) -> ignore.
+
+is_equal(F1=#func{type=T1,params=A1},F2=#func{type=T2,params=A2}) ->
+ Equal = is_equal_type(T1,T2) andalso is_equal_args(A1,A2),
+ case Equal of
+ true -> ok;
+ false ->
+ %% io:format("A1: ~p~nA2: ~p~n",[A1,A2]),
+ ?warning("Skipped Ext Not Equal ~p ~p~n",
+ [F1#func.name,F2#func.name])
+ end,
+ Equal.
+
+is_equal_args([],[]) -> true;
+is_equal_args([_A1=#arg{type=T1}|A1s],[_A2=#arg{type=T2}|A2s]) ->
+ case is_equal_type(T1,T2) of
+ true -> is_equal_args(A1s,A2s);
+ false ->
+ %%io:format("Diff~n ~p~n ~p ~n~n", [_A1,_A2]),
+ false
+ end.
+
+is_equal_type(T,T) -> true;
+is_equal_type(#type{name="GLcharARB"},#type{name="GLchar"}) -> true;
+%%is_equal_type(#type{name="GLhandleARB"},#type{name="GLuint"}) -> true;
+is_equal_type(#type{name="GLenum"},#type{name="GLuint"}) -> true;
+is_equal_type(#type{name="GLenum"},#type{name="GLint"}) -> true;
+is_equal_type(#type{base=idx_binary},#type{base=guard_int}) -> true;
+is_equal_type(#type{base=idx_binary},#type{base=memory}) -> true;
+is_equal_type(#type{single={tuple,matrix}},#type{single={tuple,matrix12}}) -> true;
+is_equal_type(#type{base=B,single=S,name=N,size=Sz},
+ #type{base=B,single=S,name=N,size=Sz}) -> true;
+is_equal_type(_,_) -> false.
+
+skip(Name,Opts) ->
+ Skip = get_value(skip, Opts, []),
+ lists:any(fun(Prefix) -> lists:prefix(Prefix,Name) end, Skip).
+
+keep(Name,Opts) ->
+ Skip = get_value(keep, Opts, []),
+ lists:any(fun(Prefix) -> lists:prefix(Prefix,Name) end, Skip).
+
+get_extension(ExtName,_Opts) ->
+ case reverse(ExtName) of
+ "BRA" ++ Name -> {reverse(Name),"ARB"};
+ "TXE" ++ Name -> {reverse(Name),"EXT"};
+ "ASEM" ++ Name -> {reverse(Name),"MESA"};
+ "ITA" ++ Name -> {reverse(Name),"ATI"};
+ "DMA" ++ Name -> {reverse(Name),"AMD"};
+ "VN" ++ Name -> {reverse(Name),"NV"}; %Nvidia
+ "ELPPA"++ Name -> {reverse(Name),"APPLE"};
+ "LETNI"++ Name -> {reverse(Name),"INTEL"};
+ "NUS" ++ Name -> {reverse(Name),"SUN"};
+ "XNUS" ++ Name -> {reverse(Name),"SUNX"};
+ "IGS" ++ Name -> {reverse(Name),"SGI"};
+ "SIGS" ++ Name -> {reverse(Name),"SGIS"};
+ "XIGS" ++ Name -> {reverse(Name),"SGIX"};
+ "XFD3" ++ Name -> {reverse(Name),"3DFX"};
+ "MBI" ++ Name -> {reverse(Name),"IBM"};
+ "RGNI" ++ Name -> {reverse(Name),"INGR"};
+ "IGP" ++ Name -> {reverse(Name),"PGI"};
+ "PH" ++ Name -> {reverse(Name),"HP"};
+ "YDEMERG" ++ Name -> {reverse(Name),"GREMEDY"};
+ %%["" ++ Name] -> {Name; %%
+ _ -> {ExtName, ""}
+ end.
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+drop_empty(List) ->
+ filter(fun(#xmlText { value = Text}) ->
+ string:strip(Text) =/= "";
+ (_)->
+ true
+ end, List).
+
+name(Name, _Opts) -> Name.
+
+next_id(What) ->
+ Next = case get(What) of
+ undefined -> 5010; %% Opengl
+ N -> N+1
+ end,
+ put(What, Next),
+ Next.
diff --git a/lib/wx/api_gen/gl_gen.hrl b/lib/wx/api_gen/gl_gen.hrl
new file mode 100644
index 0000000000..0eef69b817
--- /dev/null
+++ b/lib/wx/api_gen/gl_gen.hrl
@@ -0,0 +1,41 @@
+
+-record(func,
+ {
+ name = undefined, % real name
+ type = void, % method type
+ params = [], % arguments to the function
+ where = both, % C code and/or erlang
+ id = undefined, % Integer
+ alt = undefined, % Function alternative
+ ext = undefined % Have ARB or other extension
+ }
+ ).
+
+-record(arg,
+ {
+ name = undefined,
+ type = undefined,
+ in = true,
+ where = both, % both in c and erl or only in either
+ alt = undefined
+ }).
+
+-record(type,
+ {
+ name = undefined, % typename
+ base = undefined, % basename int, char, float ..
+ size = 4, % in bytes
+ by_val = true, % or false = by_ref
+ single = true, % Single or array (list)
+ ref = undefined, % {pointer, N}
+ mod = [] % const ...
+ }
+ ).
+
+-record(def, {name, val, type}). %% type=hex, int, string
+
+-define(error(What),
+ erlang:error({{?MODULE,?LINE},{get(current_func)},What})).
+
+-define(warning(Str,Args),
+ io:format("~p:~p Warning:"++Str, [?MODULE,?LINE] ++ Args)).
diff --git a/lib/wx/api_gen/gl_gen_c.erl b/lib/wx/api_gen/gl_gen_c.erl
new file mode 100644
index 0000000000..5c72499790
--- /dev/null
+++ b/lib/wx/api_gen/gl_gen_c.erl
@@ -0,0 +1,596 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%%-------------------------------------------------------------------
+%%% File : gl_gen_c.erl
+%%% Author : Dan Gudmundsson <[email protected]>
+%%% Description :
+%%%
+%%% Created : 25 Apr 2007 by Dan Gudmundsson <[email protected]>
+%%%-------------------------------------------------------------------
+
+-module(gl_gen_c).
+-compile(export_all).
+
+-include("gl_gen.hrl").
+
+-import(lists, [foldl/3,foldr/3,reverse/1, keysearch/3, map/2, filter/2, max/1]).
+-import(gen_util, [lowercase/1, lowercase_all/1, uppercase/1, uppercase_all/1,
+ open_write/1, close/0, c_copyright/0, w/2,
+ args/3, strip_name/2]).
+-import(wx_gen, [next_id/1]).
+
+
+gen(GLFuncs, GLUFuncs) ->
+ gen_defines(GLFuncs,GLUFuncs),
+ gl_gen_init(GLFuncs),
+ glu_gen_init(GLUFuncs),
+
+ %% Marshal funcs
+ open_write("../c_src/gen/gl_funcs.cpp"),
+ c_copyright(),
+ w("/***** This file is generated do not edit ****/ ~n~n", []),
+ w("#include <stdio.h>~n", []),
+ w("#include <string.h>~n", []),
+ w("#include \"../wxe_impl.h\"~n", []),
+ w("#include \"../wxe_gl.h\"~n", []),
+ w("#include \"gl_fdefs.h\"~n", []),
+
+ w("~nint gl_error_op;~n", []),
+ w("void gl_dispatch(int op, char *bp,ErlDrvTermData caller,WXEBinRef *bins[]){~n",
+ []),
+ w(" gl_error_op = op;~n", []),
+ w(" if(caller != gl_active) {~n", []),
+ w(" wxGLCanvas * current = glc[caller];~n", []),
+ w(" if(current) { gl_active = caller; current->SetCurrent();}~n", []),
+ w(" else {~n "
+ " ErlDrvTermData rt[] = // Error msg~n"
+ " {ERL_DRV_ATOM, driver_mk_atom((char *) \"_wxe_error_\"),~n"
+ " ERL_DRV_INT, op,~n"
+ " ERL_DRV_ATOM, driver_mk_atom((char *) \"no_gl_context\"),~n"
+ " ERL_DRV_TUPLE,3};~n"
+ " driver_send_term(WXE_DRV_PORT,caller,rt,8);~n"
+ " return ;~n }~n };~n~n", []),
+
+ w(" switch(op) ~n{~n",[]),
+ w(" case 5000: ~n wxe_tess_impl(bp, caller); ~n break;~n", []),
+ w(" case WXE_BIN_INCR:~n driver_binary_inc_refc(bins[0]->bin);~n break;~n",[]),
+ w(" case WXE_BIN_DECR:~n driver_binary_dec_refc(bins[0]->bin);~n break;~n",[]),
+
+ [funcs(F) || F <- GLUFuncs],
+ [funcs(F) || F <- GLFuncs],
+
+ w("}} /* The End */~n~n",[]),
+
+ close().
+
+funcs([F1|Fs]) when is_list(F1) ->
+ put(current_func,F1),
+ func(get(F1)),
+ erase(current_func),
+ funcs(Fs);
+funcs([]) -> ok;
+funcs(F) ->
+ put(current_func,F),
+ func(get(F)),
+ erase(current_func).
+
+func(#func{where=erl}) -> ok;
+func(#func{id=Id,alt={has_vector,_,FuncName}}) ->
+ #func{name=Name,type=T,params=As} = get(FuncName),
+ w("case ~p: { // ~s ~n", [Id,Name]),
+ put(bin_count,-1),
+ As1 = declare_vars(T, As),
+ As2 = decode_args(As1),
+ As3 = call_gl(Name,T,As2),
+ build_return_vals(T,As3),
+ free_args(),
+ w("}; break; ~n", []);
+func(#func{name=Name,id=Id,type=T,params=As,alt=_Alt}) ->
+ w("case ~p: { // ~s ~n", [Id,Name]),
+ put(bin_count,-1),
+ As2 = decode_args(As),
+ declare_vars(T, As), %% Unusal order but it's c++
+ As3 = call_gl(Name,T,As2),
+ build_return_vals(T,As3),
+ free_args(),
+ w("}; break; ~n", []).
+
+declare_vars(void,Ps) ->
+ [declare_var(P) || P <- Ps];
+declare_vars(T, Ps) ->
+ declare_var(#arg{name="result",in=false,type=T}),
+ [declare_var(P) || P <- Ps].
+
+declare_var(A=#arg{where=erl}) -> A;
+
+declare_var(A=#arg{name=N,in=false,type=#type{name=T,base=B,single={tuple,Sz}}}) ->
+ true = is_number(Sz), %% Assert
+ w(" ~s ~s[~p] = {~s};~n", [T,N,Sz,args(fun zero/1,",",lists:duplicate(Sz,B))]),
+ A;
+declare_var(A=#arg{name=N,in=false,type=#type{name=T,base=B,single={list,Sz}}}) when is_number(Sz) ->
+ w(" ~s ~s[~p] = {~s};~n", [T,N,Sz,args(fun zero/1,",",lists:duplicate(Sz,B))]),
+ A;
+declare_var(A=#arg{name=N,in=false,type=#type{name=T,single={list,ASz,_USz},mod=[]}}) ->
+ true = is_list(ASz), %% Assert
+ w(" ~s *~s;~n", [T,N]),
+ w(" ~s = (~s *) driver_alloc(sizeof(~s) * *~s);~n", [N,T,T,ASz]),
+ store_free(N),
+ A;
+declare_var(A=#arg{name=N,in=false,type=#type{name=T,base=binary,size=Sz}}) ->
+ true = is_number(Sz), %% Assert
+ w(" ~s ~s[~p];~n", [T,N,Sz]),
+ A;
+declare_var(A=#arg{name=N,in=false,
+ type=#type{name=T="GLUquadric",base=B,by_val=false,single=true}}) ->
+ A;
+declare_var(A=#arg{name=N,in=false,
+ type=#type{name=T,base=B,by_val=false,single=true}}) ->
+ w(" ~s ~s[1] = {~s};~n", [T,N,zero(B)]),
+ A;
+declare_var(A=#arg{where=_}) ->
+ A.
+
+zero(float) -> "0.0";
+zero(_) -> "0".
+
+store_free(N) ->
+ case get(free_args) of
+ undefined -> put(free_args, [N]);
+ List -> put(free_args, [N|List])
+ end.
+
+free_args() ->
+ case get(free_args) of
+ undefined -> ignore;
+ List ->
+ erase(free_args),
+ [w(" driver_free(~s);~n", [Arg]) || Arg <- List]
+ end.
+
+decode_args(As0) ->
+ {As,_Align} = lists:mapfoldl(fun decode_arg/2,0,As0),
+ As.
+
+decode_arg(P=#arg{where=erl},A) -> {P,A};
+decode_arg(P=#arg{where=c},A) -> {P,A};
+decode_arg(P=#arg{in=false},A) -> {P,A};
+
+decode_arg(P=#arg{name=Name,type=#type{name=Type,base=binary}},A0) ->
+ w(" ~s *~s = (~s *) bins[~p]->base;~n", [Type,Name,Type,next_id(bin_count)]),
+ {P, A0};
+decode_arg(P=#arg{name=Name,type=#type{name=Type,base=memory}},A0) ->
+ w(" ~s *~s = (~s *) bins[~p]->base;~n", [Type,Name,Type,next_id(bin_count)]),
+ {P, A0};
+decode_arg(P=#arg{name=Name,type=#type{name=T,base=string,single=list}},A0) ->
+ A = align(4,A0),
+ w(" int * ~sLen = (int *) bp; bp += 4;~n", [Name]),
+ w(" int * ~sTotSize = (int *) bp; bp += 4;~n",[Name]),
+%% w(" if(*~sLen > 256) *~sLen = 256;", []),
+ w(" ~s **~s;~n", [T,Name]),
+ w(" ~s = (~s **) driver_alloc(sizeof(~s *) * *~sLen); ~n",[Name, T, T, Name]),
+ store_free(Name),
+ w(" for(int i=0;i<*~sLen;i++) {~n", [Name]),
+ w(" ~s[i] = (~s *) bp; bp += 1+strlen(bp);};~n",[Name,T]),
+ w(" bp += (8 - ((~p + *~sTotSize) % 8)) % 8;~n",[A,Name]),
+ {P, 0};
+
+decode_arg(P=#arg{name=Name,type=#type{size=Sz,single=list,name=Type}},A0) ->
+ A = align(max([Sz,4]),A0),
+ w(" int * ~sLen = (int *) bp; bp += ~p;~n", [Name, max([4,Sz])]),
+ w(" ~s * ~s = (~s *) bp; ", [Type,Name,Type]),
+ w(" bp += (8-((*~sLen*~p+~p)%8))%8;~n", [Name,Sz,A]),
+ {P, 0};
+decode_arg(P=#arg{name=Name,type=#type{size=TSz,name=Type,single={tuple,undefined}}},A0) ->
+ A = align(TSz,A0),
+ w(" int *~sLen = (int *) bp; bp += ~p;~n", [Name, max([4,TSz])]),
+ if TSz =:= 4 ->
+ w(" ~s *~s = (~s *) bp; bp += *~sLen*4+((*~sLen)+~p)%2*4;~n",
+ [Type,Name,Type, Name,Name, A div 4]);
+ TSz =:= 8 ->
+ w(" ~s *~s = (~s *) bp; bp += *~sLen*8;~n", [Type,Name,Type,Name])
+ end,
+ {P, 0};
+decode_arg(P=#arg{name=Name,type=#type{size=BSz,name=Type,single={tuple,TSz}}},A0) ->
+ A = align(BSz,TSz,A0),
+ w(" ~s * ~s = (~s *) bp; bp += ~p;~n", [Type,Name,Type,BSz*TSz]),
+ {P, A};
+decode_arg(P=#arg{name=Name,type=#type{size=BSz,name=Type,single={list,TSz}}},A0) ->
+ A = align(BSz,TSz,A0),
+ w(" ~s * ~s = (~s *) bp; bp += ~p;~n", [Type,Name,Type,BSz*TSz]),
+ {P, A};
+decode_arg(P=#arg{name=Name,type=#type{name=Type,base=guard_int}},A0) ->
+ A = align(4,A0),
+ w(" ~s *~s = (~s *) * (int *) bp; bp += 4;~n", [Type,Name,Type]),
+ {P, A};
+decode_arg(P=#arg{name=Name,type=#type{name=Type,base=string,single=true}},A0) ->
+ w(" ~s *~s = (~s *) bp;~n", [Type,Name,Type]),
+ w(" int ~sLen = strlen((char *)~s); bp += ~sLen+1+((8-((1+~sLen+~p)%8))%8);~n",
+ [Name,Name,Name,Name,A0]),
+ {P, 0};
+decode_arg(P=#arg{name=Name,
+ type=#type{name=Type,size=8,base=int,by_val=true,ref=undefined}},A0) ->
+ A = align(8,A0),
+ w(" ~s ~s = (~s) * (GLuint64EXT *) bp; bp += 8;~n", [Type,Name,Type]),
+ {P, A};
+decode_arg(P=#arg{name=Name,type=#type{name=Type="GLUquadric",size=8,base=int}},A0) ->
+ A = align(8,A0),
+ w(" ~s * ~s = (~s *) * (GLuint64EXT *) bp; bp += 8;~n", [Type,Name,Type]),
+ {P, A};
+decode_arg(P=#arg{name=Name,
+ type=#type{name=Type,size=Sz,by_val=true,ref=undefined}},A0) ->
+ A = align(Sz,A0),
+ w(" ~s *~s = (~s *) bp; bp += ~p;~n", [Type,Name,Type,Sz]),
+ {P, A};
+decode_arg(P=#arg{name=Name,type=#type{size=BSz,name=Type,single={tuple_list,TSz}}},A0) ->
+ A = align(BSz,TSz,A0),
+ w(" int *~sLen = (int *) bp; bp += ~p;~n", [Name, max([4,BSz])]),
+ w(" ~s * ~s = (~s *) bp; bp += *~sLen*~p;~n", [Type,Name,Type,Name,BSz*TSz]),
+ {P, A};
+decode_arg(P=#arg{name=Name, type=#type{name=Type,size=Sz,by_val=false,
+ ref={pointer,1}, mod=[const]}},
+ A0) ->
+ A = align(Sz,A0),
+ w(" ~s *~s = (~s *) bp; bp += ~p;~n", [Type,Name,Type,Sz]),
+ {P, A};
+decode_arg(P, _A) ->
+ ?error({unhandled_type, {P#arg.name,P#arg.type,_A}}).
+
+align(Size, PreAlign) ->
+ align(Size,1,PreAlign).
+
+align(1,N,A) -> (A+1*N+0) rem 8;
+
+align(2,N,A) when (A rem 2) =:= 0 -> (A+2*N+0) rem 8;
+align(2,N,A) when (A rem 2) =:= 1 -> a_str(1),(A+2*N+1) rem 8;
+
+align(4,N,A) when (A rem 4) =:= 0 -> (A+4*N+0) rem 8;
+align(4,N,A) when (A rem 4) =:= 1 -> a_str(3),(A+4*N+3) rem 8;
+align(4,N,A) when (A rem 4) =:= 2 -> a_str(2),(A+4*N+2) rem 8;
+align(4,N,A) when (A rem 4) =:= 3 -> a_str(1),(A+4*N+1) rem 8;
+
+align(8,_,0) -> 0;
+align(8,_,1) -> a_str(7),0;
+align(8,_,2) -> a_str(6),0;
+align(8,_,3) -> a_str(5),0;
+align(8,_,4) -> a_str(4),0;
+align(8,_,5) -> a_str(3),0;
+align(8,_,6) -> a_str(2),0;
+align(8,_,7) -> a_str(1),0.
+
+a_str(P) -> w(" bp += ~p;~n", [P]).
+
+call_gl(Name,void,As) ->
+ Args = args(fun call_arg/1, ",", As),
+ w(" we~s(~s);~n", [Name,Args]),
+ As;
+call_gl(Name,T=#type{},As) ->
+ Args = args(fun call_arg/1, ",", As),
+ Type = result_type(T),
+ w(" ~s result = we~s(~s);~n", [Type,Name,Args]),
+ As.
+
+result_type(#type{name=T, ref=undefined}) -> T;
+result_type(#type{name=T, ref={pointer,1}, mod=Mods}) ->
+ mod(Mods) ++ T ++ " * ".
+
+call_arg(#arg{alt={length,Alt},type=#type{}}) ->
+ "*" ++ Alt ++ "Len";
+call_arg(#arg{alt={constant,Alt},type=#type{}}) ->
+ Alt;
+call_arg(#arg{name=Name,type=#type{single={tuple, _}}}) ->
+ Name;
+call_arg(#arg{name=Name,type=#type{single={list, _}}}) ->
+ Name;
+call_arg(#arg{name=Name,type=#type{size=8,base=int,ref=undefined}}) ->
+ Name;
+call_arg(#arg{name=Name,type=#type{ref=undefined}}) ->
+ "*" ++ Name;
+call_arg(#arg{name=Name,type=#type{base=guard_int}}) ->
+ Name;
+call_arg(#arg{name=Name,type=#type{base=string,ref={pointer,2},mod=[const]}}) ->
+ "(const GLchar **) " ++ Name;
+call_arg(#arg{name=Name,type=#type{size=8,base=int,ref={pointer,1}}}) ->
+ Name;
+call_arg(#arg{name=Name,type=#type{}}) ->
+ Name.
+
+build_return_vals(Type,As) ->
+ case calc_sizes(Type,As) of
+ {0,none,0} -> %% Sync memory access functions
+ Any = fun(#arg{type=#type{base=B}}) -> B =:= memory end,
+ case lists:any(Any, As) of
+ false -> ok;
+ true ->
+ w(" int AP = 0; ErlDrvTermData rt[6];~n",[]),
+ w(" rt[AP++]=ERL_DRV_ATOM;"
+ " rt[AP++]=driver_mk_atom((char *) \"_wxe_result_\");~n",[]),
+ w(" rt[AP++]=ERL_DRV_ATOM;"
+ " rt[AP++]=driver_mk_atom((char *) \"ok\");~n",[]),
+ w(" rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;~n",[]),
+ w(" driver_send_term(WXE_DRV_PORT,caller,rt,AP);~n",[]),
+ ok
+ end;
+ {Val,Vars,Cnt} ->
+ ExtraTuple = if Cnt > 1 -> 2; true -> 0 end,
+ CSize = if Vars =:= none ->
+ Sz = integer_to_list(Val+4+ExtraTuple),
+ w(" int AP = 0; ErlDrvTermData rt[~s];~n",[Sz]),
+ Sz;
+ true ->
+ Sz = integer_to_list(Val+4+ExtraTuple) ++ " + " ++ Vars,
+ w(" int AP = 0; ErlDrvTermData *rt;~n",[]),
+ w(" rt = (ErlDrvTermData *) "
+ "driver_alloc(sizeof(ErlDrvTermData)*(~s));~n", [Sz]),
+ Sz
+ end,
+ w(" rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) \"_wxe_result_\");~n",[]),
+ FreeList = build_ret_types(Type,As),
+ case Cnt of
+ 1 -> ok;
+ _ ->
+ w(" rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = ~p;~n",[Cnt])
+ end,
+ w(" rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;~n",[]),
+ w(" if (AP != ~s ) fprintf(stderr, \"%d: ERROR AP mismatch %d %d\\r\\n\",__LINE__,AP,~s);~n",
+ [CSize,CSize]),
+ w(" driver_send_term(WXE_DRV_PORT,caller,rt,AP);~n",[]),
+ case Vars of
+ none -> ignore;
+ _ ->
+ w(" driver_free(rt); ~n", [])
+ end,
+ [w(" ~s~n", [Name]) || Name <- FreeList],
+ ok
+ end.
+
+calc_sizes(Type,As) ->
+ TSz = case return_size("result", Type) of
+ {0, none} ->
+ {0, none, 0};
+ {Sz,Vars} ->
+ {Sz,Vars, 1}
+ end,
+ Calc = fun(#arg{name=N,in=False,where=W,type=T},{Sz,Vars, Cnt})
+ when False =/= true, W=/= c ->
+ case return_size(N, T) of
+ {Val, none} -> {Sz+Val, Vars, Cnt+1};
+ {Val, Var} when Vars =:= none ->
+ {Sz+Val, Var,Cnt+1};
+ {Val, Var} when Vars =:= none ->
+ {Sz+Val, Var ++ " + " ++ Vars,Cnt+1}
+ end;
+ (_,Acc) -> Acc
+ end,
+ foldl(Calc, TSz, As).
+
+return_size(_N,void) -> {0, none};
+return_size(_N,#type{base=binary}) -> {4, none};
+return_size(_N,#type{single=true}) -> {2,none};
+return_size(_N,#type{single={tuple,Sz}}) -> {Sz*2+2, none};
+return_size(_N,#type{name="GLubyte",single={list,null}}) ->{3, none};
+return_size(_N,#type{single={list,Sz}}) -> {Sz*2+3, none};
+return_size(_N,#type{base=string,single={list,_,_}}) -> {3, none};
+return_size(_N,#type{single={list,_,Sz}}) -> {3, "(*" ++Sz++")*2"}.
+
+
+build_ret_types(void,Ps) ->
+ Calc = fun(#arg{name=N,in=False,where=W,type=T},Free)
+ when False =/= true, W=/= c ->
+ case build_ret(N, False, T) of
+ ok -> Free;
+ Other -> [Other|Free]
+ end;
+ (_,Free) -> Free
+ end,
+ lists:foldl(Calc, [], Ps);
+build_ret_types(Type,Ps) ->
+ build_ret("result", out, Type),
+ Calc = fun(#arg{name=N,in=False,where=W,type=T},Free)
+ when False =/= true, W=/= c ->
+ case build_ret(N, False, T) of
+ ok -> Free;
+ Other -> [Other|Free]
+ end;
+ (_,Free) -> Free
+ end,
+ lists:foldl(Calc, [], Ps).
+
+build_ret(Name,_Q,#type{name=_T,base=int,single=true,by_val=true}) ->
+ w(" rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) ~s;~n", [Name]);
+build_ret(Name,_Q,#type{name=_T,base=bool,single=true,by_val=true}) ->
+ w(" rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) ~s;~n", [Name]);
+build_ret(Name,_Q,#type{name="GLUquadric",base=int}) ->
+ w(" rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) ~s;~n", [Name]);
+build_ret(Name,_Q,#type{name=_T,base=int,single=true,by_val=false}) ->
+ w(" rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *~s;~n", [Name]);
+build_ret(Name,_Q,#type{name=_T,base=bool,single=true,by_val=false}) ->
+ w(" rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *~s;~n", [Name]);
+build_ret(Name,_Q,#type{name=_T,size=4,base=float,single=true,by_val=false}) ->
+ w(" GLdouble ~sConv = (double) *~s; \n",[Name,Name]),
+ w(" rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) &~sConv;~n", [Name]);
+build_ret(Name,_Q,#type{name=_T,size=8,base=float,single=true,by_val=false}) ->
+ w(" rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) ~s;~n", [Name]);
+
+build_ret(Name,_Q,#type{name=_T,size=FSz,base=float,single={tuple,Sz}}) ->
+ Temp = Name ++ "Tmp",
+ case FSz of
+ 8 ->
+ w(" GLdouble *~s = ~s;\n", [Temp,Name]);
+ 4 ->
+ w(" GLdouble ~sConv[~p], *~s = ~sConv; \n",[Name,Sz,Temp,Name]),
+ w(" for(int i=0; i < ~p; i++) ~sConv[i] = (GLdouble) ~s[i];\n",[Sz,Name,Name])
+ end,
+ [w(" rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) ~s++;~n", [Temp])
+ || _ <- lists:seq(1,Sz)],
+ w(" rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = ~p;~n",[Sz]);
+build_ret(Name,_Q,#type{name=T,base=_,single={tuple,Sz}}) ->
+ Temp = Name ++ "Tmp",
+ w(" ~s *~s = ~s;\n", [T,Temp,Name]),
+ [w(" rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *~s++;~n", [Temp])
+ || _ <- lists:seq(1,Sz)],
+ w(" rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = ~p;~n",[Sz]);
+build_ret(Name,_Q,#type{name="GLubyte",single={list,null}}) ->
+ w(" rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) ~s;"
+ " rt[AP++] = strlen((char *) ~s);\n", [Name, Name]);
+build_ret(Name,_Q,#type{base=string,single={list,_,Sz}}) ->
+ w(" rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) ~s;"
+ " rt[AP++] = *~s;\n", [Name, Sz]);
+build_ret(Name,_Q,#type{name=_T,base=B,single={list,_,Sz}}) when B =/= float ->
+ w(" for(int i=0; i < *~s; i++) {\n", [Sz]),
+ w(" rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) ~s[i];}~n", [Name]),
+ w(" rt[AP++] = ERL_DRV_NIL;", []),
+ w(" rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*~s)+1;~n",[Sz]);
+build_ret(Name,_Q,#type{name=_T,size=FSz,base=float,single={list,Sz}}) ->
+ Temp = Name ++ "Tmp",
+ case FSz of
+ 8 ->
+ w(" GLdouble *~s = ~s;\n", [Temp,Name]);
+ 4 ->
+ w(" GLdouble ~sConv[~p], *~s = ~sConv; \n",[Name,Sz,Temp,Name]),
+ w(" for(int i=0; i < ~p; i++) ~sConv[i] = (GLdouble) ~s[i];\n",[Sz,Name,Name])
+ end,
+ [w(" rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) ~s++;~n", [Temp])
+ || _ <- lists:seq(1,Sz)],
+ w(" rt[AP++] = ERL_DRV_NIL;", []),
+ w(" rt[AP++] = ERL_DRV_LIST; rt[AP++] = ~p+1;~n",[Sz]);
+build_ret(Name,_Q,#type{name=T,base=_,single={list,Sz}}) ->
+ Temp = Name ++ "Tmp",
+ w(" ~s *~s = ~s;\n", [T,Temp,Name]),
+ [w(" rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *~s++;~n", [Temp])
+ || _ <- lists:seq(1,Sz)],
+ w(" rt[AP++] = ERL_DRV_NIL;", []),
+ w(" rt[AP++] = ERL_DRV_LIST; rt[AP++] = ~p+1;~n",[Sz]);
+build_ret(Name,_Q,#type{name="GLubyte",base=binary,size=Sz}) ->
+ w(" ErlDrvBinary * BinCopy = driver_alloc_binary(~p);~n", [Sz]),
+ w(" memcpy(BinCopy->orig_bytes, ~s, ~p);~n", [Name,Sz]),
+ w(" rt[AP++] = ERL_DRV_BINARY; rt[AP++] = (ErlDrvTermData) BinCopy;", []),
+ w(" rt[AP++] = ~p; rt[AP++] = 0;~n", [Sz]),
+ "driver_free_binary(BinCopy);";
+build_ret(Name,_Q,T=#type{}) ->
+ io:format("{~p, {~p, {single,{tuple,X}}}}.~n", [get(current_func),Name]),
+ io:format(" ~p~n",[T]).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+gen_defines(GLFuncs,GLUFuncs) ->
+ open_write("../c_src/gen/gl_fdefs.h"),
+ c_copyright(),
+ w("/***** This file is generated do not edit ****/ ~n~n", []),
+ w("#ifdef WX_DEF_EXTS~n", []),
+ w("# define WXE_EXTERN~n", []),
+ w("#else~n# define WXE_EXTERN extern~n", []),
+ w("#endif~n~n", []),
+ [fdefs(F) || F <- GLFuncs],
+ [fdefs(F) || F <- GLUFuncs],
+ close().
+
+fdefs([F1|_Fs]) when is_list(F1) ->
+ put(current_func,F1),
+ fdef(get(F1)),
+ erase(current_func);
+fdefs([]) -> ok;
+fdefs(F) ->
+ put(current_func,F),
+ fdef(get(F)),
+ erase(current_func).
+
+fdef(#func{where=erl}) -> ok;
+fdef(#func{alt={has_vector,_,FuncName}}) ->
+ #func{name=Name,type=T,params=As} = get(FuncName),
+ w("typedef ~s (APIENTRY * WXE~s)(~s);~n",
+ [fdef_type(T), uppercase_all(Name), fdef_types(As)]),
+ w("WXE_EXTERN WXE~s we~s;~n", [uppercase_all(Name), Name]);
+fdef(#func{name=Name,type=T,params=As,alt=_Alt}) ->
+ w("typedef ~s (APIENTRY * WXE~s)(~s);~n",
+ [fdef_type(T), uppercase_all(Name), fdef_types(As)]),
+ w("WXE_EXTERN WXE~s we~s;~n", [uppercase_all(Name), Name]).
+
+fdef_type(void) -> "void";
+fdef_type(#type{name=T, mod=Mod, single=true, ref=undefined}) ->
+ mod(Mod) ++ T;
+fdef_type(#type{name=T, mod=Mod, single={tuple,Sz}, ref=undefined}) ->
+ mod(Mod) ++ T ++ " m[" ++ integer_to_list(Sz) ++ "]";
+fdef_type(#type{name=T, mod=Mod, ref={pointer,1}}) ->
+ mod(Mod) ++ T ++ " *";
+fdef_type(#type{name=T, mod=Mod, ref={pointer,2}}) ->
+ mod(Mod) ++ T ++ " **".
+
+mod([const]) -> "const ";
+mod([]) -> "".
+
+fdef_types(As) ->
+ args(fun(#arg{type=T}) -> fdef_type(T) end, ",", As).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+gl_gen_init(Funcs) ->
+ open_write("../c_src/gen/gl_finit.h"),
+ c_copyright(),
+ w("/***** This file is generated do not edit ****/ ~n~n", []),
+ w("static struct {\n"
+ " const char * name;\n"
+ " const char * alt;\n"
+ " void * func;\n"
+ "} gl_fns[] = \n"
+ "{\n", []),
+ [finits(F) || F <- Funcs],
+ w(" { NULL, NULL, NULL}};\n",[]),
+ close().
+
+glu_gen_init(Funcs) ->
+ open_write("../c_src/gen/glu_finit.h"),
+ c_copyright(),
+ w("/***** This file is generated do not edit ****/ ~n~n", []),
+ w("static struct {\n"
+ " const char * name;\n"
+ " const char * alt;\n"
+ " void * func;\n"
+ "} glu_fns[] = \n"
+ "{\n", []),
+ [finits(F) || F <- Funcs],
+ w(" { NULL, NULL, NULL}};\n",[]),
+ close().
+
+
+finits([F1|_Fs]) when is_list(F1) ->
+ put(current_func,F1),
+ finit(get(F1)),
+ erase(current_func);
+finits([]) -> ok;
+finits(F) ->
+ put(current_func,F),
+ finit(get(F)),
+ erase(current_func).
+
+finit(#func{where=erl}) -> ok;
+finit(#func{alt={has_vector,_,FuncName}, ext=Ext}) ->
+ #func{name=Name} = get(FuncName),
+ w(" {~p, ~s, &we~s},\n", [Name, ext(Name,Ext), Name]);
+finit(#func{name=Name, ext=Ext}) ->
+ w(" {~p, ~s, &we~s},\n", [Name, ext(Name,Ext), Name]).
+
+ext(Name, {ext,Ext}) ->
+ "\"" ++ Name ++ Ext ++ "\"";
+ext(_,_) -> "NULL".
+
+
+
+
+
diff --git a/lib/wx/api_gen/gl_gen_erl.erl b/lib/wx/api_gen/gl_gen_erl.erl
new file mode 100644
index 0000000000..3e436100b6
--- /dev/null
+++ b/lib/wx/api_gen/gl_gen_erl.erl
@@ -0,0 +1,603 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%%-------------------------------------------------------------------
+%%% File : gl_gen_erl.erl
+%%% Author : Dan Gudmundsson <[email protected]>
+%%% Description :
+%%%
+%%% Created : 18 Apr 2007 by Dan Gudmundsson <[email protected]>
+%%%-------------------------------------------------------------------
+-module(gl_gen_erl).
+
+-include("gl_gen.hrl").
+
+-compile(export_all).
+
+-import(lists, [foldl/3,foldr/3,reverse/1, keysearch/3, map/2, filter/2, max/1]).
+-import(gen_util, [lowercase/1, lowercase_all/1, uppercase/1, uppercase_all/1,
+ open_write/1, close/0, erl_copyright/0, w/2,
+ args/3, args/4, strip_name/2]).
+
+gl_defines(Defs) ->
+ open_write("../include/gl.hrl"),
+ erl_copyright(),
+ w("~n%% OPENGL DEFINITIONS~n~n", []),
+ w("%% This file is generated DO NOT EDIT~n~n", []),
+ [gen_define(Def) || Def=#def{} <- Defs],
+ close(),
+ ok.
+
+glu_defines(Defs) ->
+ open_write("../include/glu.hrl"),
+ erl_copyright(),
+ w("~n%% GLU DEFINITIONS~n~n", []),
+ w("%% This file is generated DO NOT EDIT~n~n", []),
+ [gen_define(Def) || Def=#def{} <- Defs],
+ close(),
+ ok.
+
+gen_define(#def{name=N, val=Val, type=int}) ->
+ w("-define(~s, ~p).~n", [N,Val]);
+gen_define(#def{name=N, val=Val, type=hex}) ->
+ w("-define(~s, ~.16#).~n", [N,Val]);
+gen_define(#def{name=N, val=Val, type=string}) ->
+ w("-define(~s, ?~s).~n", [N,Val]).
+
+types() ->
+ [{"GLenum", "32/native-unsigned"},
+ {"GLboolean", "8/native-unsigned"},
+ {"GLbitfield","32/native-unsigned"}, %
+ %%{"GLvoid",":void "},%
+ {"GLbyte", "8/native-signed"}, % 1-byte signed
+ {"GLshort", "16/native-signed"}, % 2-byte signed
+ {"GLint", "32/native-signed"}, % 4-byte signed
+ {"GLubyte", "8/native-unsigned"}, % 1-byte unsigned
+ {"GLushort", "16/native-unsigned"}, % 2-byte unsigned
+ {"GLuint", "32/native-unsigned"}, % 4-byte unsigned
+ {"GLsizei", "32/native-signed"}, % 4-byte signed
+ {"GLfloat", "32/native-float"}, % single precision float
+ {"GLclampf", "32/native-float"}, % single precision float in [0,1]
+ {"GLdouble", "64/native-float"}, % double precision float
+ {"GLclampd", "64/native-float"}, % double precision float in [0,1]
+ {"GLsizeiptr","64/native-unsigned"}, % 64 bits int, convert on c-side
+ {"GLintptr", "64/native-unsigned"}, % 64 bits int, convert on c-sidew
+ {"GLUquadric", "64/native-unsigned"},% Handle 32bits aargh 64bits on mac64
+ {"GLhandleARB","64/native-unsigned"} % Handle 32bits aargh 64bits on mac64
+ ].
+
+gl_api(Fs) ->
+ open_write("../src/gen/gl.erl"),
+ erl_copyright(),
+ w("~n%% OPENGL API~n~n", []),
+ w("%% This file is generated DO NOT EDIT~n~n", []),
+ w("%% @doc Standard OpenGL api. ~n", []),
+ w("%% See <a href=\"http://www.opengl.org/sdk/docs/man/\">www.opengl.org</a>~n",[]),
+ w("%%~n", []),
+ w("%% Booleans are represented by integers 0 and 1. ~n~n", []),
+ w("%% @type wx_mem(). see wx.erl on memory allocation functions~n", []),
+ w("%% @type enum(). An integer defined in gl.hrl~n", []),
+ w("%% @type offset(). An integer which is an offset in an array~n", []),
+ w("%% @type clamp(). A float clamped between 0.0 - 1.0 ~n", []),
+
+ w("-module(gl).~n~n",[]),
+ w("-compile(inline).~n", []),
+ %% w("-compile(export_all).~n~n", []),
+ %% w("-compile(binary_comprehension).~n~n", []),
+ w("-include(\"wxe.hrl\").~n", []),
+ [w("-define(~s,~s).~n", [GL,Erl]) || {GL,Erl} <- types()],
+
+ Exp = fun(F) -> gen_export(F) end,
+ ExportList = lists:map(Exp,Fs),
+ w("~n-export([~s]).~n~n", [args(fun(EF) -> EF end, ",", ExportList, 60)]),
+
+ w("~n%% API ~n~n", []),
+ [gen_funcs(F) || F <- Fs],
+ close(),
+ ok.
+
+glu_api(Fs) ->
+ open_write("../src/gen/glu.erl"),
+ erl_copyright(),
+ w("~n%% OPENGL UTILITY API~n~n", []),
+ w("%% This file is generated DO NOT EDIT~n~n", []),
+ w("%% @doc A part of the standard OpenGL Utility api. ~n", []),
+ w("%% See <a href=\"http://www.opengl.org/sdk/docs/man/\">www.opengl.org</a>~n",[]),
+ w("%%~n", []),
+ w("%% Booleans are represented by integers 0 and 1. ~n~n", []),
+ w("%% @type wx_mem(). see wx.erl on memory allocation functions~n", []),
+ w("%% @type enum(). An integer defined in gl.hrl~n", []),
+ w("%% @type offset(). An integer which is an offset in an array~n", []),
+ w("%% @type clamp(). A float clamped between 0.0 - 1.0 ~n~n", []),
+
+ w("-module(glu).~n",[]),
+ w("-compile(inline).~n", []),
+ w("-include(\"wxe.hrl\").~n", []),
+ [w("-define(~s,~s).~n", [GL,Erl]) || {GL,Erl} <- types()],
+
+ Exp = fun(F) -> gen_export(F) end,
+ ExportList = ["tesselate/2" | lists:map(Exp,Fs)],
+ w("~n-export([~s]).~n~n", [args(fun(EF) -> EF end, ",", ExportList, 60)]),
+
+ w("~n%% API ~n~n", []),
+
+ w("%% @spec (Vec3, [Vec3]) -> {Triangles, VertexPos}~n",[]),
+ w("%% Vec3 = {float(),float(),float()}~n",[]),
+ w("%% Triangles = [VertexIndex::integer()]~n",[]),
+ w("%% VertexPos = binary()~n",[]),
+ w("%% @doc General purpose polygon triangulation.~n",[]),
+ w("%% The first argument is the normal and the second a list of~n"
+ "%% vertex positions. Returned is a list of indecies of the vertices~n"
+ "%% and a binary (64bit native float) containing an array of ~n"
+ "%% vertex positions, it starts with the vertices in Vs and ~n"
+ "%% may contain newly created vertices in the end.~n", []),
+
+ w("tesselate({Nx,Ny,Nz}, Vs) ->~n",[]),
+ w(" wxe_util:call(5000, <<(length(Vs)):32/native,0:32,~n"
+ " Nx:?GLdouble,Ny:?GLdouble,Nz:?GLdouble,~n"
+ " (<< <<Vx:?GLdouble,Vy:?GLdouble,Vz:?GLdouble >>~n"
+ " || {Vx,Vy,Vz} <- Vs>>)/binary >>).~n~n", []),
+
+ [gen_funcs(F) || F <- Fs],
+ close(),
+ ok.
+
+gen_funcs([F]) when is_list(F) ->
+ put(current_func,F),
+ gen_func(get(F)),
+ erase(current_func),
+ w(".~n~n",[]);
+gen_funcs(All=[F|Fs]) when is_list(F) ->
+ put(current_func,F),
+ gen_doc([get(A) || A <- All]),
+ gen_func(get(F)),
+ erase(current_func),
+ w(";~n",[]),
+ gen_funcs(Fs);
+gen_funcs([]) ->
+ w(".~n~n",[]);
+gen_funcs(F) ->
+ put(current_func,F),
+ gen_doc([get(F)]),
+ gen_func(get(F)),
+ erase(current_func),
+ w(".~n~n",[]).
+
+gen_export([F|_]) when is_list(F) ->
+ gen_export2(get(F));
+gen_export(F) when is_list(F) ->
+ gen_export2(get(F)).
+
+gen_export2(#func{name=Name,alt={vector,VecPos,Vec}}) ->
+ #func{params=As0} = get(Vec),
+ {As1,_As2} = lists:split(VecPos, As0),
+ Args = lists:filter(fun(Arg) -> func_arg(Arg) =/= skip end, As1),
+ erl_func_name(Name) ++ "/" ++ integer_to_list(length(Args) +1);
+gen_export2(#func{name=Name,params=As0}) ->
+ Args = lists:filter(fun(Arg) -> func_arg(Arg) =/= skip end, As0),
+ erl_func_name(Name) ++ "/" ++ integer_to_list(length(Args)).
+
+
+gen_doc([#func{alt={vector,VecPos,Vec}}]) ->
+ #func{type=T,params=As} = get(Vec),
+ {As1,As2} = lists:split(VecPos, As),
+ Args1 = case args(fun func_arg/1, ",", As1) of [] -> []; Else -> Else++"," end,
+ Args2 = args(fun func_arg/1, ",", As2),
+ w("%% @spec (~s{~s}) -> ~s~n",[Args1,Args2,doc_return_types(T,As)]),
+ w("%% @equiv ~s(~s)~n",[erl_func_name(Vec), Args1++Args2]);
+gen_doc([#func{name=Name,type=T,params=As,alt=Alt}|_]) ->
+ w("%% @spec (~s) -> ~s~n", [doc_arg_types(As),doc_return_types(T,As)]),
+ GLDoc = "http://www.opengl.org/sdk/docs/man/xhtml/",
+ w("%% @doc See <a href=\"~s~s.xml\">external</a> documentation.~n",
+ [GLDoc, doc_name(Name,Alt)]).
+
+gen_func(#func{name=Name,alt={vector,VecPos,Vec}}) ->
+ #func{params=As} = get(Vec),
+ {As1,As2} = lists:split(VecPos, As),
+ Args1 = case args(fun func_arg/1, ",", As1) of [] -> []; Else -> Else++"," end,
+ Args2 = args(fun func_arg/1, ",", As2),
+
+ w("~s(~s{~s}) ->", [erl_func_name(Name),Args1,Args2]),
+ w(" ~s(~s)", [erl_func_name(Vec), Args1++Args2]);
+gen_func(_F=#func{name=Name,type=T,params=As,id=MId}) ->
+ Args = args(fun func_arg/1, ",", As),
+ w("~s(~s)~s ", [erl_func_name(Name), Args, guard_test(As)]),
+ w("->~n", []),
+ PreAs = pre_marshal(As),
+ {StrArgs,_} = marshal_args(PreAs),
+ case have_return_vals(T,As) of
+ true ->
+ w(" wxe_util:call(~p, <<~s>>)", [MId, StrArgs]);
+ false ->
+ w(" wxe_util:cast(~p, <<~s>>)", [MId, StrArgs])
+ end.
+
+func_arg(#arg{in=In,where=W,name=Name,type=Type})
+ when In =/= false, W =/= c ->
+ case Type of
+ #type{single={tuple,TSz0}} when TSz0 =/= undefined ->
+ TSz = if is_integer(TSz0) -> TSz0;
+ TSz0 =:= matrix12 -> 12
+ end,
+ [NameId|_] = erl_arg_name(Name),
+ Names = [[NameId|integer_to_list(Id)] || Id <- lists:seq(1,TSz)],
+ "{" ++ args(fun(ElName) -> ElName end, ",", Names) ++ "}";
+ _ ->
+ erl_arg_name(Name)
+ end;
+func_arg(_) -> skip.
+
+doc_arg_types(Ps0) ->
+ Ps = [P || P=#arg{in=In, where=Where} <- Ps0,In =/= false, Where =/= c],
+ args(fun doc_arg_type/1, ",", Ps).
+
+doc_return_types(T, Ps0) ->
+ Ps = [P || P=#arg{in=In, where=Where} <- Ps0,In =/= true, Where =/= c],
+ doc_return_types2(T, Ps).
+
+doc_return_types2(void, []) -> "ok";
+doc_return_types2(void, [#arg{type=T}]) -> doc_arg_type2(T);
+doc_return_types2(T, []) -> doc_arg_type2(T);
+doc_return_types2(void, Ps) ->
+ "{" ++ args(fun doc_arg_type/1,",",Ps) ++ "}";
+doc_return_types2(T, Ps) ->
+ "{" ++ doc_arg_type2(T) ++ "," ++ args(fun doc_arg_type/1,",",Ps) ++ "}".
+
+doc_arg_type(#arg{name=Name,type=T}) ->
+ try
+ erl_arg_name(Name) ++ "::" ++ doc_arg_type2(T)
+ catch _:Error ->
+ io:format("Error: ~p ~p~n~p~n",[Name, Error, erlang:get_stacktrace()]),
+ exit(error)
+ end.
+
+doc_arg_type2(T=#type{single=true}) ->
+ doc_arg_type3(T);
+doc_arg_type2(T=#type{single=undefined}) ->
+ doc_arg_type3(T);
+doc_arg_type2(T=#type{single={tuple,undefined}}) ->
+ "{" ++ doc_arg_type3(T) ++ "}";
+doc_arg_type2(T=#type{single={tuple,_Sz}}) ->
+ "{" ++ doc_arg_type3(T) ++ "}";
+doc_arg_type2(T=#type{single=list}) ->
+ "[" ++ doc_arg_type3(T) ++ "]";
+doc_arg_type2(T=#type{single={list, Max}}) when is_integer(Max) ->
+ "[" ++ doc_arg_type3(T) ++ "]";
+doc_arg_type2(_T=#type{single={list,null}}) ->
+ "string()";
+doc_arg_type2(T=#type{base=string}) ->
+ doc_arg_type3(T);
+doc_arg_type2(T=#type{single={list,_,_}}) ->
+ "[" ++ doc_arg_type3(T) ++ "]";
+doc_arg_type2(T=#type{single={tuple_list,_TSz}}) ->
+ "[{" ++ doc_arg_type3(T) ++ "}]".
+
+doc_arg_type3(#type{name="GLenum"}) -> "enum()";
+doc_arg_type3(#type{name="GLclamp"++_}) -> "clamp()";
+doc_arg_type3(#type{base=int}) -> "integer()";
+doc_arg_type3(#type{base=float}) -> "float()";
+doc_arg_type3(#type{base=guard_int}) -> "offset()|binary()";
+doc_arg_type3(#type{base=string}) -> "string()";
+doc_arg_type3(#type{base=bool}) -> "0|1";
+doc_arg_type3(#type{base=binary}) -> "binary()";
+doc_arg_type3(#type{base=memory}) -> "wx:wx_mem()".
+
+guard_test(As) ->
+ Str = args(fun(#arg{name=N,type=#type{base=guard_int}}) ->
+ " is_integer("++erl_arg_name(N)++")";
+ (_) ->
+ skip
+ end, ",", As),
+ case Str of
+ [] -> [];
+ Other -> " when " ++ Other
+ end.
+
+pre_marshal([#arg{name=N,in=true,type=#type{base=binary}}|R]) ->
+ w(" wxe_util:send_bin(~s),~n", [erl_arg_name(N)]),
+ pre_marshal(R);
+pre_marshal([#arg{name=N,type=#type{base=memory}}|R]) ->
+ w(" wxe_util:send_bin(~s#wx_mem.bin),~n", [erl_arg_name(N)]),
+ pre_marshal(R);
+pre_marshal([A=#arg{name=N,type=#type{base=string,single=list}}|R]) ->
+ %% With null terminations
+ w(" ~sTemp = list_to_binary([[Str|[0]] || Str <- ~s ]),~n",
+ [erl_arg_name(N), erl_arg_name(N)]),
+ [A|pre_marshal(R)];
+pre_marshal([A|R]) ->
+ [A|pre_marshal(R)];
+pre_marshal([]) -> [].
+
+marshal_args(As) ->
+ marshal_args(As, [], 0).
+
+marshal_args([#arg{where=erl}|Ps], Margs, Align) ->
+ marshal_args(Ps, Margs, Align);
+marshal_args([#arg{where=c}|Ps], Margs, Align) ->
+ marshal_args(Ps, Margs, Align);
+marshal_args([#arg{in=false}|Ps], Margs, Align) ->
+ marshal_args(Ps, Margs, Align);
+marshal_args([#arg{name=Name, type=Type}|Ps], Margs, Align0) ->
+ {Arg,Align} = marshal_arg(Type,erl_arg_name(Name),Align0),
+ marshal_args(Ps, [Arg|Margs], Align);
+marshal_args([],Margs, Align) ->
+ {args(fun(Str) -> Str end, ",", reverse(Margs)), Align}.
+
+marshal_arg(#type{size=Sz,name=Type,single={tuple,undefined}},Name,A0) ->
+ KeepA = case Sz of 8 -> "0:32,"; _ -> "" end,
+ Str0 = "(size("++Name++")):?GLuint,"++KeepA++"\n"
+ " (<< <<C:?"++Type++ ">> ||"
+ "C <- tuple_to_list("++Name++")>>)/binary",
+ case Sz of
+ 4 ->
+ {Str,Align} = align(4,A0,Str0),
+ {Str++",0:((("++integer_to_list(Align div 4)++
+ "+size("++Name++")) rem 2)*32)",0};
+ 8 ->
+ align(8,A0,Str0)
+ end;
+marshal_arg(#type{size=BSz,name=Type,single={tuple,TSz}},Name,A0)
+ when is_integer(TSz) ->
+ NameId = hd(Name),
+ Names = [[NameId|integer_to_list(Id)] || Id <- lists:seq(1,TSz)],
+ All = args(fun(ElName) -> ElName ++ ":?" ++ Type end, ",", Names),
+ align(BSz,TSz,A0,All);
+
+marshal_arg(#type{size=BSz,name=Type,single={tuple,matrix12}},Name,A0) ->
+ NameId = hd(Name),
+ Ns0 = [[NameId|integer_to_list(Id)] || Id <- lists:seq(1,3)],
+ Ns1 = [[NameId|integer_to_list(Id)] || Id <- lists:seq(4,6)],
+ Ns2 = [[NameId|integer_to_list(Id)] || Id <- lists:seq(7,9)],
+ Ns3 = [[NameId|integer_to_list(Id)] || Id <- lists:seq(10,12)],
+ All = args(fun(ElName) -> ElName ++ ":?" ++ Type end, ",",
+ Ns0 ++ ["0"] ++ Ns1 ++ ["0"] ++ Ns2 ++ ["0"] ++ Ns3 ++ ["1"]),
+ align(BSz,16,A0,All);
+
+marshal_arg(#type{size=Sz,name=Type,base=Base,single=list},Name,A0)
+ when Base =:= float; Base =:= int ->
+ KeepA = case Sz of 8 -> "0:32,"; _ -> "" end,
+ Str0 = "(length("++Name++")):?GLuint,"++KeepA++"\n"
+ " (<< <<C:?"++Type++">> || C <- "++Name++">>)/binary",
+ {Str,Align} = align(max([Sz,4]),A0,Str0),
+ align_after(Sz,Align,0,1,Name,Str);
+
+marshal_arg(#type{base=guard_int},Name,A0) ->
+ align(4,A0,Name ++ ":?GLuint");
+
+marshal_arg(#type{size=Sz,name=Type,single=true,
+ by_val=true,ref=undefined},Name,A0) ->
+ align(Sz,A0,Name ++ ":?" ++ Type);
+
+marshal_arg(#type{size=8,name="GLUquadric"=Type},Name,A0) ->
+ align(8,A0,Name ++ ":?" ++ Type);
+
+marshal_arg(#type{base=string,single=true,ref={pointer,1}},Name,A0) ->
+ Str = "(list_to_binary(["++Name++"|[0]]))/binary", % Null terminate
+ align_after(1,A0,1,1,Name,Str);
+
+marshal_arg(#type{base=string,single=list,ref={pointer,2}},Name,A0) ->
+ Str0 =
+ "(length("++Name++")):?GLuint,"
+ "(size("++Name ++ "Temp)):?GLuint,"
+ "(" ++ Name ++ "Temp)/binary",
+ {Str,A} = align(4,A0,Str0),
+ {Str ++ ",0:((8-((size("++Name++"Temp)+"++
+ integer_to_list(A) ++") rem 8)) rem 8)", 0};
+
+marshal_arg(#type{size=Sz,name=Type,single={tuple_list,TSz}},Name,A0) ->
+ NameId = hd(Name),
+ Names = [[NameId|integer_to_list(Id)] || Id <- lists:seq(1,TSz)],
+ TTup = args(fun(ElName) -> ElName end, ",", Names),
+ TBin = args(fun(ElName) -> ElName ++ ":?" ++ Type end, ",", Names),
+
+ KeepA = case Sz of 8 -> "0:32,"; 4 -> "" end,
+ Str0 = "(length("++Name++")):?GLuint,"++KeepA++"\n"
+ " (<< <<"++TBin++">> || {"++TTup++"} <- "++Name++">>)/binary",
+ align(Sz,A0,Str0);
+
+marshal_arg(T=#type{}, Name, Align) ->
+ io:format("{\"~s\", {\"~s\", }}.~n", [get(current_func),lowercase(Name)]),
+ %%?error({unhandled_type, {Name,T}}).
+ w(" Don't know how to marshal this type ~p ~p ~n", [T,Name]),
+ align(8,Align,"").
+
+% Make sure that it is aligned before adding it, and update alignment
+align(Size, PreAlign, Str) ->
+ align(Size,1,PreAlign,Str).
+
+align(1,N,A,Str) -> {Str, (A+1*N+0) rem 8};
+
+align(2,N,A,Str) when (A rem 2) =:= 0 -> {Str, (A+2*N+0) rem 8};
+align(2,N,A,Str) when (A rem 2) =:= 1 -> {"0:8," ++Str, (A+2*N+1) rem 8};
+
+align(4,N,A,Str) when (A rem 4) =:= 0 -> {Str, (A+4*N+0) rem 8};
+align(4,N,A,Str) when (A rem 4) =:= 1 -> {"0:24,"++Str, (A+4*N+3) rem 8};
+align(4,N,A,Str) when (A rem 4) =:= 2 -> {"0:16,"++Str, (A+4*N+2) rem 8};
+align(4,N,A,Str) when (A rem 4) =:= 3 -> {"0:8," ++Str, (A+4*N+1) rem 8};
+
+align(8,_,0,Str) -> {Str, 0};
+align(8,_,1,Str) -> {"0:56,"++Str, 0};
+align(8,_,2,Str) -> {"0:48,"++Str, 0};
+align(8,_,3,Str) -> {"0:40,"++Str, 0};
+align(8,_,4,Str) -> {"0:32,"++Str, 0};
+align(8,_,5,Str) -> {"0:24,"++Str, 0};
+align(8,_,6,Str) -> {"0:16,"++Str, 0};
+align(8,_,7,Str) -> {"0:8," ++Str, 0}.
+
+align_after(8,0,_Add,_Multiplier,_Name,Str) -> {Str,0};
+align_after(4,0,Add,Mult,Name,Str) ->
+ Extra = extra_align(Add,Mult),
+ Align = ",0:(((length("++Name++")"++Extra++") rem 2)*32)",
+ {Str ++ Align,0};
+align_after(4,4,Add,Mult,Name,Str) ->
+ Extra = extra_align(Add,Mult),
+ Align = ",0:(((1+length("++Name++")"++Extra++") rem 2)*32)",
+ {Str ++ Align,0};
+align_after(2,A,Add,Mult,Name,Str) when (A rem 2) =:= 0 ->
+ Extra = extra_align(A+Add*2,Mult),
+ Align = ",0:((8-((length("++Name++")*2"++Extra++") rem 8)) rem 8)",
+ {Str ++ Align,0};
+align_after(1,A,Add,Mult,Name,Str) ->
+ Extra = extra_align(A+Add,Mult),
+ Align = ",0:((8-((length("++Name++")"++Extra++") rem 8)) rem 8)",
+ {Str ++ Align,0};
+align_after(Sz,A,Add,Mult,Name,Str) ->
+ io:format("~p ~p with ~p ~p ~s~n, ~p", [Sz,A,Add,Mult,Name,Str]),
+ ?error(align_error).
+
+extra_align(0,1) -> "";
+extra_align(0,M) when M > 1 -> "* " ++ integer_to_list(M);
+extra_align(A,1) when A > 0 -> "+ " ++ integer_to_list(A);
+extra_align(A,M) when A > 0,M>1 ->
+ "* " ++ integer_to_list(M) ++ "+ " ++ integer_to_list(A).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+have_return_vals(void, Ps) ->
+ lists:any(fun(#arg{in=In, type=#type{base=B}}) ->
+ In =/= true orelse B =:= memory
+ end, Ps);
+have_return_vals(#type{}, _) -> true.
+
+erl_func_name("glu" ++ Name) -> check_name(lowercase(Name));
+erl_func_name("gl" ++ Name) -> check_name(lowercase(Name)).
+
+erl_arg_name(Name) -> uppercase(Name).
+
+check_name("begin") -> "'begin'";
+check_name("end") -> "'end'";
+check_name(Other) -> Other.
+
+
+doc_name(Name0, Alt) ->
+ Name = doc_name2(Name0,Alt),
+%% case lists:member(lists:last(Name0), "uvbisdf987654312") of
+%% true -> io:format("~s ~s~n", [Name0,Name]);
+%% false -> ignore
+%% end,
+ Name.
+
+doc_name2(N="glGetBufferParameteriv", _) -> N;
+doc_name2(N="glEnd", _) -> N;
+doc_name2(Name, {has_vector,_,_}) ->
+ strip_hard(reverse(Name));
+doc_name2(Name, _) ->
+ reverse(strip(reverse(Name))).
+
+strip_hard(Rev) ->
+ case strip(Rev) of
+ Rev -> reverse(strip2(Rev));
+ Other -> reverse(Other)
+ end.
+
+strip("BRA"++R) -> "BRA"++strip(R);
+strip([$v,$b,$u,$N,N|R]) when N > 47, N < 58 ->R;
+strip([$v,$i,$u,$N,N|R]) when N > 47, N < 58 ->R;
+strip([$v,$s,$u,$N,N|R]) when N > 47, N < 58 ->R;
+strip([$v,$b,$N,N|R]) when N > 47, N < 58 -> R;
+strip([$v,$i,$N,N|R]) when N > 47, N < 58 -> R;
+strip([$v,$s,$N,N|R]) when N > 47, N < 58 -> R;
+strip([$v,$d,$N,N|R]) when N > 47, N < 58 -> R;
+strip([$v,$f,$N,N|R]) when N > 47, N < 58 -> R;
+strip([$b,$u,$N,N|R]) when N > 47, N < 58 -> R;
+
+strip([$v,$b,$u,N|R]) when N > 47, N < 58 ->R;
+strip([$v,$i,$u,N|R]) when N > 47, N < 58 ->R;
+strip([$v,$s,$u,N|R]) when N > 47, N < 58 ->R;
+strip([$v,$b,N|R]) when N > 47, N < 58 -> R;
+strip([$v,$i,N|R]) when N > 47, N < 58 -> R;
+strip([$v,$s,N|R]) when N > 47, N < 58 -> R;
+strip([$v,$d,N|R]) when N > 47, N < 58 -> R;
+strip([$v,$f,N|R]) when N > 47, N < 58 -> R;
+
+strip([$b,$u,N|R]) when N > 47, N < 58 ->R;
+strip([$i,$u,N|R]) when N > 47, N < 58 ->R;
+strip([$s,$u,N|R]) when N > 47, N < 58 ->R;
+strip([$b,N|R]) when N > 47, N < 58 -> R;
+strip([$i,N|R]) when N > 47, N < 58 -> R;
+strip([$s,N|R]) when N > 47, N < 58 -> R;
+strip([$d,N|R]) when N > 47, N < 58 -> R;
+strip([$f,N|R]) when N > 47, N < 58 -> R;
+
+strip([$v,$b,$u|R]) -> R;
+strip([$v,$i,$u|R]) -> R;
+strip([$v,$s,$u|R]) -> R;
+strip([$v,$b|R]) -> R;
+strip([$v,$i|R]) -> R;
+strip([$v,$s|R]) -> R;
+strip([$v,$d|R]) -> R;
+strip([$v,$f|R]) -> R;
+
+strip(R = "delban" ++ _) -> R;
+strip([$d,$e|R]) -> [$e|R];
+strip([$f,$e|R]) -> [$e|R];
+strip([$i,$e|R]) -> [$e|R];
+strip([$d,$x|R]) -> [$x|R];
+strip([$f,$x|R]) -> [$x|R];
+strip([$d,$d|R]) -> [$d|R];
+strip([$f,$d|R]) -> [$d|R];
+strip([$i,$l|R]) -> [$l|R];
+strip([$f,$l|R]) -> [$l|R];
+strip([$i,$r|R]) -> [$r|R];
+strip([$f,$r|R]) -> [$r|R];
+strip([$i,$g|R]) -> [$g|R];
+strip([$f,$g|R]) -> [$g|R];
+strip([$i,$n|R]) -> [$n|R];
+strip([$f,$n|R]) -> [$n|R];
+strip([$d,$n|R]) -> [$n|R];
+
+strip([$v,R]) -> R;
+strip([N|R]) when N > 47, N < 58 -> R;
+strip([_|R="tceRlg"]) -> R;
+strip([_|R="thgiLlg"]) -> R;
+strip(R) -> R.
+
+strip2([$b,$u|R]) -> R;
+strip2([$i,$u|R]) -> R;
+strip2([$s,$u|R]) -> R;
+strip2([$b|R]) -> R;
+strip2([$i|R]) -> R;
+strip2([$s|R]) -> R;
+strip2([$d|R]) -> R;
+strip2([$f|R]) -> R;
+strip2(R) -> R.
+
+gen_debug(GL, GLU) ->
+ open_write("../src/gen/gl_debug.hrl"),
+ erl_copyright(),
+ w("%% This file is generated DO NOT EDIT~n~n", []),
+ w("gldebug_table() -> ~n[~n", []),
+ [printd(F,gl) || F <- GL],
+ [printd(F,glu) || F <- GLU],
+ w(" {-1, {mod, func, -1}}~n",[]),
+ w("].~n~n", []),
+ close().
+
+printd([F|R],Mod) when is_list(F) ->
+ printd(F,Mod),
+ printd(R,Mod);
+printd([],_) -> ok;
+printd(F,Mod) ->
+ case get(F) of
+ #func{alt={vector,_VecPos,_Vec}} -> ok;
+ #func{where=erl} -> ok;
+ #func{id=Id, name=Method} ->
+ w(" {~p, {~s, ~s, 0}},~n", [Id, Mod, erl_func_name(Method)]);
+ _Other ->
+ io:format("F= ~p => ~p~n", [F, _Other])
+ end.
diff --git a/lib/wx/api_gen/gl_xml/.gitignore b/lib/wx/api_gen/gl_xml/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/wx/api_gen/gl_xml/.gitignore
diff --git a/lib/wx/api_gen/glapi.conf b/lib/wx/api_gen/glapi.conf
new file mode 100644
index 0000000000..f9ed7a1065
--- /dev/null
+++ b/lib/wx/api_gen/glapi.conf
@@ -0,0 +1,333 @@
+%% -*- erlang -*-
+% general options
+
+{skip, %% Skip these functions
+ [
+ %%% GLU
+ "glu", %% The ones we want is specified in keep
+ "gluQuad",
+ "gluBegin",
+ "gluEnd",
+ "gluNew",
+ "gluDelete",
+%% "gluTess",
+%% "gluGetNurbs",
+%% "gluGetTess",
+
+ %%% GL
+ "glProgramCallbackMESA",
+ "glGetProgramRegisterfvMESA",
+ "glGetPointerv",
+ "glGetBufferPointerv",
+ "glGetVertexAttribPointerv",
+ "glGetSeparableFilter",
+ "glMultiDrawElements",
+ "glMapBuffer",
+ "glUnmapBuffer",
+ "glEdgeFlagPointerEXT",
+ "glWeightPointerARB",
+ "glMatrixIndexPointerARB",
+ "glPixelTransformParameter",
+ %% OpengGL 3.0
+ %"glGetTransformFeedbackVarying", %% Jobbiga
+ %"glTransformFeedbackVaryings",
+
+ %% EXT
+ %% By default skip these extensions
+ "SGIX","SGIS","NV","ATI","AMD","SUN","SUNX","GREMEDY",
+ "HP","IBM","INTEL","APPLE","3DFX","PGI","EXT"]}.
+
+%% Exceptions to the above
+{keep,
+ [
+ %% GL_EXT_framebuffer_object
+ "glIsRenderbufferEXT",
+ "glBindRenderbufferEXT",
+ "glDeleteRenderbuffersEXT",
+ "glGenRenderbuffersEXT",
+ "glRenderbufferStorageEXT",
+ "glGetRenderbufferParameterivEXT",
+ "glIsFramebufferEXT",
+ "glBindFramebufferEXT",
+ "glDeleteFramebuffersEXT",
+ "glGenFramebuffersEXT",
+ "glCheckFramebufferStatusEXT",
+ "glFramebufferTexture1DEXT",
+ "glFramebufferTexture2DEXT",
+ "glFramebufferTexture3DEXT",
+ "glFramebufferRenderbufferEXT",
+ "glGetFramebufferAttachmentParameterivEXT",
+ "glGenerateMipmapEXT",
+ %% GL_ATI_separate_stencil
+ "glStencilOpSeparateATI",
+ "glStencilFuncSeparateATI",
+ %% GL_EXT_depth_bounds_test
+ "glDepthBoundsEXT",
+ %% GL_EXT_blend_equation_separate
+ "glBlendEquationSeparateEXT",
+ %% GL_EXT_stencil_clear_tag
+ "glStencilClearTagEXT",
+ %% GL_EXT_framebuffer_blit
+ "glBlitFramebufferEXT",
+ %% GL_EXT_framebuffer_multisample
+ "glRenderbufferStorageMultisampleEXT",
+
+ "gluBuild", % mipmaps*
+ "gluCheckExtension", "gluErrorString", "gluGetString",
+ "gluLookAt", "gluOrtho2D", "gluPerspective", "gluPickMatrix",
+ "gluScaleImage",
+
+ "gluNewQuadric", "gluDeleteQuadric",
+ "gluQuadricTexture", "gluQuadricOrientation", "gluQuadricNormals", "gluQuadricDrawStyle",
+ "gluDisk", "gluCylinder", "gluPartialDisk", "gluSphere",
+
+ "gluProject", "gluUnProject"
+ ]}.
+
+{vector, [{"glMultiTexCoord",1}, {"glConvolutionParameter",2},{"glVertexAttrib",1}, {"glVertexAttribI",1}]}.
+
+%% function specific information
+
+{"glBitmap", {"bitmap", {base,idx_binary}}}.
+{"glPolygonStipple", {"mask", binary}}.
+{"glGetPolygonStipple", [{"mask", [{binary, 128},out, {single,true}]}]}.
+{"glClipPlane", {"equation", {single,{tuple,4}}}}.
+{"glGetClipPlane", {"equation", {single,{tuple,4}}}}.
+{"glLoadMatrix", {"m", {single,{tuple,matrix}}}}.
+{"glMultMatrix", {"m", {single,{tuple,matrix}}}}.
+{"glCallLists", [{"n", {c_only, {length, "lists"}}},
+ {"type", {c_only, {constant, "GL_UNSIGNED_INT"}}},
+ {"lists", [{single,list},{type,"GLuint"}, {base,int}]}]}.
+{"glLight", {"params", {single,{tuple,undefined}}}}.
+{"glGetLight", {"params", {single, {tuple, 4}}}}.
+{"glMaterial", {"params", {single,{tuple,undefined}}}}.
+{"glGetMaterial", {"params", {single, {tuple, 4}}}}.
+{"glPixelMap", {"values", binary}}.
+{"glGetPixelMap", {"values", [{base,memory}, in]}}.
+{"glTexGen", {"params",{single,{tuple,undefined}}}}.
+{"glGetTexGen", {"params",{single,{tuple,4}}}}.
+{"glTexEnv", {"params",{single,{tuple,undefined}}}}.
+{"glGetTexEnv", {"params",{single,{tuple,4}}}}.
+{"glTexParameter", {"params",{single,{tuple,undefined}}}}.
+{"glGetTexParameter", {"params",{single,{tuple,4}}}}.
+{"glGetTexLevelParameter", {"params", {single,{tuple,1}}}}.
+{"glGenTextures", [{"textures", {single,{list,"n","n"}}}]}.
+{"glDeleteTextures", [{"n", {c_only, {length, "textures"}}},
+ {"textures", [{single,list}]}]}.
+{"glPrioritizeTextures", [{"n", {c_only, {length, "textures"}}},
+ {"textures", [{single,list}]},
+ {"priorities", [{single,list}]}]}.
+{"glAreTexturesResident", [{"n", {c_only,{length,"textures"}}},
+ {"textures", [{single,list}]},
+ {"residences", [{single,{list,"texturesLen","texturesLen"}}]}]}.
+{"glMap", {"points", binary}}.
+{"glGetMap", {"v", [{base,memory},in]}}.
+{"glFog", {"params", {single,{tuple,undefined}}}}.
+{"glColorTableParameter", {"params",{single,{tuple,4}}}}.
+{"glGetColorTable", {"table", [{base,memory},in]}}.
+{"glGetColorTableParameter", {"params", {single,{tuple,4}}}}.
+{"glGetHistogram", {"values", [{base,memory}, in]}}.
+{"glGetHistogramParameter", {"params", {single,{tuple,1}}}}.
+{"glGetMinmax", {"values", [{base,memory}, in]}}.
+{"glGetMinmaxParameter", {"params", {single,{tuple,1}}}}.
+{"glGetConvolutionFilter", {"image", [{base,memory}, in]}}.
+{"glConvolutionParameter", {"params", {single,{tuple,undefined}} }}.
+{"glGetConvolutionParameter", {"params", {single,{tuple,4}}}}.
+
+{"glRect", [{"v1", {single,{tuple,2}}},{"v2", {single,{tuple,2}}}]}.
+
+{"glGetString", {"result", {single,{list,null}}}}.
+{"glGetBooleanv", {"params", {single,{list,16}}}}.
+{"glGetDoublev", {"params", {single,{list,16}}}}.
+{"glGetFloatv", {"params", {single,{list,16}}}}.
+{"glGetIntegerv", {"params", {single,{list,16}}}}.
+
+{"glFeedbackBuffer", {"buffer", [{base,memory}, in]}}.
+{"glSelectBuffer", {"buffer", [{base,memory}, in]}}.
+{"glReadPixels", {"pixels", [{base,memory}, in]}}.
+{"glGetTexImage", {"pixels", [{base,memory}, in]}}.
+{"glGetCompressedTexImage", {"img", [{base,memory}, in]}}.
+
+{"glLoadTransposeMatrix", {"m", {single,{tuple,matrix}}}}.
+{"glMultTransposeMatrix", {"m",{single,{tuple,matrix}}}}.
+
+{"glMultiDrawArrays", [{"first", [in,{single,list}]},
+ {"count", [in,{single,list}]},
+ {"primcount", {c_only, {length,"first"}}}]}.
+
+{"glGenQueries", {"ids", {single,{list, "n", "n"}}}}.
+{"glGetQueryiv", {"params", {single, true}}}.
+{"glGetQueryObject", {"params", {single, true}}}.
+
+{"glPointParameter", {"params", {single,{tuple,undefined}} }}.
+{"glDeleteQueries", [{"n",{c_only,{length,"ids"}}},{"ids",[{single,list}]}]}.
+{"glGenBuffers", {"buffers",[{single,{list,"n","n"}}]}}.
+{"glGetBufferSubData", {"data", [{base,memory}, in]}}.
+{"glGetBufferParameteriv", {"params", {single,true}}}.
+{"glDeleteBuffers", [{"n",{c_only,{length,"buffers"}}},{"buffers",[{single,list}]}]}.
+{"glDrawBuffers", [{"n",{c_only,{length,"bufs"}}},{"bufs",[{single,list}]}]}.
+
+{"glShaderSource", [{"length", {c_only,{constant,"NULL"}}},
+ {"count", {c_only,{length,"string"}}},
+ {"string", {single,list}}]}.
+
+{"glGetActiveAttribARB", [{"length",[skip,{single, true}]},
+ {"size", {single, true}},
+ {"type", {single, true}},
+ {"name", {single, {list,"maxLength","length"}}}
+ ]}.
+
+{"glGetActiveAttrib", [{"length",[skip,{single, true}]},
+ {"size", {single, true}},
+ {"type", {single, true}},
+ {"name", {single, {list,"bufSize","length"}}}
+ ]}.
+
+{"glGetActiveUniformARB", [{"length",[skip,{single, true}]},
+ {"size", {single, true}},
+ {"type", {single, true}},
+ {"name", {single, {list,"maxLength","length"}}}
+ ]}.
+{"glGetActiveUniform", [{"length",[skip,{single, true}]},
+ {"size", {single, true}},
+ {"type", {single, true}},
+ {"name", {single, {list,"bufSize","length"}}}
+ ]}.
+
+{"glGetAttachedShaders", [{"count", [skip,{single,true}]},
+ {"obj", {single, {list,"maxCount","count"}}}
+ ]}.
+
+{"glGetProgramiv", {"params", {single,true}}}.
+
+{"glGetProgramInfoLog", [{"length", [skip,{single,true}]},
+ {"infoLog", {single, {list,"bufSize","length"}}}
+ ]}.
+{"glGetShaderiv", {"params", {single,true}}}.
+{"glGetShaderInfoLog", [{"length", [skip,{single,true}]},
+ {"infoLog", {single, {list,"bufSize","length"}}}
+ ]}.
+
+{"glGetShaderSourceARB", [{"length", [skip,{single,true}]},
+ {"source", {single, {list,"maxLength","length"}}}
+ ]}.
+{"glGetShaderSource", [{"length", [skip,{single,true}]},
+ {"source", {single, {list,"bufSize","length"}}}
+ ]}.
+
+
+{"glGetUniform", {"params", {single,{tuple,16}}}}.
+{"glGetVertexAttrib", {"params", {single,{tuple,4}}}}.
+
+{"glUniform1", [{"count",{c_only,{length,"value"}}}, {"value", [{single,list}]}]}.
+{"glUniform2", [{"count",{c_only,{length,"value"}}}, {"value", [{single,{tuple_list,2}}]}]}.
+{"glUniform3", [{"count",{c_only,{length,"value"}}}, {"value", [{single,{tuple_list,3}}]}]}.
+{"glUniform4", [{"count",{c_only,{length,"value"}}}, {"value", [{single,{tuple_list,4}}]}]}.
+{"glUniformMatrix2fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,4}}]}]}.
+{"glUniformMatrix3fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,9}}]}]}.
+{"glUniformMatrix4fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,16}}]}]}.
+{"glUniformMatrix2x3fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,6}}]}]}.
+{"glUniformMatrix3x2fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,6}}]}]}.
+{"glUniformMatrix2x4fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,8}}]}]}.
+{"glUniformMatrix4x2fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,8}}]}]}.
+{"glUniformMatrix3x4fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,12}}]}]}.
+{"glUniformMatrix4x3fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,12}}]}]}.
+{"glVertexAttrib4", {"v", {single, {tuple,4}}}}.
+
+
+{"glWeight", [{"size",{c_only,{length,"weights"}}}, {"weights", {single,list}}]}.
+{"glMatrixIndex", [{"size",{c_only,{length,"indices"}}}, {"indices", {single,list}}]}.
+
+
+{"glProgramStringARB", [{"len",{c_only,{constant,"stringLen"}}},
+ {"string",[{base,string},{single,true}]}]}.
+{"glGetProgramStringARB", {"string", [in,{base,memory}]}}.
+{"glGenProgramsARB", {"programs", {single,{list,"n","n"}}}}.
+{"glDeleteProgramsARB", [{"n",{c_only,{length,"programs"}}},{"programs",{single,list}}]}.
+{"glProgramEnvParameter4", {"params", {single,{tuple,4}}}}.
+{"glGetProgramEnvParameter", {"params", {single,{tuple,4}}}}.
+{"glProgramLocalParameter", {"params", {single,{tuple,4}}}}.
+{"glGetProgramLocalParameter", {"params", {single,{tuple,4}}}}.
+{"glGetObjectParameter", {"params", {single,true}}}.
+{"glGetInfoLogARB", [{"length", [skip,{single,true}]},
+ {"infoLog", {single, {list,"maxLength","length"}}}
+ ]}.
+{"glGetAttachedObjectsARB", [{"count", [skip,{single,true}]},
+ {"obj", {single, {list,"maxCount","count"}}}
+ ]}.
+
+{"glGenRenderbuffersEXT", {"renderbuffers", {single,{list,"n","n"}}}}.
+{"glDeleteRenderbuffersEXT",[{"n",{c_only,{length,"renderbuffers"}}},{"renderbuffers",{single,list}}]}.
+{"glDeleteFramebuffersEXT", [{"n",{c_only,{length,"framebuffers"}}},{"framebuffers",{single,list}}]}.
+{"glGetRenderbufferParameterivEXT", {"params", {single,true}}}.
+
+{"glGetFramebufferAttachmentParameterivEXT", {"params",{single,true}}}.
+{"glGenFramebuffersEXT", {"framebuffers",{single,{list,"n","n"}}}}.
+
+{"gluPickMatrix", {"viewport", [in, {single, {tuple, 4}}]}}.
+{"gluProject", [{"model", {single, {tuple, matrix}}},
+ {"proj", {single, {tuple, matrix}}},
+ {"view", {single, {tuple, 4}}},
+ {"winX", [{single,true},out]},
+ {"winY", [{single,true},out]},
+ {"winZ", [{single,true},out]}]}.
+{"gluUnProject", [{"model", {single, {tuple, matrix}}},
+ {"proj", {single, {tuple, matrix}}},
+ {"view", {single, {tuple, 4}}},
+ {"objX",[{single,true},out]},
+ {"objY",[{single,true},out]},
+ {"objZ",[{single,true},out]},
+ {"objW",[{single,true},out]}]}.
+{"gluBuild", {"data", [binary]}}.
+{"gluScaleImage", [{"dataIn", [in, binary]}, {"dataOut", [in, {base, memory}]}]}.
+{"gluCheckExtension", [{"extName", {single, list}}, {"extString", {single, list}}]}.
+{"gluErrorString", {"result", {single, {list,null}}}}.
+{"gluGetString", {"result", {single, {list,null}}}}.
+
+{"gluDeleteQuadric", {"quad", in}}.
+{"gluQuadric", {"quad", in}}.
+{"gluSphere", {"quad", in}}.
+{"gluPartialDisk", {"quad", in}}.
+{"gluDisk", {"quad", in}}.
+{"gluCylinder", {"quad", in}}.
+
+%% OpenGL 3.0
+{"glGetBooleani_v", {"data", {single,{list,16}}}}.
+{"glGetIntegeri_v", {"data", {single,{list,16}}}}.
+
+{"glTransformFeedbackVaryings", [{"count", {c_only,{length,"varyings"}}},
+ {"varyings", [{base,string}, {single,list}]}]}.
+{"glGetTransformFeedbackVarying", [{"size", {single, true}},{"type", {single, true}},
+ {"length", [skip, {single, true}]},
+ {"name", {single, {list,"bufSize","length"}}}]}.
+
+
+{"glGenRenderbuffers", {"renderbuffers", {single,{list,"n","n"}}}}.
+{"glGenFramebuffers", {"framebuffers",{single,{list,"n","n"}}}}.
+{"glGetRenderbufferParameteriv", {"params", {single,true}}}.
+{"glGetFramebufferAttachmentParameteriv", {"params",{single,true}}}.
+{"glGenVertexArrays", {"arrays", {single, {list,"n","n"}}}}.
+{"glGenRenderbuffers", {"renderbuffers", {single,{list,"n","n"}}}}.
+{"glDeleteRenderbuffers",[{"n",{c_only,{length,"renderbuffers"}}},
+ {"renderbuffers",{single,list}}]}.
+{"glDeleteFramebuffers", [{"n",{c_only,{length,"framebuffers"}}},
+ {"framebuffers",{single,list}}]}.
+{"glVertexAttribI4", {"v", {single, {tuple,4}}}}.
+%% {"glVertexAttribI4", {"v", }}.
+%% {"glVertexAttribI4ubv", {"v", }}.
+%% {"glVertexAttribI4usv", {"v", }}.
+{"glClearBuffer", {"value", {single, {tuple, undefined}}}}.
+{"glDeleteVertexArrays", [{"n",{c_only,{length,"arrays"}}},{"arrays", {single, list}}]}.
+
+{"glGetUniformIndices", [{"uniformCount", {c_only, {length, "uniformNames"}}},
+ {"uniformNames", [{base,string}, {single,list}]},
+ {"uniformIndices", [out, {single,{list, "uniformNamesLen", "uniformNamesLen"}}]}]}.
+{"glGetActiveUniformsiv", [{"uniformCount", {c_only, {length, "uniformIndices"}}},
+ {"uniformIndices", {single,list}},
+ {"params", [out, {single, {list, "uniformIndicesLen", "uniformIndicesLen"}}]}]}.
+
+{"glGetActiveUniformName", [{"length",[skip,{single, true}]},
+ {"uniformName", {single, {list,"bufSize","length"}}}]}.
+{"glGetActiveUniformBlockName", [{"length",[skip,{single, true}]},
+ {"uniformBlockName", {single, {list,"bufSize","length"}}}]}.
+{"glGetActiveUniformBlockiv", {"params", [in, {base,memory}]}}.
diff --git a/lib/wx/api_gen/wx_doxygen.conf b/lib/wx/api_gen/wx_doxygen.conf
new file mode 100644
index 0000000000..1fc57486e6
--- /dev/null
+++ b/lib/wx/api_gen/wx_doxygen.conf
@@ -0,0 +1,299 @@
+# Doxyfile 1.4.3
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = wxe
+PROJECT_NUMBER = 0.1
+OUTPUT_DIRECTORY = ./
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+USE_WINDOWS_ENCODING = NO
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF =
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH =
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP = NO
+INHERIT_DOCS = YES
+DISTRIBUTE_GROUP_DOC = NO
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 8
+ALIASES =
+OPTIMIZE_OUTPUT_FOR_C = YES
+OPTIMIZE_OUTPUT_JAVA = NO
+SUBGROUPING = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = YES
+EXTRACT_STATIC = YES
+EXTRACT_LOCAL_CLASSES = YES
+EXTRACT_LOCAL_METHODS = YES
+EXTRACT_ANON_NSPACES = YES
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = YES
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = NO
+INLINE_INFO = NO
+SORT_MEMBER_DOCS = NO
+SORT_BRIEF_DOCS = NO
+SORT_BY_SCOPE_NAME = NO
+GENERATE_TODOLIST = NO
+GENERATE_TESTLIST = NO
+GENERATE_BUGLIST = NO
+GENERATE_DEPRECATEDLIST= NO
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_DIRECTORIES = YES
+FILE_VERSION_FILTER =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = YES
+WARNINGS = NO
+WARN_IF_UNDOCUMENTED = NO
+WARN_IF_DOC_ERROR = NO
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = @WXGTK_DIR@/wx/ wx_extra/
+#FILE_PATTERNS = *.h
+RECURSIVE = YES
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS = mac/* mgl/* msw/* os2/* x11/* gtk1/* cocoa/* motif/* msdos/* palmos/* private/*
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+USE_HTAGS = NO
+VERBATIM_HEADERS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = NO
+HTML_OUTPUT = html
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = NO
+ENUM_VALUES_PER_LINE = 4
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = NO
+USE_PDFLATEX = NO
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = YES
+XML_OUTPUT = ./wx_xml/
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = NO
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED = \
+ wxUSE_MENUS=1 \
+ wxUSE_TOOLBAR=1 \
+ wxUSE_CONTROLS=1 \
+ wxUSE_BUTTON=1 \
+ wxUSE_STATBOX=1 \
+ wxUSE_BOOKCTRL=1 \
+ wxUSE_CHOICE=1 \
+ wxUSE_STATUSBAR=1 \
+ wxUSE_TEXTCTRL=1 \
+ wxUSE_GUI=1 \
+ wxUSE_GRID=1 \
+ wxUSE_TOGGLE_BTN=1 \
+ wxUSE_MSGDLG=1 \
+ wxUSE_FILEDLG=1 \
+ wxUSE_XRC=1 \
+ wxUSE_STATTEXT=1 \
+ wxUSE_STATLINE=1 \
+ wxUSE_LISTCTRL=1 \
+ wxUSE_ACCEL=1 \
+ wxUSE_CARET=1 \
+ wxUSE_CONSTRAINTS=1 \
+ wxUSE_TOOLTIPS=1 \
+ wxUSE_DRAG_AND_DROP=1 \
+ wxUSE_HELP=1 \
+ wxUSE_IMAGE=1 \
+ wxUSE_VALIDATORS=1 \
+ wxUSE_UNICODE=1 \
+ wxUSE_CALENDARCTRL=1 \
+ wxUSE_DATETIME=1 \
+ wxUSE_COMBOBOX=1 \
+ wxUSE_GAUGE=1 \
+ wxUSE_LISTBOX=1 \
+ wxUSE_BMPBUTTON=1 \
+ wxUSE_CHECKBOX=1 \
+ wxUSE_TREECTRL=1 \
+ wxUSE_LISTCTRL=1 \
+ wxUSE_BOOKCTRL=1 \
+ wxUSE_NOTEBOOK=1 \
+ wxUSE_CHOICEBOOK=1 \
+ wxUSE_TOOLBOOK=1 \
+ wxUSE_LISTBOOK=1 \
+ wxUSE_TREEBOOK=1 \
+ wxUSE_SPINBTN=1 \
+ wxUSE_FINDREPLDLG=1 \
+ wxUSE_TEXTDLG=1 \
+ wxUSE_FONTDLG=1 \
+ wxUSE_DIRDLG=1 \
+ wxUSE_PRINTING_ARCHITECTURE=1 \
+ wxUSE_HTML=1 \
+ wxUSE_POSTSCRIPT=1 \
+ wxUSE_PROGRESSDLG=1 \
+ wxUSE_RADIOBOX=1 \
+ wxUSE_MINIFRAME=1 \
+ wxUSE_PALETTE=1 \
+ wxUSE_SASH=1 \
+ wxTopLevelWindowNative=1 \
+ wxUSE_GLCANVAS=1 \
+ wxUSE_GRAPHICS_CONTEXT=1 \
+ wxUSE_AUI=1 \
+ wxUSE_MDI_ARCHITECTURE=1 \
+ wxUSE_FILEPICKERCTRL=1 \
+ wxUSE_DIRPICKERCTRL=1 \
+ wxUSE_FONTPICKERCTRL=1 \
+ wxUSE_DATEPICKCTRL=1 \
+ wxUSE_COLOURPICKERCTRL=1 \
+ wxUSE_DATAOBJ=1 \
+ wxUSE_SLIDER=1 \
+ wxUSE_CLIPBOARD=1 \
+ wxABI_VERSION=20809 \
+ __WXGTK24__=1 \
+ __WXGTK__=1 \
+ WXDLLEXPORT=""
+
+# WXWIN_COMPATIBILITY_2_6=1 \
+
+EXPAND_AS_DEFINED = YES
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH = /bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = YES
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = NO
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+TEMPLATE_RELATIONS = NO
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = NO
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+DOT_PATH =
+DOTFILE_DIRS =
+MAX_DOT_GRAPH_WIDTH = 1024
+MAX_DOT_GRAPH_HEIGHT = 1024
+MAX_DOT_GRAPH_DEPTH = 0
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
+
diff --git a/lib/wx/api_gen/wx_extra/bugs.h b/lib/wx/api_gen/wx_extra/bugs.h
new file mode 100644
index 0000000000..b8f3dfcb00
--- /dev/null
+++ b/lib/wx/api_gen/wx_extra/bugs.h
@@ -0,0 +1,36 @@
+
+// I have added this doxygen seems to get lost in some macros
+// in sashwin.h
+
+enum wxSashDragStatus
+ {
+ wxSASH_STATUS_OK,
+ wxSASH_STATUS_OUT_OF_RANGE
+ };
+
+// Macro needed in erlang
+class WXDLLIMPEXP_XRC wxXmlResource : public wxObject
+{
+ public:
+ wxObject xrcctrl(wxWindow *Window, wxString Name, wxString Type);
+};
+
+// The generater needs constructors
+class WXDLLIMPEXP_ADV wxGridCellBoolRenderer : public wxGridCellRenderer
+{
+ public:
+ wxGridCellBoolRenderer();
+};
+
+class WXDLLIMPEXP_ADV wxGridCellStringRenderer : public wxGridCellRenderer
+{
+ public:
+ wxGridCellStringRenderer();
+};
+
+class WXDLLIMPEXP_ADV wxGridCellNumberRenderer : public wxGridCellStringRenderer
+{
+ public:
+ wxGridCellNumberRenderer();
+};
+
diff --git a/lib/wx/api_gen/wx_extra/wxEvtHandler.c_src b/lib/wx/api_gen/wx_extra/wxEvtHandler.c_src
new file mode 100644
index 0000000000..4e492db045
--- /dev/null
+++ b/lib/wx/api_gen/wx_extra/wxEvtHandler.c_src
@@ -0,0 +1,66 @@
+case 98: { // wxeEvtListener::wxeEvtListener
+ wxeEvtListener *Result = new wxeEvtListener(Ecmd.port);
+ rt.addRef(getRef((void *)Result,memenv), "wxeEvtListener");
+ break;
+}
+case 99: { // wxeEvtListener::destroy
+ wxObject *This = (wxObject *) getPtr(bp,memenv);
+ rt.addAtom("ok");
+ delete This;
+ break;
+}
+
+case 100: { // wxEvtHandler::Connect
+ wxeEvtListener *Listener = (wxeEvtListener *) getPtr(bp,memenv); bp += 4;
+ wxEvtHandler *This = (wxEvtHandler *) getPtr(bp, memenv); bp += 4;
+ int * winid = (int *) bp; bp += 4;
+ int * lastId = (int *) bp; bp += 4;
+ int * skip = (int *) bp; bp += 4;
+ int * haveUserData = (int *) bp; bp += 4;
+ wxeErlTerm * userData = NULL;
+ int * fun_cb = (int *) bp; bp += 4;
+ int * eventTypeLen = (int *) bp; bp += 4;
+ int * class_nameLen = (int *) bp; bp += 4;
+
+ if(*haveUserData) {
+ userData = new wxeErlTerm(Ecmd.bin[0]);
+ }
+
+ int eventType = wxeEventTypeFromAtom(bp); bp += *eventTypeLen;
+ char *class_name = bp; bp+= *class_nameLen;
+ if(eventType > 0 ) {
+ wxeCallbackData * Evt_cb = new wxeCallbackData(Ecmd.caller,(void *) This,
+ class_name,*fun_cb,
+ *skip, userData);
+ This->Connect((int) *winid,(int) *lastId,eventType,
+ (wxObjectEventFunction)(wxEventFunction) &wxeEvtListener::forward,
+ Evt_cb, Listener);
+ rt.addAtom("ok");
+ } else {
+ rt.addAtom("badarg");
+ rt.addAtom("event_type");
+ rt.addTupleCount(2);
+ }
+ break;
+}
+case 101: { // wxEvtHandler::Disconnect
+ wxeEvtListener *Listener = (wxeEvtListener *) getPtr(bp,memenv); bp += 4;
+ wxEvtHandler *This = (wxEvtHandler *) getPtr(bp, memenv); bp += 4;
+ int * winid = (int *) bp; bp += 4;
+ int * lastId = (int *) bp; bp += 4;
+ int * eventTypeLen = (int *) bp; bp += 4;
+
+ int eventType = wxeEventTypeFromAtom(bp); bp += *eventTypeLen;
+ if(eventType > 0) {
+ bool Result = This->Disconnect((int) *winid,(int) *lastId,eventType,
+ (wxObjectEventFunction)(wxEventFunction)
+ &wxeEvtListener::forward,
+ NULL, Listener);
+ rt.addBool(Result);
+ } else {
+ rt.addAtom("badarg");
+ rt.addAtom("event_type");
+ rt.addTupleCount(2);
+ }
+ break;
+}
diff --git a/lib/wx/api_gen/wx_extra/wxEvtHandler.erl b/lib/wx/api_gen/wx_extra/wxEvtHandler.erl
new file mode 100644
index 0000000000..c6810eb32c
--- /dev/null
+++ b/lib/wx/api_gen/wx_extra/wxEvtHandler.erl
@@ -0,0 +1,183 @@
+%% This module is actually handwritten see ../api_gen/wx_extra/wxEvtHandler.erl
+%%
+%% @doc The Event handler.
+%%
+%% To get events from wxwidgets objects you subscribe to them by
+%% calling connect/[2-3]. Events are sent as messages, if no callback
+%% was supplied These messages will be {@link wx(). #wx{}} where
+%% EventRecord is a record that depends on the {@link
+%% wxEventType(). event type}. The records are defined in:
+%% wx/include/wx.hrl.
+%%
+%% If a callback was supplied to connect, the callback will be invoked
+%% (in another process) to handle the event. The callback should be of
+%% arity 2. fun(EventRecord::wx(), EventObject::wxObject()).
+%%
+%% Beware that the callback will be in executed in new process each time.
+%%
+%% <a href="http://www.wxwidgets.org/manuals/stable/wx_wxevthandler.html">
+%% The orginal documentation</a>.
+%%
+%% @headerfile "../../include/wx.hrl"
+%%
+%%@type wxEvtHandler(). An object reference
+
+-module(wxEvtHandler).
+-include("wxe.hrl").
+-include("../include/wx.hrl").
+
+%% API
+-export([connect/2, connect/3, disconnect/1, disconnect/2, disconnect/3]).
+
+%% internal exports
+-export([connect_impl/3, disconnect_impl/2, disconnect_impl/3,
+ new_evt_listener/0, destroy_evt_listener/1,
+ get_callback/1, replace_fun_with_id/2]).
+
+-record(evh, {et=null,id=?wxID_ANY,lastId=?wxID_ANY,skip=undefined,userdata=[],cb=0}).
+
+
+
+%% @spec (This::wxEvtHandler(), EventType::wxEventType()) -> ok
+%% @doc Equivalent to {@link connect/3. connect(This, EventType, [])}
+
+connect(This, EventType) ->
+ connect(This, EventType, []).
+
+%% @spec (This::wxEvtHandler(), EventType::wxEventType(), [Options]) -> ok
+%% @doc This function subscribes the to events of EventType,
+%% in the range id, lastId. The events will be received as messages
+%% if no callback is supplied.
+%%
+%% Options:
+%% {id, integer()}, The identifier (or first of the identifier range) to be
+%% associated with this event handler.
+%% Default ?wxID_ANY
+%% {lastId, integer()}, The second part of the identifier range.
+%% If used 'id' must be set as the starting identifier range.
+%% Default ?wxID_ANY
+%% {skip, boolean()}, If skip is true further event_handlers will be called.
+%% This is not used if the 'callback' option is used.
+%% Default false.
+%% {callback, function()} Use a callback fun(EventRecord::wx(), EventObject::wxObject())
+%% to process the event. Default not specfied i.e. a message will
+%% be delivered to the process calling this function.
+%% {userData, term()} An erlang term that will be sent with the event. Default: [].
+connect(This=#wx_ref{type=ThisT}, EventType, Options) ->
+ EvH = parse_opts(Options, #evh{et=EventType}),
+ ?CLASS(ThisT,wxEvtHandler),
+ case wxe_util:connect_cb(This, EvH) of
+ ok -> ok;
+ {badarg, event_type} ->
+ erlang:error({badarg,EventType})
+ end.
+
+parse_opts([{callback,Fun}|R], Opts) when is_function(Fun) ->
+ %% Check Fun Arity?
+ parse_opts(R, Opts#evh{cb=Fun});
+parse_opts([callback|R], Opts) ->
+ parse_opts(R, Opts#evh{cb=1});
+parse_opts([{userData, UserData}|R],Opts) ->
+ parse_opts(R, Opts#evh{userdata=UserData});
+parse_opts([{skip, Skip}|R],Opts) when is_boolean(Skip) ->
+ parse_opts(R, Opts#evh{skip=Skip});
+parse_opts([{id, Id}|R],Opts) when is_integer(Id) ->
+ parse_opts(R, Opts#evh{id=Id});
+parse_opts([{lastId, Id}|R],Opts) when is_integer(Id) ->
+ parse_opts(R, Opts#evh{lastId=Id});
+parse_opts([_BadArg|R], Opts) ->
+ parse_opts(R, Opts);
+parse_opts([], Opts = #evh{id=Id,lastId=Lid,skip=Skip, cb=CB}) ->
+ if
+ Skip =/= undefined andalso CB =/= 0 ->
+ erlang:error({badarg, {combined, skip, callback}});
+ Lid =/= ?wxID_ANY andalso Id =:= ?wxID_ANY ->
+ erlang:error({badarg, no_start_identifier_range});
+ Skip =:= undefined -> %% Default
+ Opts#evh{skip=false};
+ true ->
+ Opts
+ end.
+
+%% @spec (This::wxEvtHandler()) -> true | false
+%% @doc Equivalent to {@link disconnect/3. disconnect(This, null, [])}
+%% Can also have an optional callback Fun() as an additional last argument.
+
+disconnect(This=#wx_ref{type=ThisT,ref=_ThisRef}) ->
+ ?CLASS(ThisT,wxEvtHandler),
+ disconnect(This, null, []).
+
+%% @spec (This::wxEvtHandler(), EventType::wxEventType()) -> true | false
+%% @doc Equivalent to {@link disconnect/3. disconnect(This, EventType, [])}
+disconnect(This=#wx_ref{type=ThisT,ref=_ThisRef}, EventType) when is_atom(EventType) ->
+ ?CLASS(ThisT,wxEvtHandler),
+ disconnect(This, EventType, []).
+
+%% @spec (This::wxEvtHandler(), EventType::wxEventType(), Opts) -> true | false
+%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxevthandler.html#wxevthandlerdisconnect">external documentation</a>
+%% This function unsubscribes the process or callback fun from the event handler.
+%% EventType may be the atom 'null' to match any eventtype.
+%% Notice that the options skip and userdata is not used to match the eventhandler.
+disconnect(This=#wx_ref{type=ThisT,ref=_ThisRef}, EventType, Opts) ->
+ ?CLASS(ThisT,wxEvtHandler),
+ EvH = parse_opts(Opts, #evh{et=EventType}),
+ case wxe_util:disconnect_cb(This, EvH) of
+ {badarg, event_type} ->
+ erlang:error({badarg,EventType});
+ Bool ->
+ Bool
+ end.
+
+
+%% @hidden
+connect_impl(#wx_ref{type=wxeEvtListener,ref=EvtList},
+ #wx_ref{type=ThisT,ref=ThisRef},
+ #evh{id=Winid, lastId=LastId, et=EventType,
+ skip=Skip, userdata=Userdata, cb=FunID})
+ when is_integer(FunID)->
+ EventTypeBin = list_to_binary([atom_to_list(EventType)|[0]]),
+ ThisTypeBin = list_to_binary([atom_to_list(ThisT)|[0]]),
+ UD = if Userdata =:= [] -> 0;
+ true ->
+ wxe_util:send_bin(term_to_binary(Userdata)),
+ 1
+ end,
+ wxe_util:call(100, <<EvtList:32/?UI,ThisRef:32/?UI,
+ Winid:32/?UI,LastId:32/?UI,
+ (wxe_util:from_bool(Skip)):32/?UI,
+ UD:32/?UI,
+ FunID:32/?UI,
+ (size(EventTypeBin)):32/?UI,
+ (size(ThisTypeBin)):32/?UI,
+ %% Note no alignment
+ EventTypeBin/binary,ThisTypeBin/binary>>).
+
+%% @hidden
+disconnect_impl(Listener, Object) ->
+ disconnect_impl(Listener, Object, #evh{}).
+%% @hidden
+disconnect_impl(#wx_ref{type=wxeEvtListener,ref=EvtList},
+ #wx_ref{type=_ThisT,ref=ThisRef},
+ #evh{id=Winid, lastId=LastId, et=EventType}) ->
+ EventTypeBin = list_to_binary([atom_to_list(EventType)|[0]]),
+ wxe_util:call(101, <<EvtList:32/?UI,
+ ThisRef:32/?UI,Winid:32/?UI,LastId:32/?UI,
+ (size(EventTypeBin)):32/?UI,
+ %% Note no alignment
+ EventTypeBin/binary>>).
+
+%% @hidden
+new_evt_listener() ->
+ wxe_util:call(98, <<>>).
+
+%% @hidden
+destroy_evt_listener(#wx_ref{type=wxeEvtListener,ref=EvtList}) ->
+ wxe_util:call(99, <<EvtList:32/?UI>>).
+
+%% @hidden
+get_callback(#evh{cb=Callback}) ->
+ Callback.
+
+%% @hidden
+replace_fun_with_id(Evh, Id) ->
+ Evh#evh{cb=Id}.
diff --git a/lib/wx/api_gen/wx_extra/wxListCtrl.c_src b/lib/wx/api_gen/wx_extra/wxListCtrl.c_src
new file mode 100644
index 0000000000..cd3074e481
--- /dev/null
+++ b/lib/wx/api_gen/wx_extra/wxListCtrl.c_src
@@ -0,0 +1,24 @@
+<<SortItems
+case ~s: { // wxListCtrl::SortItems taylormade
+ wxListCtrl *This = (wxListCtrl *) getPtr(bp,memenv); bp += 4;
+ int sortCallback=*(int *) bp; bp += 4;
+ if(!This) throw wxe_badarg(0);
+
+ callbackInfo* cb = new callbackInfo();
+ cb->port = Ecmd.port;
+ cb->callbackID = sortCallback;
+ bool Result = This->SortItems(wxEListCtrlCompare, (long)cb);
+ delete cb;
+
+ /* Destroy the callback, see wxEPrintout::clear_cb */
+ wxeReturn cbrt = wxeReturn(WXE_DRV_PORT, memenv->owner, false);
+ // NOTE: Remove this later when changing from funs to gen_server
+ cbrt.addAtom("wx_delete_cb");
+ cbrt.addInt(sortCallback);
+ cbrt.addTupleCount(2);
+ cbrt.send();
+
+ rt.addBool(Result);
+ break;
+}
+SortItems>>
diff --git a/lib/wx/api_gen/wx_extra/wxListCtrl.erl b/lib/wx/api_gen/wx_extra/wxListCtrl.erl
new file mode 100644
index 0000000000..e6470182cb
--- /dev/null
+++ b/lib/wx/api_gen/wx_extra/wxListCtrl.erl
@@ -0,0 +1,39 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+<<EXPORT:SortItems sortItems/2 SortItems:EXPORT>>
+
+<<SortItems
+%% @spec (This::wxListCtrl(), SortCallBack::function()) -> boolean()
+%% @doc Sort the items in the list control<br />
+%% <pre>SortCalBack(Item1,Item2) -> integer()</pre>
+%% <br /> SortCallBack receives the client data associated with two items
+%% to compare, and should return 0 if the items are equal, a negative
+%% value if the first item is less than the second one and a positive
+%% value if the first item is greater than the second one.
+%% <br /> NOTE: The callback may not call other processes.
+sortItems(#wx_ref{type=ThisT,ref=ThisRef}, SortCallBack)
+ when is_function(SortCallBack, 2) ->
+ ?CLASS(ThisT,wxListCtrl),
+ Sort = fun([Item1,Item2]) ->
+ Result = SortCallBack(Item1,Item2),
+ <<Result:32/?UI>>
+ end,
+ SortId = wxe_util:get_cbId(Sort),
+ wxe_util:call(~s, <<ThisRef:32/?UI,SortId:32/?UI>>).
+SortItems>>
diff --git a/lib/wx/api_gen/wx_extra/wxPrintout.c_src b/lib/wx/api_gen/wx_extra/wxPrintout.c_src
new file mode 100644
index 0000000000..c088a95e73
--- /dev/null
+++ b/lib/wx/api_gen/wx_extra/wxPrintout.c_src
@@ -0,0 +1,30 @@
+<<wxPrintout
+case ~s: { // wxPrintout::wxPrintout taylormade
+ int onPreparePrinting=0,onBeginPrinting=0,onEndPrinting=0,onBeginDocument=0,
+ onEndDocument=0,hasPage=0,getPageInfo=0;
+ int * titleLen = (int *) bp; bp += 4;
+ wxString title = wxString(bp, wxConvUTF8);
+ bp += *titleLen+((8-((4+ *titleLen) & 7)) & 7);
+ int onPrintPage=*(int *) bp; bp += 4;
+ while( * (int*) bp) {
+ switch (* (int*) bp) {
+ case 1: {bp += 4; onPreparePrinting = *(int *) bp; bp += 4;} break;
+ case 2: {bp += 4; onBeginPrinting = *(int *) bp; bp += 4;} break;
+ case 3: {bp += 4; onEndPrinting = *(int *) bp; bp += 4;} break;
+ case 4: {bp += 4; onBeginDocument = *(int *) bp; bp += 4;} break;
+ case 5: {bp += 4; onEndDocument = *(int *) bp; bp += 4;} break;
+ case 6: {bp += 4; hasPage = *(int *) bp; bp += 4;} break;
+ case 7: {bp += 4; getPageInfo = *(int *) bp; bp += 4;} break;
+ }
+ }
+ wxEPrintout *Result = new wxEPrintout(title,onPrintPage,
+ onPreparePrinting,
+ onBeginPrinting,onEndPrinting,
+ onBeginDocument,onEndDocument,
+ hasPage,getPageInfo, Ecmd.port);
+
+ rt.addRef(getRef((void *)Result,memenv), "wxPrintout");
+ break;
+}
+wxPrintout>>
+
diff --git a/lib/wx/api_gen/wx_extra/wxPrintout.erl b/lib/wx/api_gen/wx_extra/wxPrintout.erl
new file mode 100644
index 0000000000..be8f2e2fa5
--- /dev/null
+++ b/lib/wx/api_gen/wx_extra/wxPrintout.erl
@@ -0,0 +1,102 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+<<EXPORT:wxPrintout new/2,new/3 wxPrintout:EXPORT>>
+
+<<wxPrintout
+%% @spec (Title::string(), OnPrintPage::function()) -> wxPrintout:wxPrintout()
+%% @doc @equiv new(Title, OnPrintPage, [])
+new(Title, OnPrintPage) ->
+ new(Title, OnPrintPage, []).
+
+%% @spec (Title::string(), OnPrintPage::function(), [Option]) -> wxPrintout:wxPrintout()
+%% Option = {onPreparePrinting, OnPreparePrinting::function()} |
+%% {onBeginPrinting, OnBeginPrinting::function()} |
+%% {onEndPrinting, OnEndPrinting::function()} |
+%% {onBeginDocument, OnBeginDocument::function()} |
+%% {onEndDocument, OnEndDocument::function()} |
+%% {hasPage, HasPage::function()} |
+%% {getPageInfo, GetPageInfo::function()}
+%% @doc Creates a wxPrintout object with a callback fun and optionally other callback funs.<br />
+%% <pre>OnPrintPage(This,Page) -> boolean() </pre>
+%% <pre>OnPreparePrinting(This) -> term() </pre>
+%% <pre>OnBeginPrinting(This) -> term() </pre>
+%% <pre>OnEndPrinting(This) -> term() </pre>
+%% <pre>OnBeginDocument(This,StartPage,EndPage) -> boolean() </pre>
+%% <pre>OnEndDocument(This) -> term() </pre>
+%% <pre>HasPage(This,Page)} -> boolean() </pre>
+%% <pre>GetPageInfo(This) -> {MinPage:.integer(), MaxPage::integer(), PageFrom::integer(), PageTo::integer()} </pre>
+%% The <b>This</b> argument is the wxPrintout object reference to this object
+%% <br /> NOTE: The callbacks may not call other processes.
+new(Title, OnPrintPage, Opts) when is_list(Title), is_function(OnPrintPage), is_list(Opts) ->
+ OnPrint = fun([This,Page]) ->
+ Bool = OnPrintPage(This,Page),
+ <<(wxe_util:from_bool(Bool)):32/?UI>>
+ end,
+ OnPrintPageId = wxe_util:get_cbId(OnPrint),
+ MOpts = fun({onPreparePrinting, F},Acc) when is_function(F) ->
+ Fun = fun([This]) ->
+ F(This),
+ <<>>
+ end,
+ [<<1:32/?UI,(wxe_util:get_cbId(Fun)):32/?UI>>|Acc];
+ ({onBeginPrinting, F},Acc) when is_function(F) ->
+ Fun = fun([This]) ->
+ F(This),
+ <<>>
+ end,
+ [<<2:32/?UI,(wxe_util:get_cbId(Fun)):32/?UI>>|Acc];
+ ({onEndPrinting, F},Acc) when is_function(F) ->
+ Fun = fun([This]) ->
+ F(This),
+ <<>>
+ end,
+ [<<3:32/?UI,(wxe_util:get_cbId(Fun)):32/?UI>>|Acc];
+ ({onBeginDocument, F},Acc) when is_function(F) ->
+ Fun = fun([This,S,E]) ->
+ BegD = F(This,S,E),
+ <<(wxe_util:from_bool(BegD)):32/?UI>>
+ end,
+ [<<4:32/?UI,(wxe_util:get_cbId(Fun)):32/?UI>>|Acc];
+ ({onEndDocument, F},Acc) when is_function(F) ->
+ Fun = fun([This]) ->
+ F(This),
+ <<>>
+ end,
+ [<<5:32/?UI,(wxe_util:get_cbId(Fun)):32/?UI>>|Acc];
+ ({hasPage, F},Acc) when is_function(F) ->
+ Fun = fun([This,Page]) ->
+ HasP = F(This,Page),
+ <<(wxe_util:from_bool(HasP)):32/?UI>>
+ end,
+ [<<6:32/?UI,(wxe_util:get_cbId(Fun)):32/?UI>>|Acc];
+ ({getPageInfo, F},Acc) when is_function(F) ->
+ Fun = fun([This]) ->
+ {Min,Max,PF,PT} = F(This),
+ <<Min:32/?UI,Max:32/?UI,PF:32/?UI,PT:32/?UI>>
+ end,
+ [<<7:32/?UI,(wxe_util:get_cbId(Fun)):32/?UI>>|Acc]
+ end,
+ BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Opts)),
+ Title_UC = unicode:characters_to_binary([Title,0]),
+ wxe_util:call(~s, << (byte_size(Title_UC)):32/?UI,Title_UC/binary,
+ 0:(((8- ((4+byte_size(Title_UC)) band 16#7)) band 16#7))/unit:8,
+ OnPrintPageId:32/?UI,
+ BinOpt/binary>>).
+
+wxPrintout>>
diff --git a/lib/wx/api_gen/wx_extra/wxXmlResource.c_src b/lib/wx/api_gen/wx_extra/wxXmlResource.c_src
new file mode 100644
index 0000000000..152e83fe32
--- /dev/null
+++ b/lib/wx/api_gen/wx_extra/wxXmlResource.c_src
@@ -0,0 +1,3 @@
+<<xrcctrl
+// XRCTRL macro implemented in erlang funcid ~s
+xrcctrl>> \ No newline at end of file
diff --git a/lib/wx/api_gen/wx_extra/wxXmlResource.erl b/lib/wx/api_gen/wx_extra/wxXmlResource.erl
new file mode 100644
index 0000000000..cd2bea6a1d
--- /dev/null
+++ b/lib/wx/api_gen/wx_extra/wxXmlResource.erl
@@ -0,0 +1,43 @@
+
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+<<EXPORT:xrcctrl xrcctrl/3 xrcctrl:EXPORT>>
+
+<<xrcctrl
+%% @spec (Window::wxWindow:wxWindow(),Name::string(), Type::atom()) -> wx:wxObject()
+
+%% @doc Looks up a control with Name in a window created with XML
+%% resources. You can use it to set/get values from controls.
+%% The object is type casted to <b>Type</b>.
+%% Example: <br />
+%% Xrc = wxXmlResource:get(), <br />
+%% Dlg = wxDialog:new(), <br />
+%% true = wxXmlResource:loadDialog(Xrc, Dlg, Frame, "controls_dialog"), <br />
+%% LCtrl = xrcctrl(Dlg, "controls_listctrl", wxListCtrl), <br />
+%% wxListCtrl:insertColumn(LCtrl, 0, "Name", [{width, 200}]), <br />
+
+xrcctrl(Window = #wx_ref{}, Name, Type) when is_list(Name), is_atom(Type) ->
+ %% Func Id ~s
+ ID = wxXmlResource:getXRCID(Name),
+ Res = wxWindow:findWindow(Window,ID),
+ wx:typeCast(Res, Type).
+
+xrcctrl>>
+
+
diff --git a/lib/wx/api_gen/wx_extra/wxe_evth.h b/lib/wx/api_gen/wx_extra/wxe_evth.h
new file mode 100644
index 0000000000..9af603b9e2
--- /dev/null
+++ b/lib/wx/api_gen/wx_extra/wxe_evth.h
@@ -0,0 +1,25 @@
+
+// This add some extra functions, special code is in the compiler
+// this file is currently not used at all except to get the inherited
+// functions in the erlang modules.
+
+
+class wxeEvtHandler : public wxObject
+{
+ public:
+ // Dynamic association of a member function handler with the event handler,
+ // winid and event type
+ void Connect(int eventType,
+ int options = -1);
+
+ // Disconnect
+
+ // Convenience function: take just one id
+ void Disconnect(int eventType, int winid = -1);
+
+ // Even more convenient: without id (same as using id of wxID_ANY)
+ void Disconnect(int eventType);
+
+ void Disconnect();
+
+}
diff --git a/lib/wx/api_gen/wx_gen.erl b/lib/wx/api_gen/wx_gen.erl
new file mode 100644
index 0000000000..50dd2d6f51
--- /dev/null
+++ b/lib/wx/api_gen/wx_gen.erl
@@ -0,0 +1,1443 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%% Api wrapper generator
+
+-module(wx_gen).
+-export([code/0,xml/0]).
+
+-include("wx_gen.hrl").
+
+-include_lib("xmerl/include/xmerl.hrl").
+
+-import(lists, [foldl/3,foldr/3,reverse/1, keysearch/3, map/2, filter/2]).
+-import(proplists, [get_value/2,get_value/3]).
+
+-compile(export_all).
+
+code() -> safe(fun gen_code/0,true).
+xml() -> safe(fun gen_xml/0,true).
+
+devcode() -> erase(),safe(fun gen_code/0,false).
+
+safe(What, QuitOnErr) ->
+ try
+ What(),
+ io:format("Completed succesfully~n~n", []),
+ QuitOnErr andalso gen_util:halt(0)
+ catch Err:Reason ->
+ io:format("Error in ~p ~p~n", [get(current_class),get(current_func)]),
+ erlang:display({Err,Reason, erlang:get_stacktrace()}),
+ catch gen_util:close(),
+ QuitOnErr andalso gen_util:halt(1)
+ end.
+
+gen_code() ->
+ {ok, Defs0} = file:consult("wxapi.conf"),
+ %% {ok, Defs0} = file:consult("test.conf"),
+ erase(func_id),
+ put(class_id, 10), %% Start from 10 using the other as special
+ Defs1 = init_defs(Defs0),
+ Defs2 = parse_defs(Defs1, []),
+ parse_enums([File || {{include, File},_} <- get()]),
+ Defs = translate_enums(Defs2),
+ wx_gen_erl:gen(Defs),
+ wx_gen_cpp:gen(Defs),
+ ok.
+
+gen_xml() ->
+%% {ok, Defs} = file:consult("wxapi.conf"),
+
+%% Rel = reverse(tl(reverse(os:cmd("wx-config --release")))),
+%% Dir = " /usr/include/wx-" ++ Rel ++ "/wx/",
+%% Files0 = [Dir ++ File || {class, File, _, _, _} <- Defs],
+%% Files1 = [Dir ++ File || {doxygen, File} <- Defs],
+%% ok = file:write_file("wxapi.files", list_to_binary("INPUT = "++Files0++Files1)),
+ ok.
+
+-record(hs,{alias,skip,fs,fopt,ev,acc,info}).
+
+init_defs(List0) ->
+ List1 = to_lists(List0),
+ lists:map(fun mangle_info/1, List1).
+
+mangle_info(E={enum,Type0,SkipStr}) ->
+ Type = case is_atom(Type0) of true -> atom_to_list(Type0); false -> Type0 end,
+ put({enum, Type}, #enum{skip=SkipStr,as_atom=false}), %% as_atom=true}),
+ E;
+mangle_info(E={const_skip,List}) ->
+ put(const_skip, [atom_to_list(M) || M <- List]),
+ E;
+mangle_info(E={not_const,List}) ->
+ put(not_const, [atom_to_list(M) || M <- List]),
+ E;
+mangle_info(E={gvars,List}) ->
+ A2L = fun({N,{T,C}}) -> {atom_to_list(N), {T,atom_to_list(C)}};
+ ({N,C}) -> {atom_to_list(N), atom_to_list(C)}
+ end,
+ put(gvars, map(A2L,List)),
+ E;
+mangle_info({class,CN,P,O,FL}) ->
+ Alias = get_value(alias,O, []),
+ Skip = get_value(skip, O, []),
+ Event = get_value(event,O, false),
+ Acc = get_value(acc, O, []),
+ {Fs,Fopts} = foldr(fun(FWO={F,FO},{Fl,Fopt}) when is_list(FO) ->
+ {[F|Fl],[FWO|Fopt]};
+ (F,{Fl,Fopt}) ->
+ {[F|Fl], Fopt}
+ end, {[],[]}, FL),
+ {class,CN,P,#hs{alias=Alias,skip=Skip,fs=Fs,ev=Event,acc=Acc,info=O,
+ fopt=gb_trees:from_orddict(lists:sort(Fopts))}}.
+
+to_lists(Defs) ->
+ map(fun({class,C,P,O,Fs}) ->
+ {class,atom_to_list(C),atom_to_list(P),to_lists2(O),to_lists2(Fs)};
+ (Skip) -> Skip
+ end, Defs).
+
+to_lists2(List) ->
+ map(fun(Skip = {const_skip, _List}) -> Skip;
+ (Skip = {not_const, _List}) -> Skip;
+ (Skip = {skip, _List}) -> Skip;
+ (Skip = {event, _List}) -> Skip;
+ (Skip = {acc, _List}) -> Skip;
+ (Skip = {doc, _List}) -> Skip;
+ (Skip = taylormade) -> Skip;
+ (Skip = {ifdef,_}) -> Skip;
+ (Skip = {erl_func, _Name}) -> Skip;
+ ({alias, AList}) -> {alias, [{atom_to_list(A),atom_to_list(B)} || {A,B} <- AList]};
+ (Else) when is_atom(Else) -> atom_to_list(Else);
+ ({Else,W}) when is_atom(Else) -> {atom_to_list(Else),W};
+ ({{Else,W},O}) when is_atom(Else) -> {{atom_to_list(Else),W},O};
+ (Else) -> Else
+ end, List).
+
+parse_defs([{class,Name,Parent,Info}|Rest], Acc0) ->
+ {FileName, Type} =
+ case Parent of
+ "static" -> {Name ++ "_8h", static};
+ _ -> {"class" ++ Name, class}
+ end,
+ Tab = ets:new(defs, [bag]),
+ Defs0 = load_members(FileName, Name, gb_trees:empty(), Tab, Type, Info),
+
+ put(current_class, Name),
+ Class0 = #class{name=name(Name,Info),parent=Parent,
+ doc=get_value(doc,Info#hs.info,undefined),
+ file=FileName,options=Info#hs.info, id=next_id(class_id)},
+ ParseClass = fun(Member,{Class,Dfs}) ->
+ parse_class(Member,Tab,Dfs,Class,Info)
+ end,
+ {Class1,Defs} = foldl(ParseClass,{Class0,Defs0},Info#hs.fs),
+
+ Class2 = case Info#hs.ev of
+ false -> Class1;
+ Ev -> parse_attr(gb_trees:to_list(Defs), Class1, Ev, Info)
+ end,
+ Class = meta_info(Class2),
+ erase(current_class),
+ [erase(Del) || {Del = {loaded, _},_} <- get()],
+ %% ets:delete(Tab), keep it for debugging
+ parse_defs(Rest, [Class|Acc0]);
+parse_defs([_|Rest], Acc) ->
+ parse_defs(Rest, Acc);
+parse_defs([], Acc) -> reverse(Acc).
+
+meta_info(C=#class{name=CName,methods=Ms0}) ->
+ Ms = lists:append(Ms0),
+ HaveConstructor =
+ lists:keysearch(constructor, #method.method_type, Ms) =/= false,
+ case lists:keysearch(destructor, #method.method_type, Ms) of
+ false when HaveConstructor ->
+ Dest = #method{name="destroy",id=next_id(func_id),
+ method_type=destructor, params=[this(CName)]},
+ C#class{methods = [[Dest]|Ms0]};
+ false ->
+ C#class{abstract = true};
+ _ ->
+ C
+ end.
+
+parse_class(Member0,Tab,Defs0,Class = #class{name=CName},Opts) ->
+ {Member,NoArgs} = case Member0 of
+ {_, _} -> Member0;
+ _ -> {Member0,all}
+ end,
+ case ets:lookup(Tab, Member) of
+ [] ->
+ case Member of
+ [$~|_] -> ignore;
+ _ ->
+ ?warning("Skipped Member ~p in ~p (not found in ~p)~n",
+ [Member,CName,Tab])
+ end,
+ {Class,Defs0};
+ Ms ->
+ case select_member(Ms, Class, Defs0, Opts) of
+ {[],Defs} ->
+ ?warning("Skipped Member ~p in ~p (not found in base)~n",
+ [Member,CName]),
+ {Class,Defs};
+ {Selected,Defs} ->
+ Parsed = parse_members(Member,Selected,Defs,CName,Opts),
+ {add_method(Parsed,NoArgs,Class,Opts), Defs}
+ end
+ end.
+
+parse_members(MemberName, Members, Defs, Class, Opts) ->
+ ParseAll =
+ fun(Member,Acc) ->
+ try
+ case gb_trees:lookup(Member, Defs) of
+ {value,#xmlElement{name=memberdef,attributes=Attrs,
+ content=Data}} ->
+ MType = case keysearch(static,#xmlAttribute.name,Attrs) of
+ {value, #xmlAttribute{value = "yes"}} ->
+ static;
+ _ ->
+ member
+ end,
+ Virtual =
+ case keysearch(virt,#xmlAttribute.name,Attrs) of
+ {value, #xmlAttribute{value = "virtual"}} ->
+ true;
+ {value, #xmlAttribute{value = "non-virtual"}} ->
+ false;
+ _ ->
+ undefined
+ end,
+ [parse_member(Data,MType,Virtual,Opts)|Acc];
+ none ->
+ Acc;
+ _Hmm ->
+ Acc
+ end
+ catch throw:skip_member ->
+ Acc
+ end
+ end,
+ case foldl(ParseAll,[],Members) of
+ [] ->
+ ?warning("Skipped ~p No public def found in ~p ~n",
+ [MemberName,Class]),
+ io:format("~p ~p~n",[MemberName, Members]),
+ [];
+ Res ->
+ Res
+ end.
+
+
+parse_attr(Defs, Class, Ev, Info = #hs{acc=AccList0}) ->
+% io:format("Parsing Class ~p~n", [Class#class.name]),
+ {Attrs, AccList} = parse_attr1(Defs, AccList0, Info, []),
+ case AccList of
+ [] ->
+ Class#class{attributes=Attrs, event=Ev};
+ _ ->
+ Inherited = [{inherited, Inherit} || Inherit <- AccList],
+ Class#class{attributes=Attrs++Inherited, event=Ev}
+ end.
+
+parse_attr1([{{attr,_}, #xmlElement{content=C, attributes=Attrs}}|R], AttrList0, Opts, Res) ->
+ Parse = fun(Con, Ac) -> parse_param(Con, Opts, Ac) end,
+ Param0 = foldl(Parse, #param{}, drop_empty(C)),
+ case keysearch(prot, #xmlAttribute.name, Attrs) of
+ {value, #xmlAttribute{value = "public"}} ->
+ {Acc,AttrList} = attr_acc(Param0, AttrList0),
+ parse_attr1(R,AttrList,Opts,
+ [Param0#param{in=false,prot=public,acc=Acc}|Res]);
+ {value, #xmlAttribute{value = "protected"}} ->
+ {Acc,AttrList} = attr_acc(Param0, AttrList0),
+ parse_attr1(R,AttrList,Opts,
+ [Param0#param{in=false,prot=protected,acc=Acc}|Res]);
+ {value, #xmlAttribute{value = "private"}} ->
+ {Acc,AttrList} = attr_acc(Param0, AttrList0),
+ parse_attr1(R,AttrList,Opts,
+ [Param0#param{in=false,prot=private,acc=Acc}|Res])
+ end;
+parse_attr1([{_Id,_}|R],AttrList,Info, Res) ->
+ parse_attr1(R,AttrList,Info, Res);
+parse_attr1([],Left,_, Res) ->
+ {lists:reverse(Res), Left}.
+
+attr_acc(#param{name=N}, List) ->
+ Name = list_to_atom(N),
+ case get_value(Name, List, undefined) of
+ undefined -> {undefined, List};
+ Val -> {Val, lists:keydelete(Name,1,List)}
+ end.
+
+load_members(FileName, Class, Defs, Tab, Type,Opts) ->
+ File = filename:join(["wx_xml",FileName ++ ".xml"]),
+ put({loaded, FileName}, true),
+ case xmerl_scan:file(File, [{space, normalize}]) of
+ {error, enoent} ->
+ io:format("Skipped File not found ~p ~n", [File]),
+ Defs;
+ {Doc, _} ->
+ %% io:format("Scanning ~p ~n", [File]),
+ INCs = xmerl_xpath:string("./compounddef/includes/text()", Doc),
+ [put({include,reverse(tl(tl(reverse(Inc))))},ref) ||
+ #xmlText{value=Inc} <- INCs],
+ case Type of
+ class ->
+ AM = xmerl_xpath:string("./compounddef/listofallmembers/*", Doc),
+ foldl(fun(X,Y) -> extract_rmembers(X,Y,Opts) end, Tab, AM);
+ _ ->
+ ignore
+ end,
+ LMembers0 = xmerl_xpath:string("./compounddef/sectiondef/*", Doc),
+ foldl(fun(E,Acc) -> extract_lmembers(E,Class,Type,Tab,Opts,Acc) end, Defs, LMembers0)
+ end.
+
+extract_lmembers(Entry=#xmlElement{name=memberdef,attributes=Attrs,content=C},Class,Type,Tab,Opts,Acc) ->
+ case keysearch(kind, #xmlAttribute.name, Attrs) of
+ {value, #xmlAttribute{value = "function"}} ->
+ case keysearch(prot, #xmlAttribute.name, Attrs) of
+ {value, #xmlAttribute{value = "public"}} ->
+ {value, #xmlAttribute{value = Id}} =
+ keysearch(id, #xmlAttribute.name, Attrs),
+ case Type of
+ static ->
+ Get = fun(#xmlElement{name=name,content=[#xmlText{value=Name}]},NAcc) ->
+ [name(string:strip(Name),Opts)|NAcc];
+ (_D, NAcc) ->
+ NAcc
+ end,
+ case foldl(Get, [], C) of
+ [Name] ->
+ true = ets:insert(Tab,{Name,Id});
+ [] ->
+ ignore
+ end;
+ _ -> ignore
+ end,
+ case gb_trees:lookup(Id,Acc) of
+ {value, _Entry} -> gb_trees:update(Id,Entry,Acc);
+ none -> gb_trees:insert(Id,Entry,Acc)
+ end;
+ _ ->
+ Acc
+ end;
+ {value, #xmlAttribute{value = "variable"}} when Type =/= static ->
+%% {value, #xmlAttribute{value = Id}} =
+%% keysearch(id, #xmlAttribute.name, Attrs),
+ %% Hopefully wxW have some decent order!!
+ Id = next_id(attr_id),
+ gb_trees:insert({attr,Id},Entry,Acc);
+ {value, #xmlAttribute{value = "enum"}} when Type =/= static ->
+ extract_enum(Entry,Class, undefined),
+ Acc;
+ _ -> Acc
+
+ end.
+
+extract_rmembers(#xmlElement{name=member,attributes=Attrs,content=C},Tab, Opts) ->
+ {value,#xmlAttribute{value=Id}} = keysearch(refid, #xmlAttribute.name, Attrs),
+ Get = fun(#xmlElement{name=name,content=[#xmlText{value=Name}]},Acc) ->
+ [name(string:strip(Name),Opts)|Acc];
+ (_D, Acc) ->
+ Acc
+ end,
+ case foldl(Get, [], C) of
+ [Name] ->
+ true = ets:insert(Tab,{Name,Id});
+ [] ->
+ ignore
+ end,
+ Tab.
+
+select_member([{_,ID}], #class{name=Class,file=Orig}, Defs0, Opts) ->
+ [FileName, _8H|_] = string:tokens(ID, "_"),
+ case get({loaded, FileName}) =:= undefined
+ andalso get({loaded, FileName ++ "_" ++ _8H}) =:= undefined of
+ true ->
+ true = FileName =/= Orig, % Assert
+ Defs = load_members(FileName, Class, Defs0, skip, skip, Opts),
+ {[ID],Defs};
+ false ->
+ {[ID],Defs0}
+ end;
+select_member(Several, #class{name=Class,file=Orig}, Defs0, Opts) ->
+ MIds = [{string:tokens(MId, "_"),MId} || {_,MId} <- Several],
+ [StatFile |_ ] = string:tokens(Orig, "_"),
+ Check =
+ fun({[FN,_|_],ID}, {T,D}) when FN =:= Orig -> {[ID|T],D};
+ ({[FN,"8h"|_],ID}, {T,D}) when FN =:= StatFile -> {[ID|T],D};
+ ({[FN,_A|_],ID},{T,D}) ->
+ InBase = "class" ++ Class ++ "Base" =:= FN,
+ "wx" ++ ClassName = Class,
+ InGeneric = "classwxGeneric" ++ ClassName =:= FN,
+ IsHelper = case re:run(FN, "Helper$") of
+ {match,_} -> true;
+ _ -> false
+ end,
+ ImplBase = case re:run(FN, "Base$") of
+ {match,_} -> true;
+ _ ->
+ %% Hack for base-base class
+ FN =:= "classwxItemContainer"
+ end,
+ case InBase orelse InGeneric orelse IsHelper orelse ImplBase of
+ true ->
+ Defs = case get({loaded, FN}) of
+ undefined ->
+ true = FN =/= Orig, % Assert
+ load_members(FN,Class,D,skip,skip,Opts);
+ true -> D
+ end,
+ {[ID|T], Defs};
+ _C ->
+ %% io:format("DBG ~p ~p ~p ~p ~n",[FN,_A,_C,Class]),
+ {T,D}
+ end
+ end,
+ foldl(Check,{[],Defs0},MIds).
+
+parse_member(Data,MType,Virtual,Opts = #hs{fopt=Fopts}) ->
+ Parse = fun(Con,A) -> parse_member2(Con,Opts,A) end,
+ Method = #method{name=MName,params=PS0} =
+ foldl(Parse, #method{method_type=MType, virtual=Virtual}, Data),
+ %% Skip motif name's if it's last and optional
+ PS2 = case PS0 of %% Backward order..
+ [#param{name="name",def=Def,type=#type{name="wxString"}}|PS1]
+ when Def =/= none ->
+ PS1;
+ _ ->
+ PS0
+ end,
+ Sz = length(PS2),
+ PS = map(fun(P=#param{name=PName}) ->
+ patch_param(MName,{Sz,PName},P,Fopts)
+ end, PS2),
+ Alias = find_erl_alias_name(MName,PS,Fopts),
+ Method#method{params=PS, alias=Alias}.
+
+find_erl_alias_name(MName,Ps,Fopts) ->
+ case gb_trees:lookup(MName, Fopts) of
+ {value, FuncO} when is_list(FuncO) ->
+ Aliases = lists:foldl(fun({Var, {erl_func, AliasName}}, Acc) ->
+ [{Var,AliasName}|Acc];
+ ({erl_func, AliasName}, Acc) ->
+ [{all,AliasName}|Acc];
+ ({Var, List}, Acc) when is_list(List) ->
+ case get_value(erl_func,List) of
+ undefined ->
+ Acc;
+ AliasName ->
+ [{Var,AliasName}|Acc]
+ end;
+ (_,Acc) -> Acc
+ end, [], FuncO),
+ case Aliases of
+ [] ->
+ undefined;
+ _ ->
+ Find = fun({all,AliasName},Acc) -> [AliasName|Acc];
+ ({Var,AliasName},Acc) ->
+ case lists:keysearch(Var, #param.name, Ps) of
+ {value, _} -> [AliasName|Acc];
+ _ -> Acc
+ end
+ end,
+ case lists:foldl(Find, [], Aliases) of
+ [Alias] -> Alias;
+ [] -> undefined
+ end
+ end;
+ _ ->
+ undefined
+ end.
+
+parse_member2(#xmlElement{name=type, content=C},Opts,M0) ->
+ Type = parse_type(drop_empty(C), Opts),
+ M0#method{type=Type};
+parse_member2(#xmlElement{name=name, content=[#xmlText{value=C}]}, Opts, M0) ->
+ Func = string:strip(C),
+ put(current_func, Func),
+ M0#method{name=name(Func,Opts)};
+parse_member2(#xmlElement{name=param, content=C},Opts,M0) ->
+ Parse = fun(Con, Ac) -> parse_param(Con, Opts, Ac) end,
+ Param0 = foldl(Parse, #param{}, drop_empty(C)),
+ add_param(Param0, Opts, M0);
+parse_member2(_, _,M0) ->
+ M0.
+
+add_param(InParam, Opts, M0) ->
+ Param0 = case InParam#param.name of
+ undefined -> InParam#param{name="val"};
+ _ -> InParam
+ end,
+ Param = case Param0#param.type of
+ #type{base={comp,_,_Comp}} -> Param0;
+ #type{base={class,_Class}} -> Param0;
+ #type{base={ref,_}} -> Param0;
+ #type{base={term,_}} -> Param0;
+ #type{base=List} when is_list(List) -> Param0;
+ %% Assume the pointer args to base types are out parameters
+ #type{by_val=false,single=true, mod=Mod} ->
+ case lists:member(const, Mod) of
+ true -> Param0; % But not if they are const
+ false -> Param0#param{in=false}
+ end;
+ _ -> Param0
+ end,
+ add_param2(Param, Opts, M0).
+
+add_param2(P=#param{name=Name},#hs{fopt=FOpt},M0=#method{name=MName,params=Ps}) ->
+ case patch_param(MName, Name, P, FOpt) of
+ #param{where=nowhere} ->
+ M0#method{params=Ps};
+ Patched ->
+ %% case MName of %% DEBUG
+ %% "GetSelections" ->
+ %% io:format("~p~n",[Patched]);
+ %% _ -> ignore
+ %% end,
+ %%ASSERT
+ case Patched#param.type of
+ #type{base=undefined} -> ?error({unknown_type,Patched});
+ _ -> ok
+ end,
+ M0#method{params=[Patched|Ps]}
+ end.
+
+patch_param(Method, Name, P, Opt) ->
+ case gb_trees:lookup(Method,Opt) of
+ none -> P;
+ {value,NoArg} when is_integer(NoArg) -> P;
+ {value,Opts} when is_list(Opts) ->
+ case get_value(Name, Opts) of
+ undefined -> P;
+ List when is_list(List) ->
+ foldl(fun handle_param_opt/2,P,List);
+ Val ->
+ handle_param_opt(Val,P)
+ end
+ end.
+
+handle_param_opt(skip, P) -> P#param{where=c};
+handle_param_opt(nowhere, P) -> P#param{where=nowhere};
+handle_param_opt(skip_member, _P) -> throw(skip_member);
+handle_param_opt({skip_member, Type}, P) ->
+ case P of
+ #param{type=#type{name=Type}} ->
+ throw(skip_member);
+ #param{type=Type} ->
+ throw(skip_member);
+ _ ->
+ P
+ end;
+handle_param_opt({erl_func,_Name}, P) -> P; %% Handled elsewhere
+handle_param_opt(in, P) -> P#param{in=true};
+handle_param_opt(out, P) -> P#param{in=false};
+handle_param_opt(both, P) -> P#param{in=both};
+handle_param_opt({def,Def},P) -> P#param{def=Def};
+handle_param_opt({type,Type}, P=#param{type=T}) -> P#param{type=T#type{name=Type}};
+handle_param_opt({single,Opt}, P=#param{type=T}) -> P#param{type=T#type{single=Opt}};
+handle_param_opt({base,Opt}, P=#param{type=T}) -> P#param{type=T#type{base=Opt}};
+handle_param_opt({c_only,Opt},P) -> P#param{where=c, alt=Opt};
+handle_param_opt({ref, pointer}, P=#param{type=T}) ->
+ P#param{type=T#type{by_val=false,ref={pointer, 1}}};
+handle_param_opt({mod,Mods}, P=#param{type=T=#type{mod=Mods0}}) ->
+ P#param{type=T#type{mod=Mods++Mods0}}.
+
+get_opt(Opt, Method, Sz, Opts) ->
+ case gb_trees:lookup(Method,Opts) of
+ none -> undefined;
+ {value, List} when is_list(List) ->
+ case get_value({Sz,Opt}, List, undefined) of
+ undefined ->
+ get_value(Opt, List, undefined);
+ Res -> Res
+ end
+ end.
+
+parse_param(#xmlElement{name=type,content=C},Opts,T) ->
+ Type = parse_type(drop_empty(C),Opts),
+ T#param{type=Type};
+parse_param(#xmlElement{name=declname,content=[C]},_Opts,T) ->
+ #xmlText{value=Name} = C,
+ T#param{name=Name};
+parse_param(#xmlElement{name=defval,content=[#xmlText{value=Def}]},_Opts,T) ->
+ T#param{def=string:strip(Def)};
+parse_param(#xmlElement{name=defval,content=Other},_Opts,T) ->
+ %% For defaults = (modifer wxType *) NULL
+ Def0 = foldr(fun(#xmlText{value=V}, Acc) -> V ++ Acc;
+ (#xmlElement{content=[#xmlText{value=V}]},Acc) ->
+ V ++ Acc
+ end, [], Other),
+%% Def1 = lists:dropwhile(fun($)) -> false;(_) -> true end, Def0),
+%% Def = string:strip(Def1), %% Drop type cast !!
+%% io:format("Def ~s => ~s => ~s ~n", [Def0, Def1,string:strip(Def)]),
+ T#param{def=string:strip(Def0)};
+parse_param(#xmlElement{name=array,content=C},_Opts, T = #param{type=Type0}) ->
+ case Type0 of
+ _ when T#param.name=:="WXUNUSED" -> %% doxygen can't handle this macro
+ [#xmlText{value=RealVar}] = C,
+ [Name] = string:tokens(RealVar, "() "),
+ T#param{name=Name};
+%% #type{mod=[const]} ->
+%% T#param{type=Type0#type{single=array, by_val=true}};
+%% _ ->
+%% T#param{type=Type0#type{single=array, by_val=false}}
+ _ ->
+ T#param{type=Type0#type{single=array, by_val=true}}
+ end;
+parse_param(#xmlElement{name=name,content=[C]}, _, T) ->
+ %% Attributes have this
+ #xmlText{value=Name} = C,
+ T#param{name=Name};
+%% Skipped: Attributes have this
+parse_param(#xmlElement{name=definition}, _, T) -> T;
+parse_param(#xmlElement{name=argsstring}, _, T) -> T;
+parse_param(#xmlElement{name=briefdescription}, _, T) -> T;
+parse_param(#xmlElement{name=detaileddescription}, _, T) -> T;
+parse_param(#xmlElement{name=inbodydescription}, _, T) -> T;
+parse_param(#xmlElement{name=location}, _, T) -> T;
+parse_param(#xmlElement{name=referencedby}, _, T) -> T;
+parse_param(Other=#xmlElement{name=Name}, _, T) ->
+ io:format("Unhandled Param ~p ~p ~n in ~p~n", [Name,Other,T]),
+ ?error(unhandled_param).
+
+parse_type([], _Opts) -> void;
+parse_type(TypeInfo, Opts) ->
+ {Type,Info} = foldl(fun extract_type_info/2,{[],undefined},TypeInfo),
+ case Info of
+ {"member", Ref} ->
+ case string:tokens(Ref, "_") of
+ [FileName, "8h", _Id] ->
+ put({file_ref, FileName++"_8h"}, ref);
+ _ ->
+ ok
+ end;
+ _ -> ok
+ end,
+
+ Empty = #type{},
+ case parse_type2(reverse(Type),Info,Opts,#type{}) of
+ Empty -> ?error({strange_type, Type});
+ Assert -> Assert
+ end.
+
+extract_type_info(#xmlText{value=Value}, {Acc, Info}) ->
+ {reverse(foldl(fun extract_type_info2/2, [], string:tokens(Value, " "))) ++ Acc, Info};
+extract_type_info(#xmlElement{name=ref,attributes=As,content=[#xmlText{value=V}]},
+ {Acc,undefined}) ->
+ {value, #xmlAttribute{value = Refid}} = keysearch(refid,#xmlAttribute.name,As),
+ {value, #xmlAttribute{value = Kind}} = keysearch(kindref,#xmlAttribute.name,As),
+ {reverse(foldl(fun extract_type_info2/2, [], string:tokens(V, " "))) ++ Acc,
+ {Kind,Refid}};
+extract_type_info(What,Acc) ->
+ ?error({parse_error,What,Acc}).
+
+extract_type_info2("const",Acc) -> [const|Acc];
+extract_type_info2("*", [{by_ref,{pointer,N}}|Acc]) -> [{by_ref,{pointer,N+1}}|Acc];
+extract_type_info2("*", Acc) -> [{by_ref,{pointer,1}}|Acc];
+extract_type_info2("**", Acc) -> [{by_ref,{pointer,2}}|Acc];
+extract_type_info2("&", Acc) -> [{by_ref,reference}|Acc];
+extract_type_info2("WXDLLIMP" ++ _, Acc) -> Acc;
+extract_type_info2(Type, Acc) -> [Type|Acc].
+
+parse_type2(["void"], _Info, _Opts, _T) -> void;
+parse_type2(["virtual"|R], _Info, _Opts, _T) ->
+ [] = R,
+ %% Bug in old doxygen virtual destructors have type virtual
+ void;
+parse_type2(["wxe_cb"|R],Info,Opts, T) ->
+ parse_type2(R,Info,Opts,T#type{name=int,base=wxe_cb});
+parse_type2([const|R],Info,Opts,T=#type{mod=Mod}) ->
+ parse_type2(R,Info,Opts,T#type{mod=[const|Mod]});
+parse_type2(["unsigned"|R],Info,Opts,T=#type{mod=Mod}) ->
+ parse_type2(R,Info,Opts,T#type{mod=[unsigned|Mod]});
+parse_type2(["int"|R],Info,Opts, T) ->
+ parse_type2(R,Info,Opts,T#type{name=int,base=int});
+parse_type2(["char"|R],Info,Opts, T) ->
+ parse_type2(R,Info,Opts,T#type{name="char",base=int});
+parse_type2([N="size_t"|R], Info, Opts, T) ->
+ parse_type2(R,Info,Opts,T#type{name=N, base=int});
+parse_type2(["long"|R],Info, Opts, T) ->
+ parse_type2(R,Info,Opts,T#type{name=long,base=int});
+parse_type2(["float"|R],Info,Opts, T) ->
+ parse_type2(R,Info,Opts,T#type{name=float,base=float});
+parse_type2(["double"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=double,base=double});
+parse_type2([N="wxDouble"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base=double});
+parse_type2(["bool"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=bool,base=bool});
+parse_type2([N="wxWindowID"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base=int});
+parse_type2([N="wxTextCoord"|R],Info,Opts,T) -> %%long
+ parse_type2(R,Info,Opts,T#type{name=N,base=int});
+parse_type2([N="wxTextPos"|R],Info,Opts,T) -> %%long
+ parse_type2(R,Info,Opts,T#type{name=N,base=int});
+parse_type2([N="wxPrintQuality"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base=int});
+parse_type2([N="wxPaperSize"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base=int});
+parse_type2(["wxDataFormat"|_R],_Info,_Opts,T) ->
+ %% Hack Hack
+ T#type{name="wxDataFormatId",base=int};
+parse_type2([N="wxArrayInt"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base=int,single=array});
+parse_type2([N="wxArrayDouble"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base=double,single=array});
+parse_type2([N="wxTreeItemId"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base={ref,N}});
+parse_type2([N="wxArrayTreeItemIds"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base={ref,"wxTreeItemId"},single=array});
+parse_type2([N="wxTreeItemData"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name="wxETreeItemData",base={term,N}});
+parse_type2([N="wxClientData"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name="wxeErlTerm",base={term,N}});
+parse_type2([N="wxChar"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base=int});
+parse_type2(["wxUint32"|R],Info,Opts,T=#type{mod=Mod}) ->
+ parse_type2(R,Info,Opts,T#type{name=int,base=int,mod=[unsigned|Mod]});
+parse_type2([N="wxCoord"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base=int});
+parse_type2([N="wxPoint"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base={comp,N,[{int,"X"},{int,"Y"}]}});
+parse_type2([N="wxSize"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base={comp,N,[{int,"W"},{int,"H"}]}});
+parse_type2([N="wxGBPosition"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base={comp,N,[{int,"R"},{int,"C"}]}});
+parse_type2([N="wxGBSpan"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base={comp,N,[{int,"RS"},{int,"CS"}]}});
+parse_type2([N="wxGridCellCoords"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base={comp,N,[{int,"R"},{int,"C"}]}});
+parse_type2([N="wxGridCellCoordsArray"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base={comp,"wxGridCellCoords",
+ [{int,"R"},{int,"C"}]},
+ single=array});
+parse_type2([N="wxRect"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base={comp,N,[{int,"X"},{int,"Y"},
+ {int,"W"},{int,"H"}]}});
+parse_type2([N="wxColour"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,
+ base={comp,N,[{int,"R"},{int,"G"},{int,"B"},{int,"A"}]}});
+parse_type2([N="wxColor"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name="wxColour",
+ base={comp,N,[{int,"R"},{int,"G"},{int,"B"},{int,"A"}]}});
+
+parse_type2([N="wxPoint2DDouble"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,
+ base={comp,N,[{double,"X"},{double,"Y"}]}});
+parse_type2([N="wxRect2DDouble"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,
+ base={comp,N,[{double,"X"},{double,"Y"},
+ {double,"W"},{double,"H"}]}});
+
+parse_type2([N="wxDateTime"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,
+ base={comp,N,[{int,"D"},{int,"Mo"},{int,"Y"},
+ {int,"H"},{int,"Mi"},{int,"S"}]}
+ });
+
+parse_type2([N="wxMouseState"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N, base={comp,N,{record, wxMouseState}}});
+parse_type2([N="wxHtmlLinkInfo"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N, base={comp,N,{record, wxHtmlLinkInfo}}});
+parse_type2([N="wxString"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base=string});
+parse_type2([N="wxArtClient"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base=string});
+parse_type2(["wxArtID"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name="wxString",base=string});
+parse_type2([N="wxFileName"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base=string});
+parse_type2([N="wxArrayString"|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base=[int],single=array,by_val=true});
+parse_type2([{by_ref,Ref}|R],Info,Opts,T) ->
+ parse_type2(R,Info,Opts,T#type{ref=Ref,by_val=false});
+parse_type2([],_,_,T) -> T;
+
+parse_type2([N="wxImageList"|R],Info,Opts,T) -> %% ARRG breaks the following clause
+ parse_type2(R,Info,Opts,T#type{name=N,base={class,N}});
+parse_type2(L=[Name|R],I,Opts,T) ->
+ case reverse(Name) of
+ "tsiL" ++ RBase ->
+ parse_type2(R,I,Opts,
+ T#type{name=Name,base={class,reverse(RBase)},single=list});
+ _ ->
+ parse_type3(L,I,Opts,T)
+ end.
+
+parse_type3(["wxNotebookPage"|R],I,Opts,T) ->
+ Xml = case I of
+ {_, Ref} -> Ref;
+ undefined -> undefined
+ end,
+ parse_type2(R,I,Opts,T#type{name="wxWindow",base={class,"wxWindow"},xml=Xml});
+parse_type3([N|R],I={"member",Ref},Opts,T) ->
+ Type = name(N,Opts),
+ ErlClass = special_name(Type),
+ case string:tokens(Ref, "_") of
+ ["class" ++ _] -> ignore;
+ Other ->
+ Inc0 = lists:takewhile(fun("8h") -> false;(_) -> true end,Other),
+ Inc = gen_util:args(fun(A) -> A end, "_", Inc0),
+%% io:format("Inc ~s ~n", [Inc]),
+ put({include,Inc}, ref)
+ end,
+ case get_enum(Type) of
+ {_, undefined} ->
+ parse_type2(R,I,Opts,T#type{name=Type,base={class,ErlClass},xml=Ref});
+ {TypeWOClass,#enum{}} ->
+ parse_type2(R,I,Opts,T#type{name=Type,base={enum,TypeWOClass},xml=Ref})
+ end;
+parse_type3([N = "wx"++_|R],I,Opts,T) ->
+ Xml = case I of
+ {_, Ref} -> Ref;
+ undefined -> undefined
+ end,
+ Class = name(N,Opts),
+ ErlClass = special_name(Class),
+ parse_type2(R,I,Opts,T#type{name=Class,base={class,ErlClass},xml=Xml});
+parse_type3([N="WXWidget"|R], Info,Opts, T) ->
+ parse_type2(R,Info,Opts,T#type{name=N,base=long});
+%% Let type errors be seen later because we don't know if these unhandled types
+%% will be used.
+parse_type3([Name|R],Info,Opts, T) ->
+ New = T#type{name={unhandled,Name,Info,get(current_class),get(current_func)}},
+ parse_type2(R,Info,Opts, New).
+
+%%skipped(#method{method_type=constructor, type=void}, _Opts) -> true;
+skipped(#method{}, #hs{skip=[]}) -> false;
+skipped(#method{name=Name,params=P}, #hs{skip=Skip}) ->
+ AtomName = list_to_atom(Name),
+ Skipped = lists:member(AtomName, Skip) orelse
+ lists:member({AtomName,length(P)}, Skip),
+ %% io:format("~p ~p skipped ~p ~n", [AtomName, length(P),Skipped]),
+ Skipped.
+
+add_method(Ms0, NoArgs, Class, Opts) ->
+ Add = fun(M=#method{params=Ps0}, Acc) ->
+ case length(Ps0) of
+ NoArgs ->
+ [add_method2(M,Class,Opts)|Acc];
+ _ when NoArgs =:= all ->
+ [add_method2(M,Class,Opts)|Acc];
+ _ ->
+ Acc
+ end
+ end,
+ NewMs = lists:foldl(Add,[],Ms0),
+ Unique = filter_functions(reverse(NewMs), Opts),
+ erase(current_func),
+ foldl(fun(M,C=#class{methods=Ms}) when is_list(M) -> C#class{methods=[M|Ms]} end,
+ Class,reverse(Unique)).
+
+add_method2(M0=#method{name=Name,params=Ps0,type=T0},#class{name=CName,parent=Par},#hs{fopt=Opts}) ->
+ Type = case patch_param(Name, return, #param{type=T0}, Opts) of
+ #param{type = T0} ->
+ case patch_param(Name, {length(Ps0),return}, #param{type=T0}, Opts) of
+ #param{where=nowhere} -> void;
+ #param{type = Type0} -> Type0
+ end;
+ #param{where=nowhere} -> void;
+ #param{type = Type0} -> Type0
+ end,
+
+ {Req,Opt} = lists:partition(fun(#param{def=Def}) -> Def == none end,
+ M0#method.params),
+ Ps = reverse(Ps0),
+
+ IsStatic = case Par of
+ "static" -> static;
+ _ -> M0#method.method_type
+ end,
+ Where = case get_opt(where, Name, length(Ps), Opts) of
+ undefined -> both;
+ Other ->
+ Other
+ end,
+ M1 = M0#method{defined_in=CName,
+ min_arity = length(Req),
+ max_arity = length(Req) + if length(Opt) > 0 -> 1; true -> 0 end,
+ type = Type,
+ method_type = IsStatic,
+ where = Where,
+ id=next_id(func_id),
+ pre_hook = get_opt(pre_hook, Name, length(Ps), Opts),
+ post_hook = get_opt(post_hook, Name, length(Ps), Opts),
+ doc = get_opt(doc, Name, length(Ps), Opts)
+ },
+ M = case Name of
+ CName ->
+ M1#method{method_type=constructor,name=CName,
+ type=constructor(CName), params=Ps};
+ [$~|CName] ->
+ M1#method{method_type=destructor,name=Name,
+ params=[this(CName)|Ps]};
+ _ ->
+ case M1#method.method_type of
+ static -> M1#method{params=Ps};
+ member -> M1#method{params=[this(CName)|Ps]}
+ end
+ end,
+ M.
+
+this(Class) ->
+ #param{name="This",where=this,
+ type=#type{name=Class,base={class,Class},by_val=false,ref={pointer,1}}}.
+
+constructor(Class) ->
+ #type{name=Class,base={class,Class},by_val=false,ref=reference}.
+
+filter_functions(Parsed, Opts) ->
+ Left = foldl(fun(M0,Acc) ->
+ case skipped(M0, Opts) of
+ true -> Acc;
+ false ->
+ TF = extract_type_footprint(M0),
+ [TF|Acc]
+ end
+ end,[],Parsed),
+ Clean = remove_or_merge(lists:sort(Left),[],[]),
+ erl_skip_opt(reverse(Clean),[],[]).
+
+remove_or_merge([{A,{L,In,O1},M1}|Rest=[{A,{L,In,O2},M2}|_]],Acc1,Acc2)
+ when M1#method.method_type =:= M2#method.method_type ->
+ %% These are the same remove one of them.
+ case O1 =:= O2 of
+ true -> ok;
+ false ->
+ ?warning("Multiple out arguments of ~s:~s: ~p or ~p~n",
+ [get(current_class),M1#method.name, O1,O2])
+ end,
+ remove_or_merge(Rest,Acc1,Acc2);
+remove_or_merge([F={A,{Len,_,_},M1}|Rest],[{A,{Len,_,_},M2}|_]=Acc1,Acc2)
+ when M1#method.method_type =:= M2#method.method_type ->
+ NewAcc1 = maybe_merge(F,Acc1,[]),
+ remove_or_merge(Rest,NewAcc1,Acc2);
+remove_or_merge([F|Rest],[],Acc2) ->
+ remove_or_merge(Rest,[F],Acc2);
+remove_or_merge([F|Rest],Acc1,Acc2) ->
+ remove_or_merge(Rest,[F], [reverse(Acc1)|Acc2]);
+remove_or_merge([],[], Acc2) -> Acc2;
+remove_or_merge([],Acc1,Acc2) -> [reverse(Acc1)|Acc2].
+
+erl_skip_opt([Ms|R],[],Acc2) ->
+ {Orig, Skipped} = erl_skip_opt2(Ms,[],[],[]),
+ erl_skip_opt(R,Orig,[Skipped|Acc2]);
+erl_skip_opt(All=[Ms=[{_,{Len,_,_},_}|_]|R],Acc1=[{_,{N,_,_},_}|_], Acc2) ->
+ case Len =:= N+1 of
+ true ->
+ {Orig, Skipped} = erl_skip_opt2(Ms,[],[],Acc1),
+ erl_skip_opt(R,Orig,[Skipped++strip_ti(Acc1)|Acc2]);
+ false ->
+ erl_skip_opt(All, [], [strip_ti(Acc1)|Acc2])
+ end;
+erl_skip_opt([],Acc1,Acc2) -> [strip_ti(Acc1)|Acc2].
+
+erl_skip_opt2([F={_,{N,In,_},M=#method{where=Where}}|Ms],Acc1,Acc2,Check) ->
+ case N > 0 andalso lists:last(In) =:= opt_list of
+ true when Where =/= merged_c, Where =/= taylormade ->
+ case Check of
+ [] ->
+ erl_skip_opt2(Ms,[F|Acc1],[M#method{where=erl_no_opt}|Acc2],[]);
+ _ ->
+ Skipped = reverse(tl(reverse(In))),
+ T = fun({_,{_,Args,_},_}) -> true =:= types_differ(Skipped,Args) end,
+ case lists:all(T, Check) of
+ true ->
+ erl_skip_opt2(Ms,[F|Acc1],
+ [M#method{where=erl_no_opt}|Acc2],
+ Check);
+ false ->
+ erl_skip_opt2(Ms,[F|Acc1],Acc2,Check)
+ end
+ end;
+ _ ->
+ erl_skip_opt2(Ms,[F|Acc1],Acc2,[])
+ end;
+erl_skip_opt2([],Acc1,Acc2,_) -> {Acc1,Acc2}.
+
+strip_ti(Ms) ->
+ [M || {_,{_,_,_},M} <- Ms].
+
+maybe_merge(T1,[],Acc) -> reverse([T1|Acc]);
+maybe_merge(F={A1,T1={Len,In1,O1},M1},[C={A2,T2={Len,In2,O2},M2}|Rest],Acc) ->
+ case types_differ(In1,In2) of
+ true -> maybe_merge(F,Rest,[C|Acc]);
+ {class,C1,C2} when O1 =:= O2 ->
+ {Merged,M2Mod} = merge_class_params(M1,M2,C1,C2),
+ reverse([{A1,T1,Merged},{A2,T2,M2Mod}|Acc]) ++ Rest;
+ false ->
+ ?warning("Argument clash in ~s:~s:~n ~p~nor ~p~n",
+ [get(current_class),M1#method.name,{In1,O1},{In2,O2}]),
+ [F|Rest++Acc]
+ end.
+
+merge_class_params(M1=#method{params=P1,id=Mi1},M2=#method{params=P2,id=Mi2},C1,C2) ->
+ Merged = merge_class_params2({class,C1},P1,Mi1,{class,C2},P2,Mi2),
+ {M1#method{params=Merged}, M2#method{where=merged_c}}.
+
+merge_class_params2(B1,[P1|R1],M1,B2,[P1|R2],M2) ->
+ [P1|merge_class_params2(B1,R1,M1,B2,R2,M2)];
+merge_class_params2(B1,[P1=#param{type=T1=#type{base=B1}}|R1],M1,
+ B2,[#param{type=T2=#type{base=B2}}|R2],M2) ->
+ [P1#param{type={merged,M1,T1,R1,M2,T2,R2}}|merge_class_params2(B1,R1,M1,B2,R2,M2)];
+merge_class_params2(B1,[P1|R1],_M1,B2,[P2|R2],_M2) ->
+ io:format("Merged Failed ~p ~p~n", [B1,B2]),
+ io:format(" ~p ~p~n ~p~p~n", [P1,R1,P2,R2]),
+ ?error(merged_failed);
+merge_class_params2(_,[],_,_,[],_) ->
+ [].
+
+types_differ([C1|R1], [C2|R2]) when is_list(C1), is_list(C2) ->
+ types_differ(R1,R2); %% Different Classes
+types_differ([C|R1], [C|R2]) ->
+ types_differ(R1,R2);
+types_differ([{term,_}|R1], [_|R2]) ->
+ types_differ(R1,R2);
+types_differ([_|R1], [{term,_}|R2]) ->
+ types_differ(R1,R2);
+types_differ([{class,C1}|R1], [{class,C2}|R2]) ->
+ case types_differ(R1,R2) of
+ true ->
+ true;
+ false ->
+%% _ ->
+ {class,C1,C2};
+ {class,C1,C2} ->
+ {class,C1,C2};
+ {class, _,_} ->
+ false
+ end;
+types_differ([int|_], _) -> true;
+types_differ(_, [int|_]) -> true;
+types_differ([{class,_}|_], _) -> true;
+types_differ(_, [{class,_}|_]) -> true;
+types_differ([binary|_], _) -> true;
+types_differ(_, [binary|_]) -> true;
+
+types_differ([list|R1], [opt_list|R2]) ->
+ types_differ(R1,R2);
+types_differ([opt_list|R1], [list|R2]) ->
+ types_differ(R1,R2);
+types_differ([C1|R1], [C2|R2]) when is_tuple(C1), is_tuple(C2) ->
+ (size(C1) =/= size(C2)) orelse types_differ(R1,R2);
+types_differ([C1|_R1], [_C2|_R2]) when is_tuple(C1) ->
+ true;
+types_differ([_C1|_R1], [C2|_R2]) when is_tuple(C2)->
+ true;
+types_differ([_C1|R1], [_C2|R2]) -> %% More cases?
+ types_differ(R1,R2);
+types_differ([], []) ->
+ false.
+
+extract_type_footprint(M=#method{type=void,alias=A,params=Ps}) ->
+ {A,extract_type_footprint2(Ps, [], [], false), M};
+extract_type_footprint(M=#method{type=Type,alias=A,params=Ps}) ->
+ {A,extract_type_footprint2(Ps, [type_foot_print(Type)], [], false), M}.
+
+extract_type_footprint2([_P=#param{where=c, in=InArg}|R], Out, In, Opt)
+ when InArg =/= false ->
+ extract_type_footprint2(R, Out, In, Opt);
+extract_type_footprint2([_P=#param{def=Def, in=InArg}|R], Out, In, _Opt) when Def =/= none, InArg =/= false ->
+ extract_type_footprint2(R, Out, In, true);
+extract_type_footprint2([#param{in=false, type=Type}|Ps], Out, In, Opt) ->
+ extract_type_footprint2(Ps, [type_foot_print(Type)|Out], In, Opt);
+extract_type_footprint2([#param{in=true, type=Type}|Ps], Out, In, Opt) ->
+ extract_type_footprint2(Ps, Out, [type_foot_print(Type)|In], Opt);
+extract_type_footprint2([#param{in=both, type=Type}|Ps], Out, In, Opt) ->
+ TFP = type_foot_print(Type),
+ extract_type_footprint2(Ps, [TFP|Out], [TFP|In], Opt);
+
+extract_type_footprint2([], Out0, In, Opt) ->
+ Out = case Out0 of
+ [] -> void;
+ [One] -> One;
+ _ -> list_to_tuple(reverse(Out0))
+ end,
+ if Opt ->
+ {length(In)+1,reverse([opt_list|In]),Out};
+ true ->
+ {length(In), reverse(In),Out}
+ end.
+
+type_foot_print(#type{single=Single}) when Single =/= true -> list;
+type_foot_print(#type{base=string}) -> list;
+type_foot_print(#type{base=Base}) when is_list(Base) -> list;
+type_foot_print(#type{base=long}) -> int;
+type_foot_print(#type{base=binary}) -> binary;
+type_foot_print(#type{base={binary,_}}) -> binary;
+type_foot_print(#type{base=int}) -> int;
+type_foot_print(#type{base=bool}) -> bool;
+%%type_foot_print(#type{base=datetime}) -> datetime;
+type_foot_print(#type{base=float}) -> float;
+type_foot_print(#type{base=double}) -> float;
+type_foot_print(#type{base=C={class,_}}) -> C;
+type_foot_print(#type{base={enum,_}}) -> int;
+type_foot_print(#type{base={ref,_}}) -> ref;
+type_foot_print(#type{base={term,_}}) -> term;
+type_foot_print(#type{base=eventType}) -> atom;
+%% type_foot_print({Type,Str}) when is_list(Str) ->
+%% type_foot_print(Type);
+type_foot_print(#type{base={comp,_,R={record,_}}}) ->
+ R;
+type_foot_print(#type{base={comp,_,Types}}) ->
+ TFL = map(fun({T,N}) when is_list(N) ->
+ case T of
+ double -> float;
+ _ -> T
+ end
+ end, Types),
+ list_to_tuple(TFL).
+%type_foot_print(What) -> What.
+
+
+translate_enums(Defs) ->
+ Res = [translate_enums1(Def) || Def <- Defs],
+ Consts = [Enum || Enum = {{enum,_},_} <- get()],
+ translate_constants(Consts, get(not_const), get(const_skip)),
+ put(gvars, [{Gvar,Class,next_id(const)} || {Gvar,Class} <- lists:sort(get(gvars))]),
+ Res.
+
+translate_enums1(C=#class{name=Name, methods=Ms0, attributes=As0}) ->
+ Ms = [translate_enums2(M, Name) || M <- Ms0],
+ As = [translate_enums3(A, Name) || A <- As0],
+ C#class{methods=Ms, attributes=As}.
+
+translate_enums2(M=#method{params=Ps0, type=T0},Class) ->
+ Ps = [translate_enums3(P, Class) || P <- Ps0],
+ T = translate_enums_type(T0,Class),
+ M#method{params=Ps,type=T};
+translate_enums2(Ms,Class) when is_list(Ms) ->
+ [translate_enums2(M,Class) || M <- Ms].
+
+translate_enums3(P=#param{type=Type0},InClass) ->
+ Type = translate_enums_type(Type0,InClass),
+ P#param{type=Type};
+translate_enums3(InHer = {inherited, _},_InClass) ->
+ InHer.
+
+translate_enums_type(T=#type{base={class,C}},Class) ->
+ case get_enum(C,Class) of
+ {_, undefined} -> T;
+ {Enum, #enum{}} ->
+ %% io:format("ENUM Change class ~p to enum ~p~n", [C,Enum]),
+ T#type{base={enum, Enum}}
+ end;
+translate_enums_type(T,_Class) -> T.
+
+translate_constants(Enums, NotConsts0, Skip0) ->
+ NotConsts = gb_sets:from_list(NotConsts0),
+ Skip = gb_sets:from_list(Skip0),
+ Consts0 = create_consts(lists:sort(Enums), Skip, NotConsts, []),
+ put(consts, gb_trees:from_orddict(lists:ukeysort(1,[{N,C}|| C = #const{name=N} <- Consts0]))).
+
+create_consts([{{enum, Name},Enum = #enum{vals=Vals}}|R], Skip, NotConsts, Acc0) ->
+ CC = fun(What, Acc) ->
+ create_const(What, Skip, NotConsts, Acc)
+ end,
+ Acc = case Vals of
+ undefined ->
+ ?warning("Missing Enum ~p ~p ~n",[Name, Enum]),
+ Acc0;
+ [] -> %% ?warning("Ignored Empty Enum list ~p ~n",[_Name]),
+ Acc0;
+ _ ->
+ foldl(CC, Acc0, lists:sort(Vals))
+ end,
+ create_consts(R, Skip, NotConsts, Acc);
+create_consts([],_,_,Acc) -> Acc.
+
+create_const({Name, Val}, Skip, NotConsts, Acc) ->
+ case gb_sets:is_member(Name, Skip) of
+ true -> Acc;
+ false ->
+ case gb_sets:is_member(Name, NotConsts) of
+ true ->
+ [#const{name=Name,val=next_id(const),is_const=false}|Acc];
+ false ->
+ [#const{name=Name,val=Val,is_const=true}|Acc]
+%% false ->
+%% [#const{name=Name,val=Val}|Acc]
+ end
+ end.
+
+%%%%%%%%%%%%%
+next_id(What) ->
+ Next = case get(What) of
+ undefined -> 100;
+ N -> N+1
+ end,
+ put(What, Next),
+ Next.
+
+name([$~|Name], Opts) ->
+ [$~|name(Name,Opts)];
+name(Name0, #hs{alias=Alias}) ->
+ Name = case reverse(Name0) of
+ "esaBlooT" ++ _ -> %% Arrg uses base
+ Name0;
+ "esaBelbaTdirG" ++ _ -> %% Arrg uses base
+ Name0;
+ "esaBrekciP" ++ _ -> %% Arrg uses base
+ Name0;
+ "esaB" ++ Rest when hd(Name0) == $w ->
+ %% Arrg Some decl uses base class directly
+ reverse(Rest);
+ _F ->
+ Name0
+ end,
+ get_value(Name,Alias,Name).
+
+special_name("wxIconLocation") -> "wx";
+special_name("wxToolBarToolBase") -> "wx";
+special_name("wxObject") -> "wx";
+special_name("wxValidator") -> "wx"; % XXXXX
+%% special_name("wxTreeItemData") -> "wx"; % XXXXX
+%% special_name("wxTreeItemId") -> "wx";
+%% special_name("wxDataObject") -> "wx";
+special_name(Other) -> Other.
+
+drop_empty(List) ->
+ filter(fun(#xmlText { value = Text}) ->
+ string:strip(Text) =/= "";
+ (_)->
+ true
+ end, List).
+
+%%% Enums
+parse_enums(Files) ->
+ DontSearch = ["wxchar","filefn", "platform", "strconv", "filename",
+ "buffer", "string", "debug", "platinfo"],
+ %% Arg need to patch some specials, atleast for wx-2.6
+ ExtraSearch = ["gtk_2glcanvas", "generic_2splash"],
+ parse_enums(Files ++ ExtraSearch,gb_sets:from_list(DontSearch)).
+
+parse_enums([File|Files], Parsed) ->
+ case gb_sets:is_member(File,Parsed) of
+ false ->
+ FileName = filename:join(["wx_xml",File ++ "_8h.xml"]),
+%% io:format("Parse Enums in ~s ~n", [FileName]),
+ case xmerl_scan:file(FileName, [{space, normalize}]) of
+ {error, enoent} ->
+ parse_enums(Files, gb_sets:add(File,Parsed));
+ {Doc, _} ->
+ ES = "./compounddef/sectiondef/memberdef[@kind=\"enum\"]",
+ AM = xmerl_xpath:string(ES, Doc),
+ lists:foreach(fun(Def) -> extract_enum(Def, undefined, File) end, AM),
+
+ DS = "./compounddef/sectiondef/memberdef[@kind=\"define\"]",
+ Defs = xmerl_xpath:string(DS, Doc),
+ extract_defs(Defs,File),
+
+ INCs = xmerl_xpath:string("./compounddef/includes/text()", Doc),
+ New = [reverse(tl(tl(reverse(Inc)))) ||
+ #xmlText{value="wx/"++Inc} <- INCs],
+ %% io:format("Scan enums from ~p ~n", [File]),
+ parse_enums(New ++ Files, gb_sets:add(File,Parsed))
+ end;
+ true ->
+ parse_enums(Files,Parsed)
+ end;
+parse_enums([],_) -> ok.
+
+extract_enum(#xmlElement{name=memberdef,content=C}, Class, File) ->
+ {Name0,Vals0} = extract_enum2(C,undefined,0,[]),
+ {Vals,Name} =
+ if
+ hd(Name0) =:= $@, Class =:= undefined ->
+ {Vals0, Name0 ++ "_" ++ File};
+ Class =:= undefined->
+ {Vals0, Name0};
+ true ->
+ {[{Class++"::"++N,V} || {N,V} <- Vals0], {Class,Name0}}
+ end,
+ case get({enum, Name}) of
+ undefined ->
+%% io:format("1Enum name ~p~n", [Name]),
+%% [io:format(" ~s ~p~n", [D,V]) || {D,V} <- Vals],
+ put({enum, Name}, #enum{vals=Vals});
+ E = #enum{vals=undefined} ->
+%% io:format("2Enum name ~p~n", [Name]),
+%% [io:format(" ~s ~p~n", [D,V]) || {D,V} <- Vals],
+ put({enum, Name}, E#enum{vals=Vals});
+ #enum{vals=Vals} -> ok;
+%% io:format("Same? ~p ~n", [PVals == Vals])
+ #enum{vals=OldVals} ->
+ io:format("Enum ~p in ~p ~p ~p~n", [Name,Class,get(current_class),get(current_func)]),
+ io:format("New ~p~n", [Vals]),
+ io:format("Old ~p~n", [OldVals]),
+ erlang:error({enum_mismatch,Name,Vals,OldVals})
+ end,
+ ok.
+
+extract_enum2([#xmlElement{name=name,content=[#xmlText{value=Name}]}|R],_,Id,Acc0) ->
+ extract_enum2(R,Name,Id,Acc0);
+
+extract_enum2([#xmlElement{name=enumvalue,content=C}|R], N,Id,Acc0) ->
+ {Acc,NewId} = extract_enum3(C,Id,Acc0),
+ extract_enum2(R, N, NewId, Acc);
+extract_enum2([_|R], N, Id, Acc) ->
+ extract_enum2(R, N, Id, Acc);
+extract_enum2([], N, _Id, Acc) ->
+ {N, reverse(Acc)}.
+
+extract_enum3([#xmlElement{name=name,content=[#xmlText{value=Name}]}|R], Id, Acc) ->
+ case lists:keymember(Name, 1, Acc) of
+ true -> %% Doxygen double includes some defs.
+ {Acc,Id};
+ false ->
+ case Id of
+ This = {Str,Num} ->
+ extract_enum3(R, {Str, Num+1}, [{Name,This}|Acc]);
+ Val ->
+ extract_enum3(R, Val+1, [{Name,Val}|Acc])
+ end
+ end;
+
+extract_enum3([#xmlElement{name=initializer,
+ content=Cs=[#xmlText{}|_]}|_],_Id,[{Name,_}|Acc]) ->
+
+ String = lists:append([string:strip(C#xmlText.value) || C <- Cs]),
+
+ Val0 = gen_util:tokens(String,"<& "),
+
+ try
+ case Val0 of
+ ["0x" ++ Val1] ->
+ Val = http_util:hexlist_to_integer(Val1),
+ {[{Name, Val}|Acc], Val+1};
+ [Single] ->
+ Val = list_to_integer(Single),
+ {[{Name, Val}|Acc], Val+1};
+ ["1", "<<", Shift] ->
+ Val = 1 bsl list_to_integer(Shift),
+ {[{Name, Val}|Acc], Val+1};
+ [_Str, "+", _What] ->
+ Val = lists:append(Val0),
+ {[{Name, {Val, 0}}|Acc], {Val,1}};
+ _What ->
+ %% io:format("~p Name ~p ~p~n",[?LINE, Name, Val0]),
+ throw(below)
+ end
+ catch _:_ ->
+ {[{Name,{String,0}}|Acc], {String,1}}
+ end;
+extract_enum3([_|R], Id, Acc) ->
+ extract_enum3(R, Id, Acc);
+extract_enum3([], Id, Acc) ->
+ {Acc, Id}.
+
+extract_defs(Defs, File) ->
+ case foldl(fun extract_defs2/2, {[], gb_sets:empty()}, Defs) of
+ [] -> ok;
+ {Vals,_Skip} ->
+%% io:format("Defs file ~p~n", [File]),
+%% [io:format(" ~s ~p~n", [D,V]) || {D,V} <- Vals, not is_integer(V)]
+ put({enum, {define,"From " ++ File ++ ".h"}}, #enum{vals=Vals})
+ end.
+
+extract_defs2(#xmlElement{name=memberdef,content=C},{Acc,Skip}) ->
+ try
+ Res = {Name,_} = extract_def(C,undefined,Skip),
+ case gb_sets:is_member(Name,Skip) orelse lists:keymember(Name, 1, Acc) of
+ true -> {Acc,Skip};
+ false -> {[Res | Acc], Skip}
+ end
+ catch throw:SkipName -> {Acc, gb_sets:add(SkipName,Skip)}
+ end.
+
+extract_def([#xmlElement{name=name,content=[#xmlText{value=Name}]}|R], _N, Skip) ->
+ case Name of
+ "wxUSE" ++ _ ->
+ throw(Name);
+ "wx" ++ _ ->
+ extract_def(R, Name, Skip);
+ _ ->
+ throw(Name)
+ end;
+extract_def([#xmlElement{name=param}|_],Name,_) ->
+ throw(Name);
+extract_def([#xmlElement{name=initializer,content=[#xmlText{value=Val0}]}|_],N,Skip) ->
+ case Val0 of
+ "0x" ++ Val1 -> {N, http_util:hexlist_to_integer(Val1)};
+ _ ->
+ try
+ Val = list_to_integer(Val0),
+ {N, Val}
+ catch _:_ ->
+ case def_is_ok(Val0, Skip) of
+ false ->
+ throw(N);
+ NVal when is_integer(NVal) ->
+ {N, NVal};
+ NVal ->
+ {N, {NVal,0}}
+ end
+ end
+ end;
+extract_def([_|R],N,Skip) ->
+ extract_def(R,N,Skip);
+extract_def(_,N,_) ->
+ throw(N).
+
+def_is_ok(Name, Skip) ->
+ Toks = gen_util:tokens(Name,"()| \\:"),
+ R = def_is_ok(Toks, Skip, []),
+% io:format("~s -> ~p~n", [Name,R]),
+ R.
+
+def_is_ok([], _Skip, [")",Int, "("]) -> Int;
+def_is_ok([], _Skip, Acc) -> lists:append(reverse(Acc));
+def_is_ok([N="wx"++_|R],Skip,Acc) ->
+ case gb_sets:is_member(N,Skip) of
+ true -> false;
+ false -> def_is_ok(R,Skip,[N|Acc])
+ end;
+def_is_ok(["0x"++Val|R],Skip,Acc) ->
+ def_is_ok(R,Skip,["16#" ++ Val|Acc]);
+def_is_ok([N="|"|R], Skip, Acc) ->
+ def_is_ok(R,Skip,[N|Acc]);
+def_is_ok([N="("|R], Skip, Acc) ->
+ def_is_ok(R,Skip,[N|Acc]);
+def_is_ok([N=")"|R], Skip, Acc) ->
+ def_is_ok(R,Skip,[N|Acc]);
+def_is_ok([":"|_], _Skip, _Acc) ->
+ false;
+def_is_ok([N|R],Skip,Acc) ->
+ case catch list_to_integer(N) of
+ {'EXIT', _} -> false;
+ Int -> def_is_ok(R,Skip,[Int|Acc])
+ end.
+
+get_enum(Type0) when is_list(Type0) ->
+ case string:tokens(Type0,":") of
+ [Type] ->
+ {Type, get({enum,Type})};
+ [Class,Type] ->
+ get_enum(Type,Class)
+ end;
+get_enum({Class,Type}) ->
+ get_enum(Type,Class).
+
+get_enum(Type,Class) ->
+ case get({enum,Type}) of
+ undefined ->
+ {{Class,Type},get({enum, {Class,Type}})};
+ Res = #enum{} ->
+ {Type,Res}
+ end.
diff --git a/lib/wx/api_gen/wx_gen.hrl b/lib/wx/api_gen/wx_gen.hrl
new file mode 100644
index 0000000000..b34d399358
--- /dev/null
+++ b/lib/wx/api_gen/wx_gen.hrl
@@ -0,0 +1,88 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+-record(class,
+ {
+ name = undefined,
+ parent = undefined,
+ methods = [],
+ attributes = [],
+ event = false,
+ file = undefined,
+ options = undefined,
+ abstract = false,
+ id, % Unique integer identifer
+ doc
+ }).
+
+-record(method,
+ {
+ name = undefined, % real name
+ alias = undefined, % erlang func name
+ type = void, % method type
+ min_arity = undefined, % Required args
+ max_arity = undefined, % Optional args
+ defined_in = undefined, %
+ params = [], % arguments to the function
+ method_type = member, % kind of method, e.g constructor
+ where = both, % Erl or c or both
+ id = undefined, % Id (integer)
+ doc, % Extra documentation
+ virtual, % Is virtual?
+ pre_hook, % Pre hook before call in c-code
+ post_hook % Post hook after call in c-code
+ }
+ ).
+
+-record(param,
+ {
+ name = undefined,
+ type = undefined,
+ def = none,
+ in = true,
+ where = both, % both in c and erl or only in either
+ prot = public, % only used by attributes
+ alt = undefined,% c-only alternative usually a length indicator
+ acc % access function if protected and needed
+ }).
+
+-record(type,
+ {
+ name = undefined, % typename
+ base = undefined, % basename int, char, float ..
+ by_val = true, % or false = by_ref
+ single = true, % Single or array (list)
+ mod = [], % const ...
+ ref = undefined, % pointer or reference
+ xml = undefined % xml identity
+ }
+ ).
+
+-record(enum, {skip="", as_atom=false, vals}).
+-record(const,{name,val,enum,is_const}).
+
+-define(error(What),
+ erlang:error({{?MODULE,?LINE},{get(current_class),get(current_func)},What})).
+
+-define(warning(Str,Args),
+ io:format("~p:~p Warning:"++Str, [?MODULE,?LINE] ++ Args)).
+
+%-ifdef(TRACE_COMMENT).
+%-define(WTC(X), w("// ~p:~p ~p~n",[?MODULE, ?LINE, X])).
+%-else.
+-define(WTC(X), void).
+%-endif.
diff --git a/lib/wx/api_gen/wx_gen_cpp.erl b/lib/wx/api_gen/wx_gen_cpp.erl
new file mode 100644
index 0000000000..fd0bea04ae
--- /dev/null
+++ b/lib/wx/api_gen/wx_gen_cpp.erl
@@ -0,0 +1,1220 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%%-------------------------------------------------------------------
+%%% File : wx_gen_cpp.erl
+%%% Author : Dan Gudmundsson <[email protected]>
+%%% Description :
+%%%
+%%% Created : 19 Feb 2007 by Dan Gudmundsson <[email protected]>
+%%%-------------------------------------------------------------------
+-module(wx_gen_cpp).
+
+-include("wx_gen.hrl").
+
+-compile(export_all).
+
+-import(lists, [foldl/3,foldr/3,reverse/1, keysearch/3, map/2, filter/2]).
+-import(gen_util, [lowercase/1, lowercase_all/1, uppercase/1, uppercase_all/1,
+ open_write/1, close/0, c_copyright/0, w/2, w/1,
+ args/3, strip_name/2]).
+-import(wx_gen, [next_id/1]).
+
+gen(Defs) ->
+ open_write("../c_src/gen/wxe_derived_dest.h"),
+ c_copyright(),
+ w("~n/***** This file is generated do not edit ****/ ~n~n", []),
+ gen_derived_dest(Defs),
+ close(),
+
+ open_write("../c_src/gen/wxe_funcs.cpp"),
+ c_copyright(),
+ Res = gen_funcs(Defs),
+ close(),
+
+ open_write("../c_src/gen/wxe_macros.h"),
+ c_copyright(),
+ gen_macros(),
+ close(),
+
+ open_write("../c_src/gen/wxe_init.cpp"),
+ c_copyright(),
+ build_enums(),
+ close(),
+
+ build_events(),
+ Res.
+
+gen_derived_dest(Defs) ->
+ [gen_derived_dest_2(Class) || Class <- Defs],
+
+ UglySkipList = ["wxCaret", "wxCalendarDateAttr",
+ "wxFileDataObject", "wxTextDataObject", "wxBitmapDataObject"
+ ],
+
+ ?WTC("gen_derived_dest"),
+ w("void WxeApp::delete_object(void *ptr, wxeRefData *refd) {~n", []),
+ w(" switch(refd->type) {~n", []),
+ Case = fun(#class{name=Class, id=Id, abstract=IsAbs, parent=P}) when P /= "static" ->
+ UglyWorkaround = lists:member(Class, UglySkipList),
+ case hd(reverse(wx_gen_erl:parents(Class))) of
+ root when IsAbs == false, UglyWorkaround == false ->
+ w(" case ~p: delete (~s *) ptr; break;~n", [Id, Class]);
+ root when IsAbs == false, UglyWorkaround == true ->
+ w(" case ~p: /* delete (~s *) ptr;"
+ "These objects must be deleted by owner object */ "
+ "break;~n", [Id, Class]);
+ _ -> ok
+ end;
+ (_) -> ok
+ end,
+ [Case(Class) || Class <- Defs],
+ w(" default: delete (wxObject *) ptr;~n", []),
+ w("}}~n~n", []).
+
+gen_derived_dest_2(C=#class{name=Class}) ->
+ case is_derived(C) of
+ true ->
+ ?WTC("gen_derived_dest_2"),
+ w("class E~s : public ~s { ~n",[Class,Class]),
+ case Class of
+ "wxGLCanvas" -> %% Special for cleaning up gl context
+ w(" public: ~~E~s() {deleteActiveGL(this);"
+ "((WxeApp *)wxTheApp)->clearPtr(this);}; ~n", [Class]);
+ _ ->
+ w(" public: ~~E~s() {((WxeApp *)wxTheApp)->clearPtr(this);}; ~n", [Class])
+ end,
+ gen_constructors(C),
+ w("}; ~n~n", []);
+ false ->
+ ignore
+ end.
+
+gen_constructors(#class{name=Class, methods=Ms0}) ->
+ Ms = lists:append(Ms0),
+ Cs = lists:filter(fun(#method{method_type=MT}) -> MT =:= constructor end, Ms),
+ [gen_constructor(Class, Const) || Const <- Cs].
+
+gen_constructor(_Class, #method{where=merged_c}) -> ok;
+gen_constructor(_Class, #method{where=erl_no_opt}) -> ok;
+gen_constructor(Class, _M=#method{params=Ps}) ->
+ Gen1 = fun(#param{name=N, type=T}) -> gen_type(T,1) ++ N end,
+ Gen2 = fun(#param{name=N, type=T}) -> gen_type(T,2) ++ N end,
+ CallA = fun(#param{name=N}) -> N end,
+ HaveMergedType = fun(#param{type={merged,_,_,_,_,_,_}}) -> true; (_) -> false end,
+ ?WTC("gen_constructor"),
+ case lists:any(HaveMergedType, Ps) of
+ false ->
+ w(" E~s(~s) : ~s(~s) {};~n",
+ [Class,args(Gen1,",",Ps),Class,args(CallA,",",Ps)]);
+ true ->
+ w(" E~s(~s) : ~s(~s) {};~n",
+ [Class,args(Gen1,",",Ps),Class,args(CallA,",",Ps)]),
+ w(" E~s(~s) : ~s(~s) {};~n",
+ [Class,args(Gen2,",",Ps),Class,args(CallA,",",Ps)])
+ end.
+
+gen_type(#type{name=Type, ref={pointer,1}, mod=Mod},_) ->
+ mods(Mod) ++ to_string(Type) ++ " * ";
+gen_type(#type{name=Type, ref={pointer,2}, mod=Mod},_) ->
+ mods(Mod) ++ to_string(Type) ++ " ** ";
+gen_type(#type{name=Type, ref=reference, mod=Mod},_) ->
+ mods(Mod) ++ to_string(Type) ++ "& ";
+gen_type(#type{name=Type, ref=undefined, base=binary, mod=Mod},_) ->
+ mods(Mod) ++ to_string(Type) ++ " * ";
+gen_type(#type{name=Type, ref=undefined, single=array, mod=Mod},_) ->
+ mods(Mod) ++ to_string(Type) ++ " * ";
+gen_type(#type{name=Type, ref=undefined, mod=Mod},_) ->
+ mods(Mod) ++ to_string(Type) ++ " ";
+gen_type({merged, _, T1, _,_, _T2,_}, 1) ->
+ gen_type(T1,error);
+gen_type({merged, _, _T1,_, _, T2,_}, 2) ->
+ gen_type(T2,error).
+
+gen_funcs(Defs) ->
+ w("~n/***** This file is generated do not edit ****/ ~n~n"),
+ w("#include <wx/wx.h>~n"),
+ w("#include \"../wxe_impl.h\"~n"),
+ w("#include \"../wxe_events.h\"~n"),
+ w("#include \"../wxe_return.h\"~n"),
+ w("#include \"wxe_macros.h\"~n"),
+ w("#include \"wxe_derived_dest.h\"~n~n"),
+
+ w("void WxeApp::wxe_dispatch(wxeCommand& Ecmd)~n{~n"),
+ w(" char * bp = Ecmd.buffer; ~n"),
+ w(" wxeMemEnv *memenv = getMemEnv(Ecmd.port);~n"),
+%% w(" wxMBConvUTF32 UTFconverter;~n"),
+ w(" wxeReturn rt = wxeReturn(WXE_DRV_PORT, Ecmd.caller, true);~n"),
+ w(" try { ~n"),
+ w(" switch (Ecmd.op) ~n{~n"),
+%% w(" case WXE_CREATE_PORT: ~n", []),
+%% w(" { newMemEnv(Ecmd.port); } break; ~n", []),
+%% w(" case WXE_REMOVE_PORT: ~n", []),
+%% w(" { destroyMemEnv(Ecmd.port); } break; ~n", []),
+ w(" case DESTROY_OBJECT: { ~n"),
+ w(" wxObject *This = (wxObject *) getPtr(bp,memenv); "),
+ w(" if(This) {"),
+ w(" ((WxeApp *) wxTheApp)->clearPtr((void *) This);~n"),
+ w(" delete This; }~n } break; ~n"),
+ w(" case WXE_REGISTER_OBJECT: {~n"
+ " registerPid(bp, Ecmd.caller, memenv);~n"
+ " rt.addAtom(\"ok\");~n"
+ " break;~n"
+ " }~n"),
+
+ Res = [gen_class(Class) || Class <- Defs],
+
+ w(" default: {~n"),
+ w(" wxeReturn error = wxeReturn(WXE_DRV_PORT, Ecmd.caller, false);"),
+ w(" error.addAtom(\"_wxe_error_\");~n"),
+ w(" error.addInt((int) Ecmd.op);~n"),
+ w(" error.addAtom(\"not_supported\");~n"),
+ w(" error.addTupleCount(3);~n"),
+ w(" error.send();~n"),
+ w(" return ;~n"),
+ w(" }~n"),
+ w("} // switch~n"),
+ w(" rt.send();~n"),
+ w("} catch (wxe_badarg badarg) { // try ~n"),
+ w(" wxeReturn error = wxeReturn(WXE_DRV_PORT, Ecmd.caller, false);"),
+ w(" error.addAtom(\"_wxe_error_\");~n"),
+ w(" error.addInt((int) Ecmd.op);~n"),
+ w(" error.addAtom(\"badarg\");~n"),
+ w(" error.addInt((int) badarg.ref);~n"),
+ w(" error.addTupleCount(2);~n"),
+ w(" error.addTupleCount(3);~n"),
+ w(" error.send();~n"),
+ w("}} /* The End */ ~n"),
+ Res.
+
+gen_class(C=#class{name=Name,methods=Ms,options=Opts}) ->
+ put(current_class, Name),
+ NewMs =
+ case lists:member(taylormade, Opts) of
+ true ->
+ {ok, Bin} = file:read_file(filename:join([wx_extra,Name++".c_src"])),
+ ?WTC("gen_class"),
+ w("~s~n", [binary_to_list(Bin)]),
+ Ms;
+ false ->
+ case lists:keysearch(ifdef,1,Opts) of
+ {value, {ifdef, What}} ->
+ w("#if ~p~n",[What]),
+ Methods = lists:flatten(Ms),
+ MsR = [gen_method(Name,M) ||
+ M <- lists:keysort(#method.id, Methods)],
+ w("#endif // ~p~n",[What]),
+ MsR;
+ false ->
+ Methods = lists:flatten(Ms),
+ [gen_method(Name,M) ||
+ M <- lists:keysort(#method.id, Methods)]
+ end
+ end,
+ erase(current_class),
+ C#class{methods=NewMs}.
+
+gen_method(_CName, M=#method{where=erl_no_opt}) -> M;
+gen_method(CName, M=#method{where=taylormade, name=Name, id=Id}) ->
+ {ok, Bin} = file:read_file(filename:join([wx_extra, CName ++".c_src"])),
+ Str0 = binary_to_list(Bin),
+ %% io:format("C++ Class ~p ~p ~n", [CName, Name]),
+
+ {match, [Str1]} = re:run(Str0, "<<"++Name++"(.*)"++Name++">>",
+ [dotall, {capture, all_but_first, list}]),
+ ?WTC("gen_method"),
+ w(Str1, [wx_gen_erl:get_unique_name(Id)]),
+ M;
+gen_method(CName, M=#method{name=N,params=[Ps],method_type=destructor,id=MethodId}) ->
+ case hd(reverse(wx_gen_erl:parents(CName))) of
+ root ->
+ ?WTC("gen_method"),
+ w("case ~s: { // ~s::~s ~n", [wx_gen_erl:get_unique_name(MethodId),CName,N]),
+ decode_arguments([Ps]),
+ w(" if(This) {", []),
+ w(" ((WxeApp *) wxTheApp)->clearPtr((void *) This);~n", []),
+ w(" delete This;}~n", []),
+ free_args(),
+ w(" break; ~n}~n", []);
+ object -> %% Use default
+ ignore
+ end,
+ M;
+gen_method(CName, M=#method{name=N,params=Ps0,type=T,method_type=MT,id=MethodId}) ->
+ put(current_func, N),
+ put(bin_count,-1),
+ ?WTC("gen_method"),
+ w("case ~s: { // ~s::~s ~n", [wx_gen_erl:get_unique_name(MethodId),CName,N]),
+ Ps1 = declare_variables(void, Ps0),
+ {Ps2,Align} = decode_arguments(Ps1),
+ Opts = [Opt || Opt = #param{def=Def,in=In,where=Where} <- Ps2,
+ Def =/= none, In =/= false, Where =/= c],
+ decode_options(Opts, Align),
+ case M#method.pre_hook of
+ undefined -> skip;
+ Pre -> w(" ~s;~n", [Pre])
+ end,
+ Ps3 = call_wx(N,{MT,CName},T,Ps2),
+ case M#method.post_hook of
+ undefined -> skip;
+ Post -> w(" ~s;~n", [Post])
+ end,
+ free_args(),
+ build_return_vals(T,Ps3),
+ w(" break; ~n}~n", []),
+ erase(current_func),
+ M.
+
+declare_variables(void,Ps) ->
+ [declare_var(P) || P <- Ps];
+declare_variables(T, Ps) ->
+ declare_type("result", out, ignore, T),
+ [declare_var(P) || P <- Ps].
+
+declare_var(P = #param{where=erl}) -> P;
+declare_var(P = #param{where=this}) -> P;
+declare_var(P = #param{name=Name,def=Def,type=Type,in=true}) when Def =/= none ->
+ declare_type(Name, true, Def, Type),
+ P;
+declare_var(P = #param{in=In}) when In =/= false -> P;
+declare_var(P = #param{name=Name,in=In,def=Def,type=Type}) ->
+ declare_type(Name, In, Def, Type),
+ P.
+
+declare_type(N,false,_,#type{name="wxArrayInt"}) ->
+ w(" wxArrayInt ~s;~n", [N]);
+declare_type(N,false,_,#type{name="wxArrayString"}) ->
+ w(" wxArrayString ~s;~n", [N]);
+declare_type(N,false,_,#type{base=Base,single=true,name=Type,by_val=false,mod=Mod})
+ when Base =:= int; Base =:= long; Base =:= float; Base =:= double ->
+ w(" ~s~s ~s;~n", [mods(Mod),Type,N]);
+declare_type(N,false,_,#type{base={enum,_},single=true,name=Type,by_val=false,mod=Mod}) ->
+ w(" ~s~s ~s;~n", [mods(Mod),Type,N]);
+declare_type(N,false,_,#type{name="wxArrayTreeItemIds",ref=reference}) ->
+ w(" wxArrayTreeItemIds ~s;~n", [N]);
+declare_type(N,false,_,#type{name="wxDateTime"}) ->
+ w(" wxDateTime ~s;~n", [N]);
+declare_type(N,true,Def,#type{base=Base,single=true,name=Type,by_val=true})
+ when Base =:= int; Base =:= long; Base =:= float; Base =:= double; Base =:= bool ->
+ w(" ~s ~s=~s;~n", [Type,N,Def]);
+declare_type(N,true,Def,#type{base={comp,_,_},single=true,name=Type,mod=Mod,ref={pointer,1}}) ->
+ w(" ~s~s *~s=~s; ~s ~s;~n", [mods(Mod),Type,N,Def,Type,N++"Tmp"]);
+declare_type(N,true,Def,#type{base={comp,_,_},single=true,name=Type,ref=reference}) ->
+ w(" ~s ~s= ~s;~n", [Type,N,Def]);
+declare_type(N,true,Def,#type{base={enum,Type},single=true}) ->
+ w(" ~s ~s=~s;~n", [enum_type(Type),N,Def]);
+declare_type(N,true,Def,#type{base={class,_},single=true,name=Type,ref={pointer,1},mod=Mod}) ->
+ w(" ~s~s * ~s=~s;~n", [mods(Mod),Type,N,Def]);
+declare_type(N,true,Def,#type{base={class,_},single=true,name=Type,ref=reference,mod=Mod}) ->
+ w(" ~s~s * ~s= &~s;~n", [mods(Mod),Type,N,Def]);
+declare_type(N,true,Def,#type{base=Base,single=true,name=Type,by_val=false,ref={pointer,1}})
+ when Base =:= int; Base =:= long; Base =:= float; Base =:= double; Base =:= bool ->
+ w(" ~s *~s=~s;~n", [Type,N,Def]);
+declare_type(N,true,Def,#type{single=true,name="wxArtClient"}) ->
+ w(" wxArtClient ~s= ~s;~n", [N,Def]);
+declare_type(N,true,Def,#type{single=true,base=string}) ->
+ w(" wxString ~s= ~s;~n", [N,Def]);
+%% declare_type(N,true,_Def,#type{name="wxString"}) ->
+%% w(" wxString ~s= wxEmptyString;~n", [N]);
+declare_type(N,true,Def,#type{base=binary, name=char}) ->
+ w(" char ~sD[] = {~s}, * ~s = ~sD;~n", [N,Def,N,N]);
+declare_type(_N,true,_Def,void) ->
+ skip;
+declare_type(N,true,Def,#type{name=Type, ref={pointer,2}}) ->
+ %% xxxx
+ w(" ~s ** ~s = ~s;~n", [Type,N,Def]);
+declare_type(N,true,Def,#type{name=Type, single=array, ref={pointer,1}}) ->
+ w(" int * ~sLen = 0;~n", [N]),
+ w(" ~s * ~s = ~s;~n", [Type,N,Def]);
+declare_type(N,true,"",#type{name="wxArrayString", single=array, ref=reference}) ->
+ w(" wxArrayString ~s;~n", [N]);
+declare_type(N,true,Def,#type{name=Type, base={term,_}}) ->
+ w(" ~s * ~s= ~s;~n", [Type,N,Def]);
+declare_type(N,In,Def,T) ->
+ ?error({unhandled_type, {N,In,Def,T}}).
+
+decode_options([], _Align) -> ok;
+decode_options(Opts, Align) ->
+ align(Align, 64),
+ w(" while( * (int*) bp) { switch (* (int*) bp) { ~n", []),
+ foldl(fun decode_opt/2, 1, Opts),
+ w(" }}; ~n", []).
+
+decode_opt(#param{name=Name,type=Type}, N) ->
+ w(" case ~p: {bp += 4;~n", [N]),
+ Align = decode_arg(Name,Type,opt,1),
+ align(Align, 64),
+ w(" } break;~n", []),
+ N+1.
+
+decode_arguments(Ps0) ->
+ lists:mapfoldl(fun decode_arg/2,0,Ps0).
+
+store_free(N) ->
+ case get(free_args) of
+ undefined -> put(free_args, [N]);
+ List -> put(free_args, [N|List])
+ end.
+
+free_args() ->
+ case get(free_args) of
+ undefined -> ignore;
+ List ->
+ erase(free_args),
+ [w(" driver_free(~s);~n", [Arg]) || Arg <- List]
+ end.
+
+decode_arg(P = #param{where=erl},A) -> {P,A};
+decode_arg(P = #param{where=c},A) -> {P,A};
+decode_arg(P = #param{in=false},A) -> {P,A};
+decode_arg(P = #param{def=Def},A) when Def =/= none -> {P,A};
+decode_arg(P = #param{name=Name,type=Type},A0) ->
+ A = decode_arg(Name, Type, arg, A0),
+ {P, A}.
+
+wa(Decl,DA,Get,GetA,arg) ->
+ w(Decl,DA),
+ w(Get,GetA);
+wa(_Decl,_DA,Get,GetA,opt) ->
+ w(Get,GetA).
+
+decode_arg(N,#type{name=Class,base={class,_},single=true},Arg,A0) ->
+ A = align(A0,32),
+ wa(" ~s *",[Class],"~s = (~s *) getPtr(bp,memenv); bp += 4;~n",[N,Class],Arg),
+ A;
+decode_arg(N,{merged,_,#type{name=Class,base={class,_},single=true},_,_,_,_},arg,A0) ->
+ A = align(A0,32),
+ w(" ~s * ~s = (~s *) getPtr(bp,memenv); bp += 4;~n", [Class,N,Class]),
+ A;
+decode_arg(N,#type{base=long,single=true,name=Type},arg,A0) ->
+ A = align(A0,64),
+ w(" long * ~s = (~s *) bp; bp += 8;~n", [N,Type]),
+ A;
+decode_arg(N,#type{base=int,single=true,mod=Mod0,name=Type,ref=Ref},Arg,A0) ->
+ Mod = mods(Mod0),
+ case Arg of
+ arg -> w(" ~s~s * ~s = (~s~s *) bp; bp += 4;~n", [Mod,int,N,Mod,int]);
+ opt when Ref =:= {pointer,1} ->
+ w(" ~s = (~s *) bp; bp += 4;~n", [N,int]);
+ opt ->
+ w(" ~s = (~s)*(~s~s *) bp; bp += 4;~n", [N,Type,Mod,int])
+ end,
+ align(A0,32);
+decode_arg(N,#type{base=float,single=true,name=Type},arg,A0) ->
+ w(" ~s * ~s = (~s *) bp; bp += 4;~n", [Type,N,Type]),
+ align(A0,32);
+decode_arg(N,#type{base=double,single=true,name=Type},Arg,A0) ->
+ A = align(A0,64),
+ case Arg of
+ arg -> w(" ~s * ~s = (~s *) bp; bp += 8;~n", [Type,N,Type]);
+ opt -> w(" ~s = * (~s *) bp; bp += 8;~n", [N,Type])
+ end,
+ A;
+decode_arg(N,#type{base=bool,single=true,name=Type},Arg,A0) ->
+ case Arg of
+ arg -> w(" bool * ~s = (~s *) bp; bp += 4;~n", [N,Type]);
+ opt -> w(" ~s = *(~s *) bp; bp += 4;~n", [N,Type])
+ end,
+ align(A0,32);
+decode_arg(N,#type{base={enum,Type},single=true},Arg,A0) ->
+ wa(" ~s ", [enum_type(Type)], "~s = *(~s *) bp; bp += 4;;~n",[N, enum_type(Type)], Arg),
+ align(A0,32);
+decode_arg(N,#type{base={comp,"wxDateTime",List},single=true,name=Type,ref=Ref},Arg,A0) ->
+ Decl = fun({int,Spec}) ->
+ w(" int * ~s~s = (int *) bp; bp += 4;~n", [N,Spec])
+ end,
+ align(A0,32),
+ lists:foreach(Decl,List),
+ Name = fun({_,"Mo"}) -> "(wxDateTime::Month) *"++N++"Mo";
+ ({_,"Y"}) -> "*"++N++"Y";
+ ({_,Spec}) -> "(wxDateTime::wxDateTime_t) *"++N++Spec
+ end,
+ case Arg of
+ arg -> w(" ~s ~s = ~s(~s);~n", [Type,N,Type,args(Name, ",", List)]);
+ opt when Ref =:= {pointer,1} ->
+ w(" ~sTmp = ~s(~s); ~s = & ~sTmp;~n",
+ [N,Type,args(Name, ",", List), N,N]);
+ opt ->
+ w(" ~s = ~s(~s);~n", [N,Type,args(Name, ",", List)])
+ end,
+ (A0+length(List)) rem 2;
+decode_arg(N,#type{base={comp,_,List},single=true,name=Type,ref=Ref},Arg,A0) ->
+ Decl = fun({int,Spec}) ->
+ w(" int * ~s~s = (int *) bp; bp += 4;~n", [N,Spec]);
+ ({double, Spec}) ->
+ w(" wxDouble * ~s~s = (wxDouble *) bp; bp += 8;~n", [N,Spec])
+ end,
+ case hd(List) of
+ {int, _} -> align(A0,32);
+ {double, _} -> align(A0,64)
+ end,
+ lists:foreach(Decl,List),
+ Name = fun({_,Spec}) -> "*"++N++Spec end,
+ case Arg of
+ arg -> w(" ~s ~s = ~s(~s);~n", [Type,N,Type,args(Name, ",", List)]);
+ opt when Ref =:= {pointer,1} ->
+ w(" ~sTmp = ~s(~s); ~s = & ~sTmp;~n",
+ [N,Type,args(Name, ",", List), N,N]);
+ opt ->
+ w(" ~s = ~s(~s);~n", [N,Type,args(Name, ",", List)])
+ end,
+ case hd(List) of
+ {int, _} -> (A0+length(List)) rem 2;
+ {double, _} -> 0
+ end;
+
+decode_arg(N,#type{name=Class,base={ref,"wxTreeItemId"},single=true},Arg,A0) ->
+ A = align(A0,32),
+ wa(" ~s ",[Class],"~s = wxTreeItemId(getPtr(bp,memenv)); bp += 4;~n",[N],Arg),
+ A;
+decode_arg(N,#type{name="wxChar", single=S},Arg,A0)
+ when S =/= true ->
+ w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
+ wa(" wxString", []," ~s = wxString(bp, wxConvUTF8);~n", [N],Arg),
+ w(" bp += *~sLen+((8-((~p+ *~sLen) & 7)) & 7);~n", [N,4*((A0+1) rem 2),N]),
+ 0;
+decode_arg(N,#type{base=string, name="wxFileName"},Arg,A0) ->
+ w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
+ wa(" wxString", []," ~sStr = wxString(bp, wxConvUTF8);~n", [N],Arg),
+ w(" bp += *~sLen+((8-((~p+ *~sLen) & 7)) & 7);~n", [N,4*((A0+1) rem 2),N]),
+ w(" wxFileName ~s = wxFileName(~sStr);~n",[N,N]),
+ 0;
+decode_arg(N,#type{base=string},Arg,A0) ->
+ w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
+ wa(" wxString", []," ~s = wxString(bp, wxConvUTF8);~n", [N],Arg),
+ w(" bp += *~sLen+((8-((~p+ *~sLen) & 7)) & 7);~n", [N,4*((A0+1) rem 2),N]),
+ 0;
+decode_arg(N,#type{name="wxArrayString"},Place,A0) ->
+ w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
+ case Place of
+ arg -> w(" wxArrayString ~s;~n", [N]);
+ opt -> ignore %% Allready declared
+ end,
+ w(" int ~sASz = 0, * ~sTemp;~n", [N,N]),
+ w(" for(int i=0; i < *~sLen; i++) {~n", [N]),
+ w(" ~sTemp = (int *) bp; bp += 4;~n", [N]),
+ w(" ~s.Add(wxString(bp, wxConvUTF8));~n", [N]),
+ w(" bp += *~sTemp;~n", [N]),
+ w(" ~sASz += *~sTemp+4;~n }~n", [N,N]),
+ w(" bp += (8-((~p+ ~sASz) & 7 )) & 7;~n", [4*((A0+1) rem 2),N]),
+ 0;
+
+decode_arg(N,#type{name="wxArrayInt"},arg,A0) ->
+ w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
+ w(" wxArrayInt ~s;~n", [N]),
+ w(" for(int i=0; i < *~sLen; i++) {", [N]),
+ w(" ~s.Add(*(int *) bp); bp += 4;}~n", [N]),
+ w(" bp += ((*~sLen + ~p) % 2 )*4;~n",[N, (A0+1)]),
+ 0;
+decode_arg(N,#type{name="wxArrayDouble"},arg,A0) ->
+ w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
+ align(A0+1,64),
+ w(" wxArrayDouble ~s;~n", [N]),
+ w(" for(int i=0; i < *~sLen; i++) {", [N]),
+ w(" ~s.Add(*(int *) bp); bp += 4;}~n", [N]),
+ 0;
+decode_arg(_N,#type{base=eventType},_Arg,A0) ->
+%% w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
+%% case Arg of
+%% arg ->
+%% w(" int ~s = wxeEventTypeFromAtom(bp);bp += *~sLen;~n",[N,N]),
+%% w(" char *class_name = bp;~n", []),
+%% w(" wxeCallbackData * Evt_cb = new wxeCallbackData(Ecmd.caller,This,class_name);~n",
+%% [])
+%% end,
+ A0;
+decode_arg(N,#type{name=Type,base=binary,mod=Mod0},Arg,A0) ->
+ Mod = mods([M || M <- Mod0]),
+ case Arg of
+ arg ->
+ w(" ~s~s * ~s = (~s~s*) Ecmd.bin[~p]->base; ~n",
+ [Mod,Type,N,Mod,Type, next_id(bin_count)]);
+ opt ->
+ w(" ~s = (~s~s*) Ecmd.bin[~p]->base; ~n",
+ [N,Mod,Type,next_id(bin_count)])
+ end,
+ A0;
+decode_arg(N,#type{base={term,"wxTreeItemData"},mod=Mod0},Arg,A0) ->
+ Mod = mods([M || M <- Mod0]),
+ Type = "wxETreeItemData",
+ BinCnt = next_id(bin_count),
+ case Arg of
+ arg ->
+ w(" ~s~s * ~s = new ~s(Ecmd.bin[~p]->size, Ecmd.bin[~p]->base); ~n",
+ [Mod,Type,N,Type,BinCnt,BinCnt]);
+ opt ->
+ w(" ~s = new ~s(Ecmd.bin[~p]->size, Ecmd.bin[~p]->base); ~n",
+ [N,Type,BinCnt,BinCnt])
+ end,
+ A0;
+decode_arg(N,#type{name=Type,base={term,_},mod=Mod0},Arg,A0) ->
+ Mod = mods([M || M <- Mod0]),
+ BinCnt = next_id(bin_count),
+ case Arg of
+ arg ->
+ w(" ~s~s * ~s = new ~s(Ecmd.bin[~p]); ~n",
+ [Mod,Type,N,Type,BinCnt]);
+ opt ->
+ w(" ~s = new ~s(Ecmd.bin[~p]); ~n",
+ [N,Type,BinCnt])
+ end,
+ A0;
+decode_arg(N,#type{single=array,base=int},Arg,A0) ->
+ case Arg of
+ arg ->
+ w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
+ w(" int * ~s = (int *) bp; bp += *~sLen*4+((~p+ *~sLen)%2 )*4;~n",
+ [N,N,(A0+1) rem 2,N]);
+ opt ->
+ w(" ~sLen = (int *) bp; bp += 4;~n", [N]),
+ w(" ~s = (int *) bp; bp += *~sLen*4+((~p+ *~sLen)%2 )*4;~n",
+ [N,N,(A0+1) rem 2,N])
+ end,
+ 0;
+decode_arg(N,#type{by_val=true,single=array,base={comp,Class="wxPoint",_}},arg,A0) ->
+ w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
+ w(" ~s *~s;~n",[Class,N]),
+ w(" ~s = (~s *) driver_alloc(sizeof(~s) * *~sLen);~n",[N,Class,Class,N]),
+ store_free(N),
+ w(" for(int i=0; i < *~sLen; i++) {~n", [N]),
+ w(" int x = * (int *) bp; bp += 4;~n int y = * (int *) bp; bp += 4;~n", []),
+ w(" ~s[i] = wxPoint(x,y);}~n", [N]),
+ align(A0,32);
+decode_arg(N,#type{by_val=true,single=array,base={class,Class}},arg,A0) ->
+ A = align(A0,32),
+ w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
+ w(" ~s *~s;~n",[Class,N]),
+ w(" ~s = (~s *) driver_alloc(sizeof(~s) * *~sLen);", [N, Class, Class, N]),
+ store_free(N),
+ w(" for(int i=0; i < *~sLen; i++) {", [N]),
+ w(" ~s[i] = * (~s *) getPtr(bp,memenv); bp += 4;}~n", [N,Class]),
+ w(" bp += ((~p+ *~sLen)%2 )*4;~n", [A, N]),
+ 0;
+decode_arg(N,#type{name=Type,single=list,base={class,Class}},arg,A0) ->
+ w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
+ A = align(A0,32),
+ w(" ~s ~s;~n",[Type,N]),
+ w(" for(int i=0; i < *~sLen; i++) {", [N]),
+ w(" ~s.Append(*(~s *) getPtr(bp,memenv)); bp += 4;}~n", [N,Class]),
+ w(" bp += ((~p+ *~sLen)%2 )*4;~n", [A,N]),
+ 0;
+decode_arg(Name,T, Arg,_A) ->
+ ?error({unhandled_type, {Name,T, Arg}}).
+
+align(0, 32) -> 1;
+align(1, 32) -> 0;
+align(0, 64) -> 0;
+align(1, 64) ->
+ w(" bp += 4; /* Align */~n"),
+ 0;
+align(N,Sz) ->
+ align(N rem 2, Sz).
+
+call_wx(_N,{constructor,_},#type{base={class,RClass}},Ps) ->
+ #class{id=Id} = ClassDef = get({class,RClass}),
+ Class = case is_derived(ClassDef) of
+ true -> "E" ++ RClass;
+ false -> RClass
+ end,
+ w(" ~s * Result = new ~s(~s);~n",
+ [RClass, Class,args(fun call_arg/1, ",",filter(Ps))]),
+ CType = case is_window(RClass) of
+ true -> %% Windows have parents that should be deleted first
+ case is_dialog(RClass) of
+ true -> 2; %% Dialogs must be closed first event before windows
+ false -> 0
+ end;
+ false ->
+ case hd(reverse(wx_gen_erl:parents(RClass))) of
+ root -> Id;
+ _ -> 1
+ end
+ end,
+ case virtual_dest(ClassDef) orelse (CType =/= 0) of
+ true ->
+ w(" newPtr((void *) Result, ~p, memenv);~n", [CType]);
+ false -> %% Hmm window without virt dest
+ w(" /* Possible memory leak here, class is missing virt dest */ \n")
+ end,
+ Ps;
+call_wx(N,{member,_},Type,Ps) ->
+ {Beg,End} = return_res(Type),
+ w(" if(!This) throw wxe_badarg(0);~n",[]),
+ w(" ~sThis->~s(~s)~s;~n",[Beg,N,args(fun call_arg/1, ",",filter(Ps)),End]),
+ Ps;
+call_wx(N,{static,Class},Type,Ps) ->
+ {Beg,End} = return_res(Type),
+ #class{parent=Parent} = get({class,Class}),
+ case Parent of
+ "static" ->
+ w(" ~s::~s(~s)~s;~n",[Beg,N,args(fun call_arg/1, ",",filter(Ps)),End]);
+ _ ->
+ w(" ~s~s::~s(~s)~s;~n",[Beg,Class,N,args(fun call_arg/1, ",",filter(Ps)),End])
+ end,
+ Ps.
+
+
+return_res(void) -> {"", ""};
+return_res(Type = #type{mod=Mod}) ->
+ case lists:member(const, Mod) of
+ true ->
+ {Beg, End} = return_res1(Type),
+ {"const " ++ Beg, End};
+ _ ->
+ return_res1(Type)
+ end.
+
+return_res1(#type{name=Type,ref={pointer,_}, base={term,_}}) ->
+ {Type ++ " * Result = (" ++ Type ++ "*)", ""};
+return_res1(#type{name=Type,ref={pointer,_}}) ->
+ {Type ++ " * Result = (" ++ Type ++ "*)", ""};
+return_res1(#type{name=Type,single=true,ref=reference}) ->
+ {Type ++ " * Result = &", ""};
+return_res1(#type{name=Type,single=true,by_val=true})
+ when is_atom(Type) ->
+ {atom_to_list(Type) ++ " Result = ", ""};
+return_res1(#type{name=Type="wxArrayInt"}) ->
+ {Type ++ " Result = ", ""};
+return_res1(#type{name=Type,base={class,_},single=list,ref=reference}) ->
+ {Type ++ " Result = ", ""};
+return_res1(#type{name=Type,base={comp,_,_},single=array,by_val=true}) ->
+ {Type ++ " Result = ", ""};
+return_res1(#type{name=Type,single=true,by_val=true, base={class, _}}) ->
+ %% Memory leak !!!!!! XXXX BUGBUG FIXME or doument!!
+ case Type of
+ "wxImage" -> ok;
+ "wxFont" -> ok;
+ "wxBitmap" -> ok;
+ "wxIcon" -> ok;
+ "wxGraphics" ++ _ -> ok;
+ _ ->
+ io:format("~s::~s Building return value of temp ~s~n",
+ [get(current_class),get(current_func),Type])
+ end,
+ %% #class{id=Id} = get({class,Type}),
+ {Type ++ " * Result = new " ++ Type ++ "(", "); newPtr((void *) Result,"
+ ++ "3, memenv);"};
+return_res1(#type{base={enum,_Type},single=true,by_val=true}) ->
+ {"int Result = " , ""};
+return_res1(#type{name="wxCharBuffer", base={binary,_},single=true,by_val=true}) ->
+ {"char * Result = ", ".data()"};
+return_res1(#type{name=Type,single=array,ref=reference}) ->
+ {Type ++ " Result = ", ""};
+return_res1(#type{name=Type,single=true,by_val=true}) ->
+ {Type ++ " Result = ", ""}.
+
+filter(Ps) ->
+ lists:filter(fun filter_arg/1, Ps).
+filter_arg(#param{where=erl}) -> false;
+filter_arg(#param{where=this}) -> false;
+filter_arg(#param{}) -> true.
+%%filter_arg(#param{def=Def, in=In}) -> Def =:= none orelse In =:= false.
+
+
+call_arg(#param{where=c, alt={length,Alt}}) when is_list(Alt) ->
+ "*" ++ Alt ++ "Len";
+call_arg(#param{where=c, alt={size,Id}}) when is_integer(Id) ->
+ %% It's a binary
+ "Ecmd.bin["++ integer_to_list(Id) ++ "]->size";
+call_arg(#param{name=N,def=Def,type=#type{name=Type,by_val=true,single=true,base=Base}})
+ when Base =:= int; Base =:= long; Base =:= float; Base =:= double; Base =:= bool ->
+ case Def of
+ none -> "(" ++ to_string(Type) ++ ") *" ++ N;
+ _ -> N
+ end;
+
+call_arg(#param{name=N,type=#type{base={enum,Type}, by_val=true,single=true}}) ->
+ "(" ++ enum_type(Type) ++") " ++ N;
+call_arg(#param{name=N,type=#type{base={class,_},by_val=true,single=true}}) -> "*" ++ N;
+call_arg(#param{name=N,type=#type{base={class,_},ref=reference,single=true}}) -> "*" ++ N;
+call_arg(#param{name=N,type=#type{base=eventType}}) ->
+ N ++ ", (wxObjectEventFunction)(wxEventFunction) &WxeApp::handle_evt, Evt_cb, this";
+call_arg(#param{name=N,type=#type{by_val=true, single=_False}}) -> N;
+call_arg(#param{name=N,def=Def,type=#type{by_val=false, ref={pointer,2}}})
+ when Def =/= none -> N;
+call_arg(#param{name=N,type=#type{by_val=false, ref={pointer,2}}}) -> "&" ++ N;
+call_arg(#param{name=N,in=false,type=#type{ref=reference, single=true}}) -> N;
+call_arg(#param{name=N,in=false,type=#type{by_val=false, single=true}}) -> "&" ++ N;
+call_arg(#param{name=N,def=Def,type=#type{base={comp,_,_},ref={pointer,1},single=true}})
+ when Def =:= none ->
+ "&" ++N;
+call_arg(#param{name=N,type=#type{by_val=false}}) -> N;
+call_arg(#param{name=N,type={merged,_,#type{base={class,_},single=true,
+ by_val=ByVal,
+ ref=Ref},_,_,_,_}})
+ when ByVal =:= true; Ref =:= reference ->
+ "*" ++ N;
+call_arg(#param{def=Def, type=void}) when Def =/= none -> Def;
+call_arg(#param{name=N,type=#type{base={ref,_},by_val=true,single=true}}) -> N;
+call_arg(#param{name=N,type={merged,_,_,_,_,_,_}}) -> N.
+
+%% call_arg(#param{name=N,type=#type{base=Tuple,ref=reference}})
+%% when is_tuple(Tuple) -> "&" ++ N;
+
+to_string(Type) when is_atom(Type) -> atom_to_list(Type);
+to_string(Type) when is_list(Type) -> Type.
+
+virtual_dest(#class{abstract=true, parent="root"}) -> false;
+virtual_dest(#class{abstract=true, parent="object"}) -> true;
+virtual_dest(#class{abstract=true, parent=Parent}) ->
+ virtual_dest(get({class,Parent}));
+virtual_dest(#class{methods=Ms, parent=Parent}) ->
+ case lists:keysearch(destructor,#method.method_type, lists:append(Ms)) of
+ {value, #method{method_type=destructor, virtual=Virtual}} ->
+ case Virtual of
+ undefined ->
+ case get({class,Parent}) of
+ undefined ->
+ case Parent of
+ "object" ->
+ true;
+ "root" ->
+ false;
+ _ ->
+ io:format("Error: ~p ~n",[Parent]),
+ erlang:error(no_parent)
+ end;
+ PClass ->
+ virtual_dest(PClass)
+ end;
+ _ ->
+ Virtual
+ end;
+ false ->
+ false
+ end.
+
+debug(F,A) ->
+ case get(debug) of
+ true -> ?warning(F,A);
+ _ -> ok
+ end.
+
+is_derived(#class{abstract=true}) -> false;
+is_derived(C = #class{}) -> virtual_dest(C).
+
+is_window(Class) ->
+ lists:member("wxWindow", wx_gen_erl:parents(Class)).
+
+is_dialog(Class) ->
+ lists:member("wxDialog", wx_gen_erl:parents(Class)).
+
+build_return_vals(Type,Ps) ->
+ HaveType = case Type of void -> 0; _ -> 1 end,
+ NoOut = lists:sum([1 || #param{in=In} <- Ps, In =/= true]) + HaveType,
+ OutTupSz = if NoOut > 1 -> NoOut; true -> 0 end,
+
+ build_ret_types(Type,Ps),
+ if
+ OutTupSz > 1 -> w(" rt.addTupleCount(~p);~n",[OutTupSz]);
+ true -> ignore
+ end,
+ Ps.
+
+build_ret_types(void,Ps) ->
+ Calc = fun(#param{name=N,in=False,type=T}, Free) when False =/= true ->
+ case build_ret(N, False, T) of
+ ok -> Free;
+ Other -> [Other|Free]
+ end;
+ (_, Free) -> Free
+ end,
+ lists:foldl(Calc, [], Ps);
+build_ret_types(Type,Ps) ->
+ Free = case build_ret("Result", out, Type) of
+ ok -> [];
+ FreeStr -> [FreeStr]
+ end,
+ Calc = fun(#param{name=N,in=False,type=T}, FreeAcc) when False =/= true ->
+ case build_ret(N, False, T) of
+ ok -> FreeAcc;
+ FreeMe -> [FreeMe|FreeAcc]
+ end;
+ (_, FreeAcc) -> FreeAcc
+ end,
+ lists:foldl(Calc, Free, Ps).
+
+build_ret(Name,_,#type{base={class,Class},single=true}) ->
+ w(" rt.addRef(getRef((void *)~s,memenv), \"~s\");~n",[Name,Class]);
+build_ret(Name,_,#type{base={ref,"wxTreeItemId"=Class},single=true}) ->
+ w(" rt.addRef(getRef((void *)~s.m_pItem,memenv), \"~s\");~n",[Name,Class]);
+build_ret(Name,_,#type{base={term,_},single=true}) ->
+ w(" rt.addExt2Term(~s);~n", [Name]);
+build_ret(Name,_,#type{base={binary,Size},single=true}) ->
+ w(" if(~s) {~n", [Name]),
+ w(" rt.addBinary(~s, ~s);~n", [Name,Size]),
+ w(" } else {rt.addAtom(\"null\");};~n");
+build_ret(Name,_,#type{name="wxUIntPtr", ref={pointer,1}, single=true}) ->
+ w(" rt.add(~s);~n", [Name]);
+build_ret(Name,_,#type{base={enum,_Type},single=true}) ->
+ w(" rt.addInt(~s);~n",[Name]);
+build_ret(Name,_,#type{base={comp,_,{record, _}},single=true}) ->
+ w(" rt.add(~s);~n", [Name]);
+build_ret(Name,_,#type{base={comp,_,_},single=true, ref=reference}) ->
+ w(" rt.add((*~s));~n",[Name]);
+build_ret(Name,_,#type{base={comp,_,_},single=true}) ->
+ w(" rt.add(~s);~n",[Name]);
+build_ret(Name,_,#type{base=bool,single=true,by_val=true}) ->
+ w(" rt.addBool(~s);~n",[Name]);
+build_ret(Name,both,#type{base=int,single=true,mod=M}) ->
+ case lists:member(unsigned, M) of
+ true -> w(" rt.addUint(*~s);~n",[Name]);
+ false -> w(" rt.addInt(*~s);~n",[Name])
+ end;
+build_ret(Name,_,#type{base=int,single=true,mod=M}) ->
+ case lists:member(unsigned, M) of
+ true -> w(" rt.addUint(~s);~n",[Name]);
+ false -> w(" rt.addInt(~s);~n",[Name])
+ end;
+build_ret(Name,_,#type{name="wxArrayInt"}) ->
+ w(" rt.add(~s);~n", [Name]);
+build_ret(Name,_,#type{base={comp,_,_},single=array}) ->
+ w(" for(unsigned int i=0; i < ~s.GetCount(); i++) {~n", [Name]),
+ w(" rt.add(~s[i]);~n }~n",[Name]),
+ w(" rt.endList(~s.GetCount());~n",[Name]);
+build_ret(Name,_,#type{name=List,single=list,base={class,Class}}) ->
+ w(" int i=0;~n"),
+ w(" for(~s::const_iterator it = ~s.begin(); it != ~s.end(); ++it) {~n",
+ [List, Name, Name]),
+ w(" ~s * ~sTmp = *it;~n", [Class,Name]),
+ w(" rt.addRef(getRef((void *)~sTmp,memenv), \"~s\"); i++;}~n",[Name,Class]),
+ w(" rt.endList(~s.GetCount());~n",[Name]);
+
+build_ret(Name,_,#type{name="wxArrayTreeItemIds"}) ->
+ w(" for(unsigned int i=0; i < ~s.GetCount(); i++) {~n", [Name]),
+ w(" rt.addRef(getRef((void *)~s[i].m_pItem,memenv), \"wxTreeItemId\");}~n",[Name]),
+ w(" rt.endList(~s.GetCount());~n",[Name]);
+
+build_ret(Name,_,#type{base=float,single=true}) ->
+%% w(" double Temp~s = ~s;~n", [Name,Name]),
+ w(" rt.addFloat(~s);~n",[Name]);
+build_ret(Name,_,#type{base=double,single=true}) ->
+ w(" rt.addFloat(~s);~n",[Name]);
+build_ret(Name,_,#type{base=string,single=true}) ->
+ w(" rt.add(~s);~n",[Name]);
+build_ret(Name,_,#type{name="wxArrayString", single=array}) ->
+ w(" rt.add(~s);~n", [Name]);
+build_ret(Name,In,T) ->
+ ?error({nyi, Name,In, T}).
+
+mods([const|R]) -> "const " ++ mods(R);
+mods([unsigned|R]) -> "unsigned " ++ mods(R);
+mods([]) -> "".
+
+build_enums() ->
+ Tree = get(consts),
+ w(" /* This file is also generated */~n"),
+ w("#include <wx/wx.h>~n"),
+ w("#include \"../wxe_impl.h\"~n"),
+ w("#include \"wxe_macros.h\"~n"),
+ w("#include \"../wxe_return.h\"~n"),
+ w("void WxeApp::init_nonconsts(wxeMemEnv *memenv, ErlDrvTermData caller) {~n"),
+ NotConsts = [NC || NC = #const{is_const=false} <- gb_trees:values(Tree)],
+ Size = length(NotConsts),
+ GVars = get(gvars),
+ GSize = length(GVars),
+ w(" wxeReturn rt = wxeReturn(WXE_DRV_PORT, caller);~n"),
+ w(" rt.addAtom((char*)\"wx_consts\");~n"),
+ [build_enum(NConst) || NConst <- lists:keysort(#const.val, NotConsts)],
+ _Cnt = foldl(fun(Gvar, I) -> build_gvar(Gvar,I) end, 0, lists:sort(GVars)),
+ w(" rt.endList(~p);~n", [Size+GSize]),
+ w(" rt.addTupleCount(2);~n"),
+ w(" rt.send();~n"),
+ w("}~n"),
+ ok.
+
+build_enum(#const{name=Name}) ->
+ w(" rt.addAtom(\"~s\"); rt.addInt(~s);~n", [Name, Name]),
+ w(" rt.addTupleCount(2);~n").
+
+build_gvar({Name, "wxColour", _Id}, Cnt) ->
+ w(" rt.addAtom(\"~s\"); rt.add(*(~s));~n",[Name,Name]),
+ w(" rt.addTupleCount(2);~n"),
+ Cnt;
+build_gvar({Name, {address,Class}, _Id}, Cnt) ->
+ w(" rt.addAtom(\"~s\"); rt.addRef(getRef((void *)&~s,memenv), \"~s\");~n",[Name,Name,Class]),
+ w(" rt.addTupleCount(2);~n"),
+ Cnt+1;
+build_gvar({Name, Class, _Id}, Cnt) ->
+ w(" rt.addAtom(\"~s\"); rt.addRef(getRef((void *)~s,memenv),\"~s\");~n",[Name,Name,Class]),
+ w(" rt.addTupleCount(2);~n"),
+ Cnt+1.
+
+gen_macros() ->
+ w("#include <wx/caret.h>~n"), %% Arrg wxw forgot?? some files
+ w("#include <wx/tooltip.h>~n"),
+ w("#include <wx/gbsizer.h>~n"),
+ w("#include <wx/splash.h>~n"),
+ w("#include <wx/grid.h>~n"),
+ w("#include <wx/image.h>~n"),
+ w("#include <wx/tglbtn.h>~n"),
+ w("#include <wx/calctrl.h>~n"),
+ w("#include <wx/dirctrl.h>~n"),
+ w("#include <wx/listctrl.h>~n"),
+ w("#include <wx/treectrl.h>~n"),
+ w("#include <wx/spinbutt.h>~n"),
+ w("#include <wx/spinctrl.h>~n"),
+ w("#include <wx/colordlg.h>~n"),
+ w("#include <wx/fdrepdlg.h>~n"),
+ w("#include <wx/fontdlg.h>~n"),
+ w("#include <wx/progdlg.h>~n"),
+ w("#include <wx/printdlg.h>~n"),
+ w("#include <wx/dcbuffer.h>~n"),
+ w("#include <wx/dcmirror.h>~n"),
+ w("#include <wx/glcanvas.h>~n"),
+ w("#include <wx/dcps.h>~n"),
+ w("#include <wx/xrc/xmlres.h>~n"),
+ w("#include <wx/html/htmprint.h>~n"),
+ w("#include <wx/stc/stc.h>~n"),
+ w("#include <wx/minifram.h>~n"),
+ w("#include <wx/sashwin.h>~n"),
+ w("#include <wx/laywin.h>~n"),
+ w("#include <wx/graphics.h>~n"),
+ w("#include <wx/aui/aui.h>~n"),
+ w("#include <wx/datectrl.h>~n"),
+ w("#include <wx/filepicker.h>~n"),
+ w("#include <wx/fontpicker.h>~n"),
+ w("#include <wx/clrpicker.h>~n"),
+ w("#include <wx/statline.h>~n"),
+ w("#include <wx/clipbrd.h>~n"),
+ w("#include <wx/splitter.h>~n"),
+ w("#include <wx/choicebk.h>~n"),
+ w("#include <wx/toolbook.h>~n"),
+ w("#include <wx/listbook.h>~n"),
+ w("#include <wx/treebook.h>~n"),
+ w("#include <wx/html/htmlwin.h>~n"),
+ w("#include <wx/html/htmlcell.h>~n"),
+ w("#include <wx/filename.h>~n"),
+
+ w("~n~n", []),
+ [w("#define ~s_~s ~p~n", [Class,Name,Id]) ||
+ {Class,Name,_,Id} <- wx_gen_erl:get_unique_names()],
+ w("~n~n").
+
+build_events() ->
+ open_write("../c_src/gen/wxe_events.cpp"),
+ c_copyright(),
+ w("~n/***** This file is generated do not edit ****/ ~n~n"),
+ w("#include <wx/wx.h>~n"),
+ w("#include \"../wxe_impl.h\"~n~n"),
+ w("#include \"wxe_macros.h\"~n"),
+ w("#include \"../wxe_events.h\"~n~n"),
+ w("#include \"../wxe_return.h\"~n~n"),
+
+ w("wxeEtype::wxeEtype(const char *name, int Id) {eName = name;cID = Id;}~n~n"),
+ w("WX_DECLARE_HASH_MAP(int, wxeEtype*, wxIntegerHash, wxIntegerEqual, wxeETmap );~n~n"),
+
+ w("wxeETmap etmap; ~n~n"),
+
+ w(
+"int wxeEventTypeFromAtom(char *etype_atom) {
+ wxeETmap::iterator it;
+ for(it = etmap.begin(); it != etmap.end(); ++it) {
+ wxeEtype * value = it->second;
+ if(strcmp(value->eName, etype_atom) == 0) {
+ if(it->first > wxEVT_USER_FIRST) {
+ return it->first - wxEVT_USER_FIRST;
+ } else {
+ return it->first;
+ }
+ }
+ }
+ return -1;
+}
+
+"),
+
+ Evs0 = [C || {_,C=#class{event=Evs}} <- get(), Evs =/= false],
+ Evs = lists:keysort(#class.id, Evs0),
+ initEventTable(Evs),
+ encode_events(Evs),
+ close().
+
+initEventTable(Evs) ->
+ w("void initEventTable() ~n{~n"),
+ w(" struct { ",[]),
+ w("int ev_type; int class_id; const char * ev_name;} event_types[] = ~n {~n",[]),
+
+ lists:foreach(fun(Ev) -> init_event_classes(Ev) end,
+ [#class{id=0,event=[wxEVT_NULL]}|Evs]),
+ w(" {-1, 0, ""}~n };~n",[]),
+ w(" for(int i=0; event_types[i].ev_type != -1; i++) {~n",[]),
+ w(" if(NULL == etmap[event_types[i].ev_type]) {~n",[]),
+ w(" etmap[event_types[i].ev_type] = ~n"
+ " new wxeEtype(event_types[i].ev_name, event_types[i].class_id);~n"),
+ w(" } else {~n",[]),
+ w(" wxeEtype *prev = etmap[event_types[i].ev_type];~n"
+ " wxString msg(wxT(\"Duplicate event defs: \"));~n"
+ " msg += wxString::FromAscii(event_types[i].ev_name);~n"
+ " msg += wxString::Format(wxT(\" %d \"), event_types[i].class_id);~n"
+ " msg += wxString::FromAscii(prev->eName);~n"
+ " msg += wxString::Format(wxT(\" %d\"), prev->cID);~n"
+ " send_msg(\"internal_error\", &msg);~n"
+ " }~n"
+ " }~n", []),
+ w("}~n~n").
+
+init_event_classes(#class{event=ETs, id=Id}) ->
+ F = fun({Eev, Cev, OtherClass}) ->
+ w(" {~w + wxEVT_USER_FIRST, ~w, ~p},~n",
+ [Cev, find_id(OtherClass), wx_gen_erl:event_type_name(Eev)]);
+ ({Ev, {test_if, Test}}) ->
+ w("#if ~s ~n", [Test]),
+ w(" {~w, ~w, ~p},~n",
+ [Ev, Id, wx_gen_erl:event_type_name(Ev)]),
+ w("#endif ~n", []);
+ (Ev) ->
+ w(" {~w, ~w, ~p},~n",
+ [Ev, Id, wx_gen_erl:event_type_name(Ev)])
+ end,
+ [F(ET) || ET <- ETs].
+
+find_id(OtherClass) ->
+ Class = get({class,atom_to_list(OtherClass)}),
+ %%{value, Class} = lists:keysearch(atom_to_list(OtherClass), #class.name, All),
+ Class#class.id.
+
+encode_events(Evs) ->
+ ?WTC("encode_events"),
+ w("void wxeEvtListener::forward(wxEvent& event) ~n"
+ "{ ~n"
+ "#ifdef DEBUG~n"
+ " if(!sendevent(&event, port)) ~n"
+ " fprintf(stderr, \"Couldn't send event!\\r\\n\");~n"
+ "#else~n"
+ "sendevent(&event, port);~n"
+ "#endif~n"
+ "}~n~n"),
+ w("int getRef(void* ptr, wxeMemEnv* memenv) ~n"
+ "{ ~n"
+ " WxeApp * app = (WxeApp *) wxTheApp;~n"
+ " return app->getRef(ptr,memenv);~n"
+ "} ~n~n"),
+ w("bool sendevent(wxEvent *event, ErlDrvPort port)~n{~n"
+ " int send_res ;~n"
+ " char * evClass = NULL;~n"
+ " wxMBConvUTF32 UTFconverter;~n"
+ " wxeEtype *Etype = etmap[event->GetEventType()];~n"
+ " wxeCallbackData *cb = (wxeCallbackData *)event->m_callbackUserData;~n"
+ " WxeApp * app = (WxeApp *) wxTheApp;~n"
+ " wxeMemEnv *memenv = app->getMemEnv(port);~n"
+ " if(!memenv) return 0;~n~n"
+ " wxeReturn rt = wxeReturn(port, cb->listener);~n"),
+
+ w("~n rt.addAtom((char*)\"wx\");~n"
+ " rt.addInt((int) event->GetId());~n"
+ " rt.addRef(getRef((void *)(cb->obj), memenv), cb->class_name);~n"
+ " rt.addExt2Term(cb->user_data);~n"),
+
+ w(" switch(Etype->cID) {~n"),
+ lists:foreach(fun(Ev) -> encode_event(Ev) end, Evs),
+ w(" }~n~n"),
+
+ w(" rt.addTupleCount(5);~n"),
+ w(" if(cb->fun_id) {~n"),
+ w(" rt.addRef(getRef((void *)event,memenv), evClass);~n"),
+ w(" rt.addTupleCount(2);~n"),
+ w(" rt.addInt(cb->fun_id);~n"),
+ w(" rt.addAtom(\"_wx_invoke_cb_\");~n"),
+ w(" rt.addTupleCount(3);~n"),
+ w(" pre_callback();~n"),
+ w(" send_res = rt.send();~n"),
+ w(" if(send_res) handle_event_callback(port, cb->listener);~n"),
+ w(" app->clearPtr((void *) event);~n"),
+ w(" } else {~n"),
+ w(" send_res = rt.send();~n"),
+ w(" if(cb->skip) event->Skip();~n"),
+ w(" };~n"),
+ w(" return send_res;~n"),
+ w(" }~n").
+
+encode_event(C = #class{name=Class, id=Id, options=Opts}) ->
+ ?WTC("encode_event"),
+ case proplists:get_value("mixed_event", Opts) of
+ undefined ->
+ w("case ~p: {// ~s~n", [Id,Class]),
+ encode_event2(C),
+ ok;
+ Mixed ->
+ w("case ~p: {// ~s or ~s~n", [Id,Class,Mixed]),
+ w(" if(event->IsKindOf(CLASSINFO(~s))) {~n",[Class]),
+ encode_event2(C),
+ w(" } else {~n",[]),
+ w(" Etype = etmap[event->GetEventType() + wxEVT_USER_FIRST];~n",[]),
+ encode_event2(get({class,atom_to_list(Mixed)})),
+ w(" }~n",[]),
+ ok
+ end,
+ w(" break;~n}~n").
+
+encode_event2(Class = #class{name=Name}) ->
+ Attrs = build_event_attrs(Class),
+ w(" evClass = (char*)\"~s\";~n",[Name]),
+ w(" rt.addAtom((char*)\"~s\");~n", [wx_gen_erl:event_rec_name(Name)]),
+ w(" rt.addAtom(Etype->eName);~n"),
+ build_ret_types(void, Attrs),
+ w(" rt.addTupleCount(~p);~n",[length(Attrs) + 2]).
+
+build_event_attrs(ClassRec = #class{name=Class}) ->
+ Attrs0 = wx_gen_erl:filter_attrs(ClassRec),
+ Rename =
+ fun(Att = #param{name=Name,prot=public,acc=undefined}, {All,Use}) ->
+ {[Att#param{name= "ev->" ++ Name}|All],Use};
+ (Att = #param{acc=Acc}, {All,_}) ->
+ {[Att#param{name= "ev->" ++ Acc}|All], true}
+ end,
+ case foldr(Rename,{[],false},Attrs0) of
+ {[],_} -> [];
+%% {Attrs,false} ->
+%% w(" ~s ev = dynamic_cast<~s&>(event);~n",[Class,Class]),
+%% Attrs;
+ {Attrs,_} ->
+ w(" ~s * ev = (~s *) event;~n",[Class,Class]),
+ FixClass =
+ fun(P=#param{name=N,acc=Acc,type=#type{single=Single,by_val=ByVal,
+ base={class,C}}})
+ when Acc =/= undefined ->
+ Var = var_name(N),
+ if Single, ByVal ->
+ w(" ~s * ~s = new ~s(~s);~n", [C,Var,C,N]),
+ w(" app->newPtr((void *) ~s,3, memenv);~n", [Var]);
+ true ->
+ w(" ~s * ~s = ~s;~n", [C,Var,N])
+ end,
+ P#param{name=Var};
+ (P) -> P
+ end,
+ lists:map(FixClass, Attrs)
+ end.
+
+var_name("ev->" ++ Name0) ->
+ case reverse(Name0) of
+ ")(" ++ Name -> reverse(Name);
+ _ -> Name0
+ end;
+var_name(Name) -> Name.
+
+enum_name({Class,Type}) ->
+ uppercase_all(Class ++ "_" ++ Type);
+enum_name(Type) ->
+ uppercase_all(Type).
+
+
+enum_type({Class,Type}) ->
+ Class ++ "::" ++ Type;
+enum_type(Type) -> Type.
diff --git a/lib/wx/api_gen/wx_gen_erl.erl b/lib/wx/api_gen/wx_gen_erl.erl
new file mode 100644
index 0000000000..64c11baec1
--- /dev/null
+++ b/lib/wx/api_gen/wx_gen_erl.erl
@@ -0,0 +1,1272 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%%-------------------------------------------------------------------
+%%% File : wx_gen_erl.erl
+%%% Author : Dan Gudmundsson <[email protected]>
+%%% Description :
+%%%
+%%% Created : 25 Jan 2007 by Dan Gudmundsson <[email protected]>
+%%%-------------------------------------------------------------------
+
+-module(wx_gen_erl).
+
+-include("wx_gen.hrl").
+
+-compile(export_all).
+
+-import(lists, [foldl/3,foldr/3,reverse/1, keysearch/3, map/2, filter/2]).
+-import(gen_util, [lowercase/1, lowercase_all/1, uppercase/1, uppercase_all/1,
+ open_write/1, close/0, erl_copyright/0, w/2,
+ args/3, args/4, strip_name/2]).
+
+gen(Defs) ->
+ [put({class,N},C) || C=#class{name=N} <- Defs],
+ gen_unique_names(Defs),
+ gen_event_recs(),
+ gen_enums_ints(),
+ [gen_class(Class) || Class <- Defs],
+ gen_funcnames().
+
+gen_class(Class) ->
+ try
+ gen_class1(Class)
+ catch throw:skipped ->
+ Class
+ end.
+
+gen_class1(C=#class{name=Name,parent="static",methods=Ms,options=_Opts}) ->
+ open_write("../src/gen/wx_misc.erl"),
+ put(current_class, Name),
+ erl_copyright(),
+ w("", []),
+ w("%% This file is generated DO NOT EDIT~n~n", []),
+ w("%% @doc See external documentation: "
+ "<a href=\"http://www.wxwidgets.org/manuals/stable/wx_miscellany.html\">Misc</a>.\n\n",[]),
+
+ w("%% This module contains wxWidgets utility functions.~n~n", []),
+ w("-module(wx_misc).~n", []),
+ w("-include(\"wxe.hrl\").~n",[]),
+ %% w("-compile(export_all).~n~n", []), %% XXXX remove ???
+
+ Exp = fun(M) -> gen_export(C,M) end,
+ ExportList = lists:usort(lists:append(lists:map(Exp,reverse(Ms)))),
+ w("-export([~s]).~n~n", [args(fun(EF) -> EF end, ",", ExportList, 60)]),
+
+
+ Gen = fun(M) -> gen_method(Name,M) end,
+ NewMs = lists:map(Gen,reverse(Ms)),
+ close(),
+ erase(current_class),
+ C#class{methods=NewMs};
+
+gen_class1(C=#class{name=Name,parent=Parent,methods=Ms,options=Opts}) ->
+ case Opts of
+ ["ignore"] -> throw(skipped);
+ _ -> ok
+ end,
+ open_write("../src/gen/"++Name++".erl"),
+ put(current_class, Name),
+ erl_copyright(),
+ w("", []),
+ w("%% This file is generated DO NOT EDIT~n~n", []),
+
+ case lists:member(taylormade, Opts) of
+ true ->
+ {ok, Bin} = file:read_file(filename:join([wx_extra, Name++".erl"])),
+ w("~s~n", [binary_to_list(Bin)]),
+ NewMs = Ms;
+ false ->
+ w("%% @doc See external documentation: "
+ "<a href=\"http://www.wxwidgets.org/manuals/stable/wx_~s.html\">~s</a>.\n",
+ [lowercase_all(Name), Name]),
+
+ case C#class.doc of
+ undefined -> ignore;
+ Str -> w("%%~n%% ~s~n~n%%~n", [Str])
+ end,
+
+ case C#class.event of
+ false -> ignore;
+ Evs ->
+ EvTypes = [event_type_name(Ev) || Ev <- Evs],
+ EvStr = args(fun(Ev) -> "<em>"++Ev++"</em>" end, ", ", EvTypes),
+
+ w("%% <dl><dt>Use {@link wxEvtHandler:connect/3.} with EventType:</dt>~n",[]),
+ w("%% <dd>~s</dd></dl>~n", [EvStr]),
+ w("%% See also the message variant {@link wxEvtHandler:~s(). #~s{}} event record type.~n",
+ [event_rec_name(Name),event_rec_name(Name)]),
+ w("%%~n",[]),
+ ok
+ end,
+
+ Parents = parents(Parent),
+ case [P || P <- Parents, P =/= root, P =/= object] of
+ [] -> ignore;
+ Ps ->
+ w("%% <p>This class is derived (and can use functions) from: ~n", []),
+ [w("%% <br />{@link ~s}~n", [P]) || P <- Ps],
+ w("%% </p>~n",[])
+ end,
+ w("%% @type ~s(). An object reference, The representation is internal~n",[Name]),
+ w("%% and can be changed without notice. It can't be used for comparsion~n", []),
+ w("%% stored on disc or distributed for use on other nodes.~n~n", []),
+ w("-module(~s).~n", [Name]),
+ w("-include(\"wxe.hrl\").~n",[]),
+ %% w("-compile(export_all).~n~n", []), %% XXXX remove ???
+ %% w("-compile(nowarn_unused_vars).~n~n", []), %% XXXX remove ???
+ Exp = fun(M) -> gen_export(C,M) end,
+ ExportList = lists:usort(lists:append(lists:map(Exp,reverse(Ms)))),
+ w("-export([~s]).~n~n", [args(fun(EF) -> EF end, ",", ExportList, 60)]),
+ w("%% inherited exports~n",[]),
+ Done0 = ["Destroy", "New", "Create", "destroy", "new", "create"],
+ Done = gb_sets:from_list(Done0 ++ [M|| #method{name=M} <- lists:append(Ms)]),
+ {_, InExported} = gen_inherited(Parents, Done, []),
+ w("-export([~s]).~n~n", [args(fun(EF) -> EF end, ",",
+ lists:usort(["parent_class/1"|InExported]),
+ 60)]),
+
+ w("%% @hidden~n", []),
+ parents_check(Parents),
+
+ Gen = fun(M) -> gen_method(Name,M) end,
+ NewMs = lists:map(Gen,reverse(Ms)),
+ gen_dest(C, Ms),
+
+ gen_inherited(Parents, Done, true)
+ end,
+
+ close(),
+ erase(current_class),
+ C#class{methods=NewMs}.
+
+
+parents("root") -> [root];
+parents("object") -> [object];
+parents(Parent) ->
+ case get({class,Parent}) of
+ #class{parent=GrandParent} ->
+ [Parent|parents(GrandParent)];
+ undefined ->
+ ?warning("unknown parent of ~p~n",[Parent]),
+ [Parent]
+ end.
+
+parents_check([object]) ->
+ w("parent_class(_Class) -> erlang:error({badtype, ?MODULE}).~n~n",[]);
+parents_check([root]) ->
+ w("parent_class(_Class) -> erlang:error({badtype, ?MODULE}).~n~n",[]);
+parents_check([Parent|Ps]) ->
+ w("parent_class(~s) -> true;~n",[Parent]),
+ parents_check(Ps).
+
+check_class(#type{base={class,"wx"}}) -> ok;
+check_class(#type{base={class,Name},xml=Xml}) ->
+ case get({class,Name}) of
+ undefined ->
+ case get({enum, Name}) of
+ undefined ->
+ case Xml of
+ "class" ++ _ ->
+ ?warning("~s:~s: Class ~p used but not defined~n",
+ [get(current_class),get(current_func),Name]);
+ _ ->
+ ?warning("~s:~s: Class ~p used but not defined~n (see ~p)~n",
+ [get(current_class),get(current_func),Name, Xml])
+ end;
+ _ ->
+ ?warning("~s:~s: Class ~p used is enum~n",
+ [get(current_class),get(current_func),Name])
+ end;
+ _ -> ok
+ end.
+
+gen_export(#class{name=Class,abstract=Abs},Ms0) ->
+ RemoveC = fun(#method{where=merged_c}) -> false;(_Other) -> true end,
+ Res = filter(RemoveC, Ms0),
+ case Res of
+ [] -> [];
+ [M=#method{where=taylormade}|_] ->
+ [taylormade_export(Class, M)];
+ Ms ->
+ GetF = fun(#method{method_type=constructor,where=W,params=Ps}) ->
+ {Args,Opts} = split_optional(Ps),
+ OptLen = case Opts of
+ [] -> 0;
+ _ when W =:= erl_no_opt -> 0;
+ _ -> 1
+ end,
+ "new/" ++ integer_to_list(length(Args)+OptLen);
+ (#method{method_type=destructor}) ->
+ case Abs of
+ true -> [];
+ _ -> "destroy/1"
+ end;
+ (#method{name=N,alias=A,where=W, params=Ps}) ->
+ {Args,Opts} = split_optional(Ps),
+ OptLen = case Opts of
+ [] -> 0;
+ _ when W =:= erl_no_opt -> 0;
+ _ -> 1
+ end,
+ erl_func_name(N,A) ++ "/" ++ integer_to_list(length(Args) + OptLen)
+ end,
+ lists:map(GetF, Ms)
+ end.
+
+
+gen_method(Class,Ms0) ->
+ RemoveC = fun(#method{where=merged_c}) -> false;(_Other) -> true end,
+ Res = filter(RemoveC, Ms0),
+ case Res of
+ [] -> Ms0;
+ [M=#method{where=taylormade}|_] ->
+ taylormade_func(Class, M),
+ Ms0;
+ Ms ->
+ gen_doc(Class,Ms),
+ gen_method1(Ms),
+ Ms0
+ end.
+
+gen_method1([M=#method{method_type=destructor}]) ->
+ %% Skip now do destructors later
+ M;
+gen_method1([M0]) ->
+ gen_method2(M0),
+ w(".~n~n",[]);
+gen_method1([M0|Ms]) ->
+ gen_method2(M0),
+ w(";~n",[]),
+ gen_method1(Ms).
+
+gen_method2(M=#method{name=N,alias=A,params=Ps0,where=erl_no_opt,method_type=MT}) ->
+ put(current_func, N),
+ Ps = [patch_param(P,classes) || P <- Ps0],
+ w("~n", []),
+ gen_function_clause(erl_func_name(N,A),MT,Ps,[],[name_type]),
+ w(" ", []),
+ gen_function_clause(erl_func_name(N,A),MT,Ps,empty_list,[no_guards,name_only]),
+ M;
+gen_method2(M=#method{name=N,alias=A,params=Ps,type=T,method_type=MT,id=MethodId}) ->
+ put(current_func, N),
+ {Args, Optional} = split_optional(Ps),
+ gen_function_clause(erl_func_name(N,A),MT, Args, Optional, []),
+ MId = arg_type_tests(Args, "?" ++ get_unique_name(MethodId)),
+ {MArgs,Align} = marshal_args(Args),
+ MOpts = marshal_opts(Optional, Align, Args),
+ case have_return_vals(T, Ps) of
+ _ when MT =:= constructor ->
+ w(" wxe_util:construct(~s,~n <<~s~s>>)", [MId, MArgs,MOpts]);
+ true ->
+ w(" wxe_util:call(~s,~n <<~s~s>>)", [MId, MArgs,MOpts]);
+ false ->
+ w(" wxe_util:cast(~s,~n <<~s~s>>)", [MId, MArgs,MOpts])
+ end,
+ erase(current_func),
+ M.
+
+gen_dest(#class{name=CName,abstract=Abs}, Ms) ->
+ case Abs of
+ true ->
+ ignore;
+ false ->
+ case lists:keysearch(destructor,#method.method_type, lists:append(Ms)) of
+ {value, #method{method_type=destructor, id=Id}} ->
+ case hd(reverse(parents(CName))) of
+ object ->
+ gen_dest2(CName, object);
+ root ->
+ gen_dest2(CName, Id)
+ end;
+ false ->
+ erlang:error({no_destructor_found, CName})
+ end
+ end.
+
+gen_dest2(Class, Id) ->
+ w("%% @spec (This::~s()) -> ok~n", [Class]),
+ w("%% @doc Destroys this object, do not use object again~n", []),
+ w("destroy(Obj=#wx_ref{type=Type}) -> ~n", []),
+ w(" ?CLASS(Type,~s),~n",[Class]),
+ case Id of
+ object ->
+ w(" wxe_util:destroy(?DESTROY_OBJECT,Obj),~n ok.~n", []);
+ _ ->
+ w(" wxe_util:destroy(?~s,Obj),~n ok.~n", [get_unique_name(Id)])
+ end,
+ ok.
+
+gen_inherited([root], Done, Exported) -> {Done, Exported};
+gen_inherited([object], Done, Exported) -> {Done, Exported};
+gen_inherited([Parent|Ps], Done0, Exported0) ->
+ #class{name=Class, methods=Ms} = get({class,Parent}),
+ case is_list(Exported0) of
+ false -> w(" %% From ~s ~n", [Class]);
+ true -> ignore
+ end,
+ {Done,Exported} = gen_inherited_ms(Ms, Class, Done0, gb_sets:empty(), Exported0),
+ gen_inherited(Ps, gb_sets:union(Done,Done0), Exported).
+
+gen_inherited_ms([[#method{name=Name,alias=A,params=Ps0,where=W,method_type=MT}|_]|R],
+ Class,Skip,Done, Exported)
+ when W =/= merged_c ->
+ case gb_sets:is_member(Name,Skip) of
+ false when MT =:= member, Exported =:= true ->
+ Ps = [patch_param(P,all) || P <- Ps0],
+ Opts = if W =:= erl_no_opt -> [];
+ true ->
+ [Opt || Opt = #param{def=Def,in=In, where=Where} <- Ps,
+ Def =/= none, In =/= false, Where =/= c]
+ end,
+ w("%% @hidden~n", []),
+ gen_function_clause(erl_func_name(Name,A),MT,Ps,Opts,[no_guards,name_only]),
+ w(" -> ~s:", [Class]),
+ gen_function_clause(erl_func_name(Name,A),MT,Ps,Opts,[no_guards,name_only]),
+ w(".~n", []),
+ gen_inherited_ms(R,Class, Skip, gb_sets:add(Name,Done), Exported);
+ false when MT =:= member, is_list(Exported) ->
+ {Args,Opts} = split_optional(Ps0),
+ OptLen = case Opts of
+ [] -> 0;
+ _ when W =:= erl_no_opt -> 0;
+ _ -> 1
+ end,
+ Export = erl_func_name(Name,A) ++ "/" ++ integer_to_list(length(Args) + OptLen),
+ gen_inherited_ms(R,Class,Skip, gb_sets:add(Name,Done), [Export|Exported]);
+ _ ->
+ gen_inherited_ms(R,Class, Skip, Done, Exported)
+ end;
+gen_inherited_ms([[_|Check]|R],Class,Skip, Done0,Exp) ->
+ gen_inherited_ms([Check|R],Class,Skip, Done0,Exp);
+gen_inherited_ms([[]|R],Class,Skip,Done0,Exp) ->
+ gen_inherited_ms(R,Class,Skip,Done0,Exp);
+gen_inherited_ms([], _, _Skip, Done,Exp) -> {Done,Exp}.
+
+
+%%%%%%%%%%%%%%%
+
+taylormade_func(Class, #method{name=Name, id=Id}) ->
+ {ok, Bin} = file:read_file(filename:join([wx_extra, Class ++".erl"])),
+ Str0 = binary_to_list(Bin),
+ {match, [Str1]} = re:run(Str0, "<<"++Name++"(.*)"++Name++">>",
+ [dotall, {capture, all_but_first, list}]),
+
+ w(Str1, ["?" ++ get_unique_name(Id)]),
+ ok.
+
+taylormade_export(Class, #method{name=Name}) ->
+ {ok, Bin} = file:read_file(filename:join([wx_extra, Class ++".erl"])),
+ Str0 = binary_to_list(Bin),
+ {match, [Str1]} = re:run(Str0, "<<EXPORT:"++Name++"(.*)"++Name++":EXPORT>>",
+ [dotall, {capture, all_but_first, list}]),
+ Str1.
+
+%%%%%%%%%%%%%%%
+
+arg_type_tests([P|Ps], Mid0) ->
+ case arg_type_test(P,"\n",Mid0) of
+ Mid0 ->
+ arg_type_tests(Ps, Mid0);
+ Mid -> %% Already checked the other args
+ Mid
+ end;
+arg_type_tests([],Mid) -> Mid.
+
+arg_type_test(#param{where=c}, _, Acc) ->
+ Acc;
+arg_type_test(#param{name=Name0,in=In,type=#type{base={class,T},single=true},def=none},
+ EOS,Acc) when In =/= false ->
+ Name = erl_arg_name(Name0),
+ w(" ?CLASS(~sT,~s),~s", [Name,T,EOS]),
+ Acc;
+arg_type_test(#param{name=Name0,in=In,type=#type{base={class,T}}, def=none},EOS,Acc)
+ when In =/= false ->
+ Name = erl_arg_name(Name0),
+ w(" [?CLASS(~sT,~s) || #wx_ref{type=~sT} <- ~s],~s", [Name,T,Name,Name,EOS]),
+ Acc;
+arg_type_test(#param{name=Name0,def=none,in=In,
+ type={merged,
+ M1, #type{base={class,T1},single=true},Ps1,
+ M2, #type{base={class,T2},single=true},Ps2}}, EOS, _Acc)
+ when In =/= false ->
+ Name = erl_arg_name(Name0),
+ Opname = Name++"OP",
+ w(" ~s = case ?CLASS_T(~sT,~s) of~n true ->\n ", [Opname,Name,T1]),
+ lists:foreach(fun(Param) -> arg_type_test(Param,"\n ", ignore) end,
+ element(1,split_optional(Ps1))),
+ w("?~s;~n",[get_unique_name(M1)]),
+ w(" _ -> ?CLASS(~sT,~s),\n ",[Name,T2]),
+ {Ps21,_} = split_optional(patchArgName(Ps2,Ps1)),
+ lists:foreach(fun(Param) -> arg_type_test(Param,"\n ", ignore) end,
+ Ps21),
+ w("?~s\n end,~s",[get_unique_name(M2),EOS]),
+ Opname;
+arg_type_test(#param{name=Name0, type=#type{base=eventType}}, EOS, Acc) ->
+ Name = erl_arg_name(Name0),
+ w(" ~sBin = list_to_binary([atom_to_list(~s)|[0]]),~s", [Name,Name,EOS]),
+ w(" ThisTypeBin = list_to_binary([atom_to_list(ThisT)|[0]]),~s", [EOS]),
+ Acc;
+arg_type_test(#param{name=Name0,def=none,type=#type{base={term,_}}}, EOS, Acc) ->
+ Name = erl_arg_name(Name0),
+ w(" wxe_util:send_bin(term_to_binary(~s)),~s", [Name,EOS]),
+ Acc;
+arg_type_test(#param{name=Name0,type=#type{base=binary}},EOS,Acc) ->
+ Name = erl_arg_name(Name0),
+ w(" wxe_util:send_bin(~s),~s", [Name,EOS]),
+ Acc;
+arg_type_test(#param{name=Name0,type=#type{name=Type,base=Base,single=Single}},EOS,Acc) ->
+ if
+ Type =:= "wxArtClient", Single =:= true ->
+ Name = erl_arg_name(Name0),
+ w(" ~s_UC = unicode:characters_to_binary([~s, $_, $C,0]),~s",
+ [Name,Name, EOS]);
+ Base =:= string orelse (Type =:= "wxChar" andalso Single =/= true) ->
+ Name = erl_arg_name(Name0),
+ w(" ~s_UC = unicode:characters_to_binary([~s,0]),~s", [Name,Name,EOS]);
+ Type =:= "wxArrayString" ->
+ Name = erl_arg_name(Name0),
+ w(" ~s_UCA = [unicode:characters_to_binary([~sTemp,0]) || ~s",
+ [Name,Name, EOS]),
+ w(" ~sTemp <- ~s],~s", [Name,Name,EOS]);
+ true -> %% Not a string
+ ignore
+ end,
+ Acc;
+arg_type_test(_,_,Acc) -> Acc.
+
+patchArgName([Param|R1], [#param{name=Name}|R2]) ->
+ [Param#param{name=Name}|patchArgName(R1,R2)];
+patchArgName([],[]) -> [].
+
+have_return_vals(void, Ps) ->
+ lists:any(fun(#param{in=In}) -> In =/= true end, Ps);
+have_return_vals(#type{}, _) -> true.
+
+gen_function_clause(Name0,MT,Ps,Optional,Variant) ->
+ PArg = fun(Arg) ->
+ case lists:member(name_only, Variant) of
+ true -> func_arg_name(Arg);
+ false ->
+ case lists:member(name_type, Variant) of
+ true ->
+ Name = func_arg_name(Arg),
+ case func_arg(Arg) of
+ Name -> Name;
+ Typed -> Name ++ "=" ++ Typed
+ end;
+ false ->
+ func_arg(Arg)
+ end
+ end
+ end,
+ Args = args(PArg, ",", Ps),
+ Name = case MT of constructor -> "new"; _ -> Name0 end,
+ w("~s(~s",[Name,Args]),
+ Opts = case Optional of
+ [] -> "";
+ empty_list when Args =:= [] -> "[]";
+ empty_list -> ", []";
+ _ when Args =:= [] -> "Options";
+ _ -> ", Options"
+ end,
+ w("~s)", [Opts]),
+ case lists:member(no_guards, Variant) of
+ true -> ok;
+ false ->
+ Guards = args(fun guard_test/1, ",", Ps),
+ if
+ Guards =:= [], Opts =:= "" -> w(" ->~n", []);
+ Guards =:= [] -> w("~n when is_list(Options) ->~n", []);
+ Opts =:= "" -> w("~n when ~s ->~n", [Guards]);
+ true -> w("~n when ~s,is_list(Options) ->~n", [Guards])
+ end
+ end.
+
+split_optional(Ps) ->
+ split_optional(Ps, [], []).
+split_optional([P=#param{def=Def,in=In, where=Where}|Ps], Standard, Opts)
+ when Def =/= none, In =/= false, Where =/= c ->
+ split_optional(Ps, Standard, [P|Opts]);
+split_optional([P=#param{def=Def,in=In, where=Where}|Ps], Standard, Opts)
+ when Def =:= none, In =/= false, Where =/= c ->
+ split_optional(Ps, [P|Standard], Opts);
+split_optional([_|Ps], Standard, Opts) ->
+ split_optional(Ps, Standard, Opts);
+split_optional([], Standard, Opts) ->
+ {reverse(Standard), reverse(Opts)}.
+
+patch_param(P=#param{type=#type{base=Tuple}}, all) when is_tuple(Tuple) ->
+ P#param{type={class,ignore}};
+patch_param(P=#param{type={merged,_,_,_,_,_,_}}, _) ->
+ P#param{type={class,ignore}};
+patch_param(P=#param{type=#type{base={class,_}}},_) ->
+ P#param{type={class,ignore}};
+patch_param(P=#param{type=#type{base={ref,_}}},_) ->
+ P#param{type={class,ignore}};
+patch_param(P,_) -> P.
+
+func_arg_name(#param{def=Def}) when Def =/= none -> skip;
+func_arg_name(#param{in=false}) -> skip;
+func_arg_name(#param{where=c}) -> skip;
+func_arg_name(#param{name=Name}) ->
+ erl_arg_name(Name).
+
+func_arg(#param{def=Def}) when Def =/= none -> skip;
+func_arg(#param{in=false}) -> skip;
+func_arg(#param{where=c}) -> skip;
+func_arg(#param{name=Name,type=#type{base=string}}) ->
+ erl_arg_name(Name);
+func_arg(#param{name=Name,type=#type{name="wxArrayString"}}) ->
+ erl_arg_name(Name);
+func_arg(#param{name=Name0,type=#type{base={class,_CN}, single=true}}) ->
+ Name = erl_arg_name(Name0),
+ "#wx_ref{type=" ++ Name ++ "T,ref=" ++ Name++"Ref}";
+func_arg(#param{name=Name0,type=#type{base={ref,CN}, single=true}}) ->
+ Name = erl_arg_name(Name0),
+ "#wx_ref{type=" ++ CN ++ ",ref=" ++ Name++"Ref}";
+func_arg(#param{name=Name0,type={merged,_,#type{base={class,_},single=true},_,
+ _, #type{base={class,_},single=true},_}}) ->
+ Name = erl_arg_name(Name0),
+ "#wx_ref{type=" ++ Name ++ "T,ref=" ++ Name++"Ref}";
+func_arg(#param{name=Name,type=#type{base={enum,_}}}) ->
+ erl_arg_name(Name);
+func_arg(#param{name=Name,type=#type{base={comp,"wxColour",_Tup}, single=true}}) ->
+ erl_arg_name(Name);
+func_arg(#param{name=Name,type=#type{base={comp,"wxDateTime",_Tup}, single=true}}) ->
+ erl_arg_name(Name);
+func_arg(#param{name=Name,type=#type{name="wxArtClient", single=true}}) ->
+ erl_arg_name(Name);
+func_arg(#param{name=Name,type=#type{base={comp,_,Tup}, single=true}}) ->
+ N = erl_arg_name(Name),
+ Doc = fun({_,V}) -> erl_arg_name(N)++V end,
+ "{" ++ args(Doc, ",", Tup) ++ "}";
+func_arg(#param{name=Name}) ->
+ erl_arg_name(Name).
+
+
+guard_test(#param{type=#type{base={class,_},single=true}}) -> skip;
+guard_test(#param{def=Def}) when Def =/= none -> skip;
+guard_test(#param{where=c}) -> skip;
+guard_test(#param{in=In}) when In == false -> skip;
+guard_test(#param{name=N, type=#type{base=string}}) ->
+ "is_list(" ++ erl_arg_name(N) ++")";
+guard_test(#param{name=N, type=#type{name="wxArtClient"}}) ->
+ "is_list(" ++ erl_arg_name(N) ++")";
+guard_test(#param{name=N, type=#type{name="wxArrayString"}}) ->
+ "is_list(" ++ erl_arg_name(N) ++")";
+guard_test(#param{name=Name,type=#type{single=Single}})
+ when Single =/= true->
+ "is_list(" ++ erl_arg_name(Name) ++ ")";
+guard_test(#param{name=N,type=#type{base=int}}) ->
+ "is_integer(" ++ erl_arg_name(N) ++ ")";
+guard_test(#param{name=N,type=#type{base=long}}) ->
+ "is_integer(" ++ erl_arg_name(N) ++ ")";
+guard_test(#param{name=N,type=#type{base=float}}) ->
+ "is_float(" ++ erl_arg_name(N) ++ ")";
+guard_test(#param{name=N,type=#type{base=double}}) ->
+ "is_float(" ++ erl_arg_name(N) ++ ")";
+guard_test(#param{name=N,type=#type{base=bool}}) ->
+ "is_boolean(" ++ erl_arg_name(N) ++ ")";
+guard_test(#param{name=N,type=#type{name="wxDateTime"}}) ->
+ "tuple_size(" ++ erl_arg_name(N) ++ ") =:= 2";
+guard_test(#param{name=N,type=#type{base=binary}}) ->
+ "is_binary(" ++ erl_arg_name(N) ++ ")";
+guard_test(#param{name=Name,type=#type{base={enum,_}}}) ->
+ "is_integer(" ++ erl_arg_name(Name) ++ ")";
+guard_test(#param{name=Name,type=#type{base=eventType}}) ->
+ "is_atom(" ++ erl_arg_name(Name) ++ ")";
+guard_test(#param{name=_N,type=#type{base={term,_}}}) ->
+ skip;
+guard_test(#param{name=_N,type=#type{base={ref,_}}}) ->
+ skip;
+guard_test(#param{name=_N,type=#type{base={class,_}}}) ->
+ skip;
+guard_test(#param{name=_N,type={merged,_,#type{base={class,_}},_,_,#type{},_}}) ->
+ skip;
+guard_test(#param{name=N,type=#type{base={comp,"wxColour",_Tup}}}) ->
+ "tuple_size(" ++ erl_arg_name(N) ++ ") =:= 3; tuple_size(" ++ erl_arg_name(N) ++ ") =:= 4";
+guard_test(#param{name=N,type=#type{base={comp,_,Tup}}}) ->
+ Doc = fun({int,V}) -> "is_integer("++erl_arg_name(N)++V ++")";
+ ({double,V}) -> "is_number("++erl_arg_name(N)++V ++")"
+ end,
+ args(Doc, ",", Tup);
+guard_test(#param{name=N,type={class,ignore}}) ->
+ "is_record(" ++ erl_arg_name(N)++ ", wx_ref)";
+guard_test(T) -> ?error({unknown_type,T}).
+
+gen_doc(_Class, [#method{method_type=destructor}]) -> skip;
+gen_doc(_Class,[#method{name=N,alias=A,params=Ps,type=T,where=erl_no_opt,method_type=MT}])->
+ w("%% @spec (~s~s) -> ~s~n",[doc_arg_types(Ps),"",doc_return_types(T,Ps)]),
+ w("%% @equiv ", []),
+ gen_function_clause(erl_func_name(N,A),MT,Ps,empty_list,[no_guards,name_only]);
+gen_doc(Class,[#method{name=N,params=Ps,type=T}])->
+ {_, Optional} = split_optional(Ps),
+ NonDef = [Arg || Arg = #param{def=Def,in=In, where=Where} <- Ps,
+ Def =:= none, In =/= false, Where =/= c],
+ OptsType = case Optional of
+ [] -> "";
+ _ when NonDef =:= [] -> "[Option]";
+ _ -> ", [Option]"
+ end,
+ w("%% @spec (~s~s) -> ~s~n",
+ [doc_arg_types(Ps),OptsType,doc_return_types(T,Ps)]),
+ doc_optional(Optional, normal),
+ DocEnum = doc_enum(T,Ps, normal),
+ case Class of
+ "utils" ->
+ w("%% @doc See <a href=\"http://www.wxwidgets.org/manuals/stable/wx_miscellany.html#~s\">"
+ "external documentation</a>.~n",
+ [lowercase_all(N)]);
+ _ ->
+ w("%% @doc See <a href=\"http://www.wxwidgets.org/manuals/stable/wx_~s.html#~s~s\">"
+ "external documentation</a>.~n",
+ [lowercase_all(Class),lowercase_all(Class),lowercase_all(N)])
+ end,
+ doc_enum_desc(DocEnum);
+gen_doc(Class, Cs = [#method{name=N, alias=A,method_type=MT}|_]) ->
+ GetRet = fun(#method{params=Ps,type=T}) ->
+ doc_return_types(T,Ps)
+ end,
+ GetArgs = fun(#method{params=Ps, where=Where}) ->
+ Opt = case Where of
+ erl_no_opt -> [];
+ _ ->
+ case split_optional(Ps) of
+ {_, []} -> [];
+ _ -> ["[Option]"]
+ end
+ end,
+ [doc_arg_type(P) ||
+ P=#param{in=In,def=none,where=W} <- Ps,
+ In =/= false, W =/= c] ++ Opt
+ end,
+ Args = zip(lists:map(GetArgs, Cs)),
+ Ret = lists:map(GetRet, Cs),
+ w("%% @spec (~s) -> ~s~n",[args(fun doc_arg/1,",",Args),doc_ret(Ret)]),
+ case Class of
+ "utils" ->
+ w("%% @doc See <a href=\"http://www.wxwidgets.org/manuals/stable/wx_miscellany.html#~s\">"
+ "external documentation</a>.~n",
+ [lowercase_all(N)]);
+ _ ->
+ w("%% @doc See <a href=\"http://www.wxwidgets.org/manuals/stable/wx_~s.html#~s~s\">"
+ "external documentation</a>.~n",
+ [lowercase_all(Class),lowercase_all(Class),lowercase_all(N)])
+ end,
+ Name = case MT of constructor -> "new"; _ -> erl_func_name(N,A) end,
+ w("%% <br /> Alternatives: ~n",[]),
+ [gen_doc2(Name, Clause) || Clause <- Cs],
+ ok.
+
+gen_doc2(Name,#method{params=Ps,where=erl_no_opt,method_type=MT}) ->
+ w("%% <p><c>~n",[]),
+ w("%% ~s(~s) -> ", [Name,doc_arg_types(Ps)]),
+ gen_function_clause(Name,MT,Ps,empty_list,[no_guards,name_only]),
+ w(" </c></p>~n",[]);
+gen_doc2(Name,#method{params=Ps,type=T}) ->
+ {NonDef, Optional} = split_optional(Ps),
+ OptsType = case Optional of
+ [] -> "";
+ _ when NonDef =:= [] -> "[Option]";
+ _ -> ", [Option]"
+ end,
+ w("%% <p><c>~n",[]),
+ w("%% ~s(~s~s) -> ~s </c>~n",
+ [Name,doc_arg_types(Ps),OptsType,doc_return_types(T,Ps)]),
+ doc_optional(Optional, xhtml),
+ DocEnum = doc_enum(T,Ps, xhtml),
+ doc_enum_desc(DocEnum),
+ w("%% </p>~n",[]).
+
+doc_arg(ArgList) ->
+ case all_eq(ArgList) of
+ true -> hd(ArgList);
+ false ->
+ Get = fun(Str) ->
+ [_Name|Types] = string:tokens(Str, ":"),
+ case Types of
+ [Type] -> Type;
+ _ ->
+ "term()"
+ end
+ end,
+ Args0 = lists:map(Get, ArgList),
+ Args = unique(Args0, []),
+ "X::" ++ args(fun(A) -> A end, "|", Args)
+ end.
+
+doc_ret(ArgList) ->
+ case all_eq(ArgList) of
+ true -> hd(ArgList);
+ false ->
+ args(fun(A) -> A end, "|", ArgList)
+ end.
+
+unique([], U) -> reverse(U);
+unique([H|R], U) ->
+ case lists:member(H,U) of
+ false -> unique(R,[H|U]);
+ true -> unique(R,U)
+ end.
+
+all_eq([H|R]) -> all_eq(R,H).
+
+all_eq([H|R],H) -> all_eq(R,H);
+all_eq([],_) -> true;
+all_eq(_,_) -> false.
+
+zip(List) ->
+ zip(List, [], [], []).
+
+zip([[F|L1]|List], Rest, AccL, Acc) ->
+ zip(List, [L1|Rest], [F|AccL], Acc);
+zip(Empty, Rest, AccL, Acc) ->
+ true = empty(Empty),
+ case empty(Rest) andalso empty(AccL) of
+ true -> reverse(Acc);
+ false ->
+ zip(reverse(Rest), [], [], [reverse(AccL)|Acc])
+ end.
+
+empty([[]|R]) -> empty(R);
+empty([]) -> true;
+empty(_) -> false.
+
+doc_arg_types(Ps0) ->
+ Ps = [P || P=#param{in=In, where=Where} <- Ps0,In =/= false, Where =/= c],
+ args(fun doc_arg_type/1, ", ", Ps).
+doc_arg_type(#param{name=Name,def=none,type=T}) ->
+ erl_arg_name(Name) ++ "::" ++ doc_arg_type2(T);
+doc_arg_type(#param{name=Name,in=false,type=T}) ->
+ erl_arg_name(Name) ++ "::" ++ doc_arg_type2(T);
+doc_arg_type(_) -> skip.
+
+doc_arg_type2(T=#type{single=Single}) when Single =:= array; Single =:= list ->
+ "[" ++ doc_arg_type3(T) ++ "]";
+doc_arg_type2(T) ->
+ doc_arg_type3(T).
+
+doc_arg_type3(#type{base=string}) -> "string()";
+doc_arg_type3(#type{name="wxChar", single=S}) when S =/= true -> "string()";
+doc_arg_type3(#type{name="wxArrayString"}) -> "[string()]";
+doc_arg_type3(#type{name="wxDateTime"}) -> "wx:datetime()";
+doc_arg_type3(#type{name="wxArtClient"}) -> "string()";
+doc_arg_type3(#type{base=int}) -> "integer()";
+doc_arg_type3(#type{base=long}) -> "integer()";
+doc_arg_type3(#type{base=bool}) -> "bool()";
+doc_arg_type3(#type{base=float}) -> "float()";
+doc_arg_type3(#type{base=double}) -> "float()";
+doc_arg_type3(#type{base=binary}) -> "binary()";
+doc_arg_type3(#type{base={binary,_}}) -> "binary()";
+doc_arg_type3(#type{base=eventType}) -> "atom()";
+doc_arg_type3(#type{base={ref,N}}) -> N++"()";
+doc_arg_type3(#type{base={term,_N}}) -> "term()";
+doc_arg_type3(T=#type{base={class,N}}) ->
+ check_class(T),
+ case get(current_class) of
+ N -> N ++ "()";
+ _ -> N++":" ++ N++"()"
+ end;
+doc_arg_type3({merged,_,T1=#type{base={class,N1}},_,_,T2=#type{base={class,N2}},_}) ->
+ check_class(T1),
+ check_class(T2),
+ Curr = get(current_class),
+ if
+ N1 =:= Curr, N2 =:= Curr -> N1++"() | "++ N2++"()";
+ N1 =:= Curr -> N1++"() | "++ N2++":" ++ N2++"()";
+ N2 =:= Curr -> N1++":" ++ N1++"() | "++ N2++"()";
+ true ->
+ N1++":" ++ N1++"() | "++ N2++":" ++ N2++"()"
+ end;
+doc_arg_type3(#type{base={enum,{_,N}}}) -> uppercase(N);
+doc_arg_type3(#type{base={enum,N}}) -> uppercase(N);
+doc_arg_type3(#type{base={comp,"wxColour",_Tup}}) ->
+ "wx:colour()";
+doc_arg_type3(#type{base={comp,_,{record,Name}}}) ->
+ "wx:" ++ atom_to_list(Name) ++ "()";
+doc_arg_type3(#type{base={comp,_,Tup}}) ->
+ Doc = fun({int,V}) -> V ++ "::integer()";
+ ({double,V}) -> V ++ "::float()"
+ end,
+ "{" ++ args(Doc, ",", Tup) ++ "}";
+doc_arg_type3(T) -> ?error({unknown_type,T}).
+
+doc_return_types(T, Ps) ->
+ doc_return_types2(T, [P || P=#param{in=In} <- Ps,In =/= true]).
+doc_return_types2(void, []) -> "ok";
+doc_return_types2(void, [#param{type=T}]) -> doc_arg_type2(T);
+doc_return_types2(T, []) -> doc_arg_type2(T);
+doc_return_types2(void, Ps) ->
+ "{" ++ args(fun doc_arg_type/1,",",Ps) ++ "}";
+doc_return_types2(T, Ps) ->
+ "{" ++ doc_arg_type2(T) ++ "," ++ args(fun doc_arg_type/1,",",Ps) ++ "}".
+
+break(xhtml) -> "<br />";
+break(_) -> "".
+
+doc_optional([],_) -> ok;
+doc_optional(Opts,Type) ->
+ w("%%~s Option = ~s~n", [break(Type),args(fun doc_optional2/1, " | ", Opts)]).
+
+doc_optional2(#param{name=Name, def=_Def, type=T}) ->
+ "{" ++ erl_option_name(Name) ++ ", " ++ doc_arg_type2(T) ++ "}".
+
+doc_enum(#type{base={enum,Enum}},Ps,Break) ->
+ [doc_enum_type(Enum,Break) |
+ [doc_enum_type(Type,Break) || #param{type=#type{base={enum,Type}}} <- Ps]];
+doc_enum(_,Ps,Break) ->
+ [doc_enum_type(Type,Break) || #param{type=#type{base={enum,Type}}} <- Ps].
+
+doc_enum_type(Type,Break) ->
+ {Enum0, #enum{vals=Vals}} = wx_gen:get_enum(Type),
+ case Enum0 of {_, Enum} -> Enum; Enum -> Enum end,
+ Consts = get(consts),
+ Format = fun({Name,_What}) ->
+ #const{name=Name} = gb_trees:get(Name, Consts),
+ "?" ++ enum_name(Name)
+ end,
+ Vs = args(Format, " | ", Vals),
+ w("%%~s ~s = integer()~n", [break(Break),uppercase(Enum)]),
+ {uppercase(Enum),Vs}.
+
+doc_enum_desc([]) -> ok;
+doc_enum_desc([{Enum,Vs}|R]) ->
+ w("%%<br /> ~s is one of ~s~n", [Enum,Vs]),
+ doc_enum_desc(R).
+
+%% Misc functions prefixed with wx
+erl_func_name("wx" ++ Name, undefined) -> check_name(lowercase(Name));
+erl_func_name(Name, undefined) -> check_name(lowercase(Name));
+erl_func_name(_, Alias) -> check_name(lowercase(Alias)).
+
+erl_option_name(Name) -> lowercase(Name).
+erl_arg_name(Name) -> uppercase(Name).
+
+check_name("destroy") -> "'Destroy'";
+check_name("xor") -> "'Xor'";
+check_name("~" ++ _Name) -> "destroy";
+check_name(Name) -> Name.
+
+marshal_opts([], _,_) -> ""; %% No opts skip this!
+marshal_opts(Opts, Align, Args) ->
+ w(" MOpts = fun", []),
+ marshal_opts1(Opts,1),
+ w(";~n (BadOpt, _) -> erlang:error({badoption, BadOpt}) end,~n", []),
+ w(" BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),~n", []),
+ {Str, _} = align(64, Align, "BinOpt/binary"),
+ case Args of
+ [] -> Str; % All Args are optional
+ _ -> ", " ++ Str
+ end.
+
+marshal_opts1([P],N) ->
+ marshal_opt(P,N);
+marshal_opts1([P|R],N) ->
+ marshal_opt(P,N),
+ w(";~n ", []),
+ marshal_opts1(R,N+1).
+
+marshal_opt(P0=#param{name=Name,type=Type},N) ->
+ P = P0#param{def=none},
+ {Arg,Align} = marshal_arg(Type,erl_arg_name(Name),1),
+ AStr = if Align =:= 0 -> "";
+ Align =:= 1 -> ",0:32"
+ end,
+ w("({~s, ~s}, Acc) -> ", [erl_option_name(Name), func_arg(P)]),
+ arg_type_test(P,"",[]),
+ case Arg of
+ skip ->
+ w("[<<~p:32/?UI~s>>|Acc]", [N, AStr]);
+ _ ->
+ w("[<<~p:32/?UI,~s~s>>|Acc]", [N, Arg,AStr])
+ end.
+marshal_args(Ps) ->
+ marshal_args(Ps, [], 0).
+
+marshal_args([#param{where=erl}|Ps], Margs, Align) ->
+ marshal_args(Ps, Margs, Align);
+marshal_args([#param{name=_N,where=c}|Ps], Margs, Align) ->
+ %% io:format("~p:~p: skip ~p~n",[get(current_class),get(current_func),_N]),
+ marshal_args(Ps, Margs, Align);
+marshal_args([#param{in=false}|Ps], Margs, Align) ->
+ marshal_args(Ps, Margs, Align);
+marshal_args([#param{def=Def}|Ps], Margs, Align) when Def =/= none ->
+ marshal_args(Ps, Margs, Align);
+marshal_args([#param{name=Name, type=Type}|Ps], Margs, Align0) ->
+ {Arg,Align} = marshal_arg(Type,erl_arg_name(Name),Align0),
+ marshal_args(Ps, [Arg|Margs], Align);
+marshal_args([],Margs, Align) ->
+ {args(fun(Str) -> Str end, ",", reverse(Margs)), Align}.
+
+marshal_arg(#type{base={class,_}, single=true}, Name, Align) ->
+ align(32, Align, Name ++ "Ref:32/?UI");
+marshal_arg({merged,_,#type{base={class,_},single=true},_,_,_,_},Name,Align) ->
+ align(32, Align, Name ++ "Ref:32/?UI");
+marshal_arg(#type{base={ref,_}, single=true}, Name, Align) ->
+ align(32, Align, Name ++ "Ref:32/?UI");
+marshal_arg(#type{single=true,base=long}, Name, Align) ->
+ align(64, Align, Name ++ ":64/?UI");
+marshal_arg(#type{single=true,base=float}, Name, Align) ->
+ align(32, Align, Name ++ ":32/?F");
+marshal_arg(#type{single=true,base=double}, Name, Align) ->
+ align(64, Align, Name ++ ":64/?F");
+marshal_arg(#type{single=true,base=int}, Name, Align) ->
+ align(32, Align, Name ++ ":32/?UI");
+marshal_arg(#type{single=true,base={enum,_Enum}}, Name, Align) ->
+ align(32, Align, Name ++ ":32/?UI");
+
+marshal_arg(#type{single=true,base=bool}, Name, Align) ->
+ align(32, Align, "(wxe_util:from_bool(" ++ Name ++ ")):32/?UI");
+marshal_arg(#type{name="wxChar", single=Single}, Name, Align0)
+ when Single =/= true ->
+ {Str,Align} =
+ align(32,Align0, "(byte_size("++Name++"_UC)):32/?UI,(" ++ Name ++ "_UC)/binary"),
+ MsgSize = "(" ++ integer_to_list(Align*4)++"+byte_size("++Name++"_UC))",
+ {Str++", 0:(((8- (" ++ MsgSize ++" band 16#7)) band 16#7))/unit:8",0};
+marshal_arg(#type{base=string}, Name, Align0) ->
+ {Str,Align} =
+ align(32,Align0, "(byte_size("++Name++"_UC)):32/?UI,(" ++ Name ++ "_UC)/binary"),
+ MsgSize = "(" ++ integer_to_list(Align*4)++"+byte_size("++Name++"_UC))",
+ {Str++", 0:(((8- (" ++ MsgSize ++" band 16#7)) band 16#7))/unit:8",0};
+marshal_arg(#type{name="wxArrayString"}, Name, Align0) ->
+ InnerBin = "<<(byte_size(UC_Str)):32/?UI, UC_Str/binary>>",
+ Outer = "(<< " ++ InnerBin ++ "|| UC_Str <- "++ Name ++"_UCA>>)/binary",
+ Str0 = "(length("++Name++"_UCA)):32/?UI, " ++ Outer,
+ {Str,Align} = align(32,Align0,Str0),
+ MsgSize = "("++integer_to_list(Align*4) ++
+ " + lists:sum([byte_size(S)+4||S<-" ++ Name ++"_UCA]))",
+ AStr = ", 0:(((8- (" ++ MsgSize ++" band 16#7)) band 16#7))/unit:8",
+ {Str ++ AStr, 0};
+marshal_arg(#type{single=true,base={comp,"wxColour",_Comp}}, Name, Align0) ->
+ Str = "(wxe_util:colour_bin(" ++ Name ++ ")):16/binary",
+ {Str,Align0};
+marshal_arg(#type{single=true,base={comp,"wxDateTime",_Comp}}, Name, Align) ->
+ {"(wxe_util:datetime_bin(" ++ Name ++ ")):24/binary", Align};
+marshal_arg(#type{single=true,base={comp,_,Comp}}, Name, Align0) ->
+ case hd(Comp) of
+ {int,_} ->
+ A = [Name++Spec++":32/?UI" || {int,Spec} <- Comp],
+ Str = args(fun(Str) -> Str end, ",", A),
+ {Str,(Align0 + length(Comp)) rem 2};
+ {double,_} ->
+ A = [Name++Spec++":64/float" || {double,Spec} <- Comp],
+ Str = args(fun(Str) -> Str end, ",", A),
+ align(64,Align0,Str)
+ end;
+marshal_arg(#type{base={term,_}}, _Name, Align0) ->
+ {skip,Align0};
+marshal_arg(#type{base=binary}, _Name, Align0) ->
+ {skip,Align0};
+marshal_arg(#type{base=Base, single=Single}, Name, Align0)
+ when Single =/= true ->
+ case Base of
+ int ->
+ Str0 = "(length("++Name++")):32/?UI,\n"
+ " (<< <<C:32/?I>> || C <- "++Name++">>)/binary",
+ {Str,Align} = align(32,Align0, Str0),
+ {Str ++ ", 0:((("++integer_to_list(Align)++"+length("++Name++ ")) rem 2)*32)", 0};
+ {ObjRef,_} when ObjRef =:= class; ObjRef =:= ref ->
+ Str0 = "(length("++Name++")):32/?UI,",
+ Str1 = "\n (<< <<(C#wx_ref.ref):32/?UI>> || C <- "++Name++">>)/binary",
+ {Str2,Align} = align(32, Align0, Str1),
+ AlignStr = ", 0:((("++integer_to_list(Align)++"+length("++Name++ ")) rem 2)*32)",
+ {Str0 ++ Str2 ++ AlignStr, 0};
+ {comp, "wxPoint", _} ->
+ Str0 = "(length("++Name++")):32/?UI,\n"
+ " (<< <<X:32/?I,Y:32/?I>> || {X,Y} <- "++Name++">>)/binary",
+ align(32,Align0, Str0);
+ double ->
+ Str0 = "(length("++Name++")):32/?UI,\n",
+ Str1 = " (<< <<C:64/float>> || C <- "++Name++">>)/binary",
+ {Str,_Align} = align(64,Align0+1, Str1),
+ {Str0 ++ Str, 0};
+ _ ->
+ ?error({unhandled_array_type, Base})
+ end;
+marshal_arg(T=#type{name=_wxString}, Name, _Align) ->
+ ?error({unhandled_type, {Name,T}}).
+
+
+align(32, 0, Str) -> {Str, 1};
+align(32, 1, Str) -> {Str, 0};
+align(64, 0, Str) -> {Str, 0};
+align(64, 1, Str) -> {"0:32," ++ Str,0};
+align(Sz, W, Str) -> align(Sz, W rem 2, Str).
+
+enum_name(Name) ->
+ case string:tokens(Name, ":") of
+ [Name] -> Name;
+ [C,N] -> C ++ "_" ++ N
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+gen_enums_ints() ->
+ %% open_write("../include/wx.hrl"), opened in gen_event_recs
+ w("~n%% Hardcoded Records ~n", []),
+ w("-record(wxMouseState, {x, y, %% integer() ~n"
+ " leftDown, middleDown, rightDown, %% bool() ~n"
+ " controlDown, shiftDown, altDown, metaDown, cmdDown %% bool()~n"
+ " }).~n", []),
+ w("-record(wxHtmlLinkInfo, { ~n"
+ " href, target %% string() ~n"
+ " }).~n", []),
+ w("~n%% Hardcoded Defines ~n", []),
+ Enums = [E || E = {{enum,_},#enum{as_atom=false}} <- get()],
+ w("-define(wxDefaultSize, {-1,-1}).~n", []),
+ w("-define(wxDefaultPosition, {-1,-1}).~n", []),
+ w("~n%% Global Variables ~n", []),
+ [w("-define(~s, wxe_util:get_const(~s)).~n", [Gvar, Gvar]) ||
+ {Gvar,_,_Id} <- get(gvars)],
+ w("~n%% Enum and defines ~n", []),
+ foldl(fun({{enum,Type},Enum= #enum{as_atom=false}}, Done) ->
+ build_enum_ints(Type,Enum,Done);
+ (_,Done) -> Done
+ end, gb_sets:empty(), lists:sort(Enums)),
+ close().
+
+build_enum_ints(Type,#enum{vals=Vals},Done) ->
+ case Type of
+ [$@|_] -> ok; % anonymous
+ {Class,[$@|_]} when Vals =/= [] -> w("% From class ~s ~n", [Class]);
+ {Class,Enum} when Vals =/= [] -> w("% From ~s::~s ~n", [Class,Enum]);
+ _ when Vals =/= [] -> w("% Type ~s ~n", [Type]);
+ _ -> ok
+ end,
+
+ Format = fun(#const{name=Name,val=Value,is_const=true}) when is_integer(Value) ->
+ w("-define(~s, ~p).~n", [enum_name(Name),Value]);
+ (#const{name=Name,val=Value,is_const=false}) when is_integer(Value) ->
+ w("-define(~s, wxe_util:get_const(~s)).~n", [enum_name(Name),enum_name(Name)]);
+ (#const{name=Name,val={Str,0}}) ->
+ case string:tokens(Str, " |()") of
+ [Token] ->
+ w("-define(~s, ?~s).~n", [enum_name(Name),Token]);
+ Tokens ->
+ Def = args(fun(T) -> [$?|T] end, " bor ", Tokens),
+ w("-define(~s, (~s)).~n", [enum_name(Name),Def])
+ end;
+ (#const{name=Name,val={Str,N}}) ->
+ case string:tokens(Str, " |()") of
+ [Token] ->
+ w("-define(~s, (?~s+~p)).~n", [enum_name(Name),Token,N])
+ end
+ end,
+ Consts = get(consts),
+ Write = fun({Name,_What}, Skip) ->
+ case gb_sets:is_member(Name,Skip) of
+ true ->
+ Skip;
+ false ->
+ case gb_trees:lookup(Name, Consts) of
+ {value, Const} ->
+ Format(Const),
+ gb_sets:add(Name,Skip);
+ none -> Skip
+ end
+ end
+ end,
+ lists:foldl(Write, Done, Vals).
+
+gen_event_recs() ->
+ open_write("../include/wx.hrl"),
+ erl_copyright(),
+ w("", []),
+ w("%% This file is generated DO NOT EDIT~n~n", []),
+ w("%% All event messages are encapsulated in a wx record ~n"
+ "%% they contain the widget id and a specialized event record.~n"
+ "%% Each event record may be sent for one or more event types.~n"
+ "%% The mapping to wxWidgets is one record per class.~n~n",[]),
+ w("%% @type wx() = #wx{id=integer(), obj=wx:wxObject(), userData=term(), event=Rec}. Rec is a event record.~n",[]),
+ w("-record(wx, {id, %% Integer Identity of object.~n"
+ " obj, %% Object reference that was used in the connect call.~n"
+ " userData, %% User data specified in the connect call.~n"
+ " event}).%% The event record ~n~n",[]),
+ w("%% Here comes the definitions of all event records.~n"
+ "%% they contain the event type and possible some extra information.~n~n",[]),
+ Types = [build_event_rec(C) || {_,C=#class{event=Evs}} <- get(), Evs =/= false],
+ w("%% @type wxEventType() = ~s.~n",
+ [args(fun(Ev) -> Ev end, " | ", lists:sort(lists:append(Types)))]),
+ %% close(), closed in gen_enums_ints
+ ok.
+
+find_inherited_attr(Param = {PName,_}, Name) ->
+ #class{parent=Parent, attributes=Attrs} = get({class, Name}),
+ case lists:keysearch(atom_to_list(PName), #param.name, Attrs) of
+ {value, P=#param{}} ->
+ P;
+ _ ->
+ find_inherited_attr(Param, Parent)
+ end.
+
+filter_attrs(#class{name=Name, parent=Parent,attributes=Attrs}) ->
+ Attr1 = lists:foldl(fun(#param{acc=skip},Acc) -> Acc;
+ (P=#param{prot=public},Acc) -> [P|Acc];
+ (#param{acc=undefined},Acc) -> Acc;
+ ({inherited, PName},Acc) ->
+ case find_inherited_attr(PName, Parent) of
+ undefined ->
+ io:format("~p:~p: Missing Event Attr ~p in ~p~n",
+ [?MODULE,?LINE, PName, Name]),
+ Acc;
+ P ->
+ [P|Acc]
+ end;
+ (P, Acc) -> [P|Acc]
+ end, [], Attrs),
+ lists:reverse(Attr1).
+
+build_event_rec(Class=#class{name=Name, event=Evs}) ->
+ EvTypes = [event_type_name(Ev) || Ev <- Evs],
+ Str = args(fun(Ev) -> "<em>"++Ev++"</em>" end, ", ", EvTypes),
+ Attr = filter_attrs(Class),
+ Rec = event_rec_name(Name),
+ GetName = fun(#param{name=N}) ->event_attr_name(N) end,
+ GetType = fun(#param{name=N,type=T}) ->
+ event_attr_name(N) ++ "=" ++ doc_arg_type2(T)
+ end,
+ case Attr =:= [] of
+ true ->
+ w("%% @type ~s() = #~s{type=wxEventType()}.~n", [Rec,Rec]),
+ w("%% <dl><dt>EventType:</dt> <dd>~s</dd></dl>~n",[Str]),
+%% case is_command_event(Name) of
+%% true -> w("%% This event skips other event handlers.~n",[]);
+%% false -> w("%% This event will be handled by other handlers~n",[])
+%% end,
+ w("%% Callback event: {@link ~s}~n", [Name]),
+ w("-record(~s, {type}). ~n~n", [Rec]);
+ false ->
+ w("%% @type ~s() = #~s{type=wxEventType(),~s}.~n",
+ [Rec,Rec,args(GetType,",",Attr)]),
+ w("%% <dl><dt>EventType:</dt> <dd>~s</dd></dl>~n",[Str]),
+%% case is_command_event(Name) of
+%% true -> w("%% This event skips other event handlers.~n",[]);
+%% false -> w("%% This event will be handled by other handlers~n",[])
+%% end,
+ w("%% Callback event: {@link ~s}~n", [Name]),
+ w("-record(~s,{type, ~s}). ~n~n", [Rec,args(GetName,",",Attr)])
+ end,
+ EvTypes.
+
+is_command_event(Name) ->
+ case lists:member("wxCommandEvent", parents(Name)) of
+ true -> true;
+ false -> false
+ end.
+
+event_rec_name(Name0 = "wx" ++ _) ->
+ "tnevE" ++ Name1 = reverse(Name0),
+ reverse(Name1).
+
+event_type_name({EvN,_,_}) -> event_type_name(EvN);
+event_type_name({EvN,_}) -> event_type_name(EvN);
+event_type_name(EvN) ->
+ "wxEVT_" ++ Ev = atom_to_list(EvN),
+ lowercase_all(Ev).
+
+event_attr_name("m_" ++ Attr) ->
+ lowercase(Attr);
+event_attr_name(Attr) ->
+ lowercase(Attr).
+
+
+gen_funcnames() ->
+ open_write("../src/gen/wxe_debug.hrl"),
+ erl_copyright(),
+ w("%% This file is generated DO NOT EDIT~n~n", []),
+ w("wxdebug_table() -> ~n[~n", []),
+ w(" {0, {wx, internal_batch_start, 0}},~n", []),
+ w(" {1, {wx, internal_batch_end, 0}},~n", []),
+ w(" {4, {wxObject, internal_destroy, 1}},~n", []),
+ Ns = get_unique_names(),
+ [w(" {~p, {~s, ~s, ~p}},~n", [Id,Class,erl_func_name(Name,undefined),A]) || {Class,Name,A,Id} <- Ns],
+ w(" {-1, {mod, func, -1}}~n",[]),
+ w("].~n~n", []),
+ close(),
+ open_write("../src/gen/wxe_funcs.hrl"),
+ erl_copyright(),
+ w("%% This file is generated DO NOT EDIT~n~n", []),
+ w("%% We define each id so we don't get huge diffs when adding new funcs/classes~n~n",[]),
+ [w("-define(~s_~s, ~p).~n", [Class,Name,Id]) || {Class,Name,_,Id} <- Ns],
+ close().
+
+get_unique_name(ID) when is_integer(ID) ->
+ Tree = get(unique_names),
+ {Class,Name, _,_} = gb_trees:get(ID, Tree),
+ Class ++ "_" ++ Name.
+
+get_unique_names() ->
+ Tree = get(unique_names),
+ gb_trees:values(Tree).
+
+gen_unique_names(Defs) ->
+ Names = [ unique_names(Ms, Class) || #class{name=Class, methods=Ms} <- Defs],
+ Data = [{Id, Struct} || Struct = {_,_,_,Id} <- lists:append(Names)],
+ Tree = gb_trees:from_orddict(lists:sort(Data)),
+ put(unique_names, Tree).
+
+unique_names(Ms0, Class) ->
+ Ms1 = [M || M = #method{where = W} <- lists:append(Ms0),
+ W =/= erl_no_opt],
+ Ms2 = lists:keysort(#method.name, Ms1),
+ Ms = split_list(fun(#method{name=N}, M) -> {N =:= M, N} end, undefined, Ms2),
+ unique_names2(Ms,Class).
+%% by Names
+unique_names2([[#method{id=Id, name=Method,alias=Alias, max_arity=A}]|Ms], Class) ->
+ [{Class,uname(alias(Method,Alias),Class),A,Id} | unique_names2(Ms,Class)];
+unique_names2([Ms0|RMs], Class) ->
+ Split = fun(#method{max_arity=A}, P) -> {A =:= P, A} end,
+ Ms = split_list(Split, 0, Ms0),
+ unique_names3(Ms, Class) ++ unique_names2(RMs, Class);
+unique_names2([], _Class) -> [].
+%% by Arity
+unique_names3([[#method{id=Id, name=Method,alias=Alias, max_arity=A}]|Ms], Class) ->
+ [{Class,uname(alias(Method,Alias),Class) ++ "_" ++ integer_to_list(A),A,Id} | unique_names3(Ms,Class)];
+unique_names3([Ms0|RMs], Class) ->
+ unique_names4(Ms0, 0, Class) ++ unique_names3(RMs, Class);
+unique_names3([], _Class) -> [].
+
+unique_names4([#method{id=Id, name=Method,alias=Alias, max_arity=A}|Ms], C, Class) ->
+ [{Class,uname(alias(Method,Alias),Class) ++ "_" ++ integer_to_list(A) ++ "_" ++ integer_to_list(C),A,Id}
+ | unique_names4(Ms,C+1,Class)];
+unique_names4([], _, _Class) -> [].
+
+alias(Method, undefined) -> Method;
+alias(_, Alias) -> Alias.
+
+uname(Class,Class) -> "new";
+uname([$~ | _], _ ) -> "destruct";
+uname(Name, _) -> Name.
+
+split_list(F, Keep, List) ->
+ split_list(F, Keep, List, []).
+
+split_list(F, Keep, [M|Ms], Acc) ->
+ case F(M,Keep) of
+ {true, Test} ->
+ split_list(F, Test, Ms, [M|Acc]);
+ {false, Test} when Acc =:= [] ->
+ split_list(F, Test, Ms, [M]);
+ {false, Test} ->
+ [lists:reverse(Acc)|split_list(F, Test, Ms, [M])]
+ end;
+split_list(_, _, [], []) -> [];
+split_list(_, _, [], Acc) -> [lists:reverse(Acc)].
+
+
diff --git a/lib/wx/api_gen/wx_xml/.gitignore b/lib/wx/api_gen/wx_xml/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/wx/api_gen/wx_xml/.gitignore
diff --git a/lib/wx/api_gen/wxapi.conf b/lib/wx/api_gen/wxapi.conf
new file mode 100644
index 0000000000..df154f0125
--- /dev/null
+++ b/lib/wx/api_gen/wxapi.conf
@@ -0,0 +1,1777 @@
+%% -*- erlang -*-
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%
+%% Api defs file, defines the classes and members we want.
+
+%% {class,wxObject,Options,[Function|{Func,Opt}]}.
+%% {enum, Type, SkipPart}
+
+{const_skip, [wxGenericFindReplaceDialog]}.
+{not_const, [wxHAS_INT64,wxBYTE_ORDER,wxRETAINED,
+ wxFONTENCODING_UTF32,wxFONTENCODING_UTF16,
+ wxDEFAULT_CONTROL_BORDER,wxMOD_CMD,
+ wxMAJOR_VERSION, wxMINOR_VERSION,
+ wxRELEASE_NUMBER,wxSUBRELEASE_NUMBER,wxBETA_NUMBER
+ ]}.
+
+{gvars,
+ [
+ {wxITALIC_FONT, wxFont},
+ {wxNORMAL_FONT, wxFont},
+ {wxSMALL_FONT, wxFont},
+ {wxSWISS_FONT, wxFont},
+
+ {wxBLACK_DASHED_PEN, wxPen},
+ {wxBLACK_PEN, wxPen},
+ {wxCYAN_PEN, wxPen},
+ {wxGREEN_PEN, wxPen},
+ {wxGREY_PEN, wxPen},
+ {wxLIGHT_GREY_PEN, wxPen},
+ {wxMEDIUM_GREY_PEN, wxPen},
+ {wxRED_PEN, wxPen},
+ {wxTRANSPARENT_PEN, wxPen},
+ {wxWHITE_PEN, wxPen},
+
+ {wxBLACK_BRUSH, wxBrush},
+ {wxBLUE_BRUSH, wxBrush},
+ {wxCYAN_BRUSH, wxBrush},
+ {wxGREEN_BRUSH, wxBrush},
+ {wxGREY_BRUSH, wxBrush},
+ {wxLIGHT_GREY_BRUSH, wxBrush},
+ {wxMEDIUM_GREY_BRUSH, wxBrush},
+ {wxRED_BRUSH, wxBrush},
+ {wxTRANSPARENT_BRUSH, wxBrush},
+ {wxWHITE_BRUSH, wxBrush},
+
+ {wxCROSS_CURSOR, wxCursor},
+ {wxHOURGLASS_CURSOR, wxCursor},
+ {wxSTANDARD_CURSOR, wxCursor},
+
+ {wxBLACK, wxColour},
+ {wxBLUE, wxColour},
+ {wxCYAN, wxColour},
+ {wxGREEN, wxColour},
+ {wxLIGHT_GREY, wxColour},
+ {wxRED, wxColour},
+ {wxWHITE, wxColour},
+
+ {wxNullBitmap, {address,wxBitmap}},
+ {wxNullIcon, {address,wxIcon}},
+ {wxNullCursor, {address,wxCursor}},
+ {wxNullPen, {address,wxPen}},
+ {wxNullBrush, {address,wxBrush}},
+ {wxNullPalette, {address,wxPalette}},
+ {wxNullFont, {address,wxFont}}]}.
+{enum, wxBackgroundStyle, "wxBG_STYLE_"}.
+{enum, wxWindowVariant, "wxWINDOW_VARIANT_"}.
+{enum, wxBitmapType, "wxBITMAP_TYPE_"}.
+
+{class, wxeEvtHandler, object, [taylormade, {alias, [{wxeEvtHandler, wxEvtHandler}]}],
+ [{'Connect', [{"eventType",{base,eventType}},{"userData",nowhere}]},
+ {'Disconnect',[{"eventType",{base,eventType}},{"userData",nowhere}]}]
+}.
+
+{class, wxWindowGTK, wxEvtHandler,
+ [{alias, [{wxWindowGTK, wxWindow}]}],
+ [wxWindow,'~wxWindow', %% 'AddChild',
+ 'CacheBestSize','CaptureMouse',
+ 'Center','CenterOnParent','Centre','CentreOnParent','ClearBackground',
+ {'ClientToScreen',[{"x",both},{"y",both}]}, 'Close',
+ 'ConvertDialogToPixels','ConvertPixelsToDialog','Destroy','DestroyChildren',
+ 'Disable',%%'DoGetBestSize','DoUpdateWindowUI', 'DragAcceptFiles',
+ 'Enable',
+ 'FindFocus','FindWindow','FindWindowById','FindWindowByName','FindWindowByLabel',
+ 'Fit','FitInside','Freeze', 'GetAcceleratorTable', % 'GetAccessible',
+ 'GetBackgroundColour','GetBackgroundStyle',
+ 'GetBestSize','GetCaret','GetCapture','GetCharHeight',
+ 'GetCharWidth','GetChildren',
+ %%'GetClassDefaultAttributes','GetConstraints'
+ 'GetClientSize','GetContainingSizer','GetCursor',
+ %%'GetDefaultAttributes',
+ 'GetDropTarget','GetEventHandler','GetExtraStyle','GetFont','GetForegroundColour',
+ 'GetGrandParent',
+ {'GetHandle', [{return, [{type,"wxUIntPtr"}, {ref,pointer}, {base, int}]}]},
+ 'GetHelpText','GetId','GetLabel','GetMaxSize',
+ 'GetMinSize','GetName','GetParent','GetPosition','GetRect',
+ {'GetScreenPosition', [{"x",out},{"y",out}]}, 'GetScreenRect',
+ 'GetScrollPos','GetScrollRange','GetScrollThumb','GetSize','GetSizer',
+ {'GetTextExtent', [{"descent", out}, {"externalLeading", out}]},
+ 'GetToolTip','GetUpdateRegion',%'GetValidator',
+ 'GetVirtualSize','GetWindowStyleFlag','GetWindowVariant','HasCapture','HasScrollbar',
+ 'HasTransparentBackground','Hide','InheritAttributes','InitDialog',
+ 'InvalidateBestSize','IsEnabled','IsExposed','IsRetained','IsShown','IsTopLevel',
+ 'Layout','LineDown','LineUp','Lower','MakeModal','Move','MoveAfterInTabOrder',
+ 'MoveBeforeInTabOrder','Navigate',%'OnInternalIdle',
+ 'PageDown','PageUp',
+ 'PopEventHandler','PopupMenu',%'PushEventHandler',
+ 'Raise', 'Refresh', 'RefreshRect',%'RegisterHotKey',
+ 'ReleaseMouse','RemoveChild',%'RemoveEventHandler',
+ 'Reparent',
+ 'ScreenToClient','ScrollLines','ScrollPages','ScrollWindow','SetAcceleratorTable',
+ %%'SetAccessible',
+ 'SetAutoLayout','SetBackgroundColour','SetBackgroundStyle',
+ 'SetCaret','SetClientSize','SetContainingSizer','SetCursor',
+ %%'SetConstraints','SetInitialBestSize',
+ 'SetMaxSize','SetMinSize',
+ 'SetOwnBackgroundColour','SetOwnFont','SetOwnForegroundColour','SetDropTarget',
+ %%'SetEventHandler',
+ 'SetExtraStyle','SetFocus','SetFocusFromKbd','SetFont',
+ 'SetForegroundColour','SetHelpText','SetId','SetLabel','SetName','SetPalette',
+ 'SetScrollbar','SetScrollPos','SetSize','SetSizeHints','SetSizer','SetSizerAndFit',
+ 'SetThemeEnabled','SetToolTip',%'SetValidator',
+ 'SetVirtualSize',
+ 'SetVirtualSizeHints','SetWindowStyle','SetWindowStyleFlag','SetWindowVariant',
+ 'ShouldInheritColours','Show','Thaw','TransferDataFromWindow',
+ 'TransferDataToWindow',%'UnregisterHotKey',
+ 'Update','UpdateWindowUI','Validate',
+ 'WarpPointer']}.
+
+{class, wxTopLevelWindowGTK, wxWindow,
+ [{alias, [{wxTopLevelWindowGTK, wxTopLevelWindow}]}],
+ ['GetIcon','GetIcons','GetTitle','IsActive','Iconize',
+ 'IsFullScreen','IsIconized','IsMaximized','Maximize',
+ 'RequestUserAttention','SetIcon','SetIcons',
+ 'CenterOnScreen', 'CentreOnScreen',
+ %%'SetLeftMenu', 'SetRightMenu',
+ 'SetShape','SetTitle','ShowFullScreen'
+ ]}.
+
+{class, wxFrame, wxTopLevelWindow, [],
+ ['wxFrame','~wxFrame',%'Centre',
+ 'Create','CreateStatusBar','CreateToolBar',
+ 'GetClientAreaOrigin','GetMenuBar','GetStatusBar','GetStatusBarPane',
+ 'GetToolBar',%'OnCreateStatusBar','OnCreateToolBar',
+ 'ProcessCommand','SendSizeEvent','SetMenuBar','SetStatusBar',
+ 'SetStatusBarPane','SetStatusText',
+ {'SetStatusWidths', [{"n",{c_only,{length,"widths_field"}}}]},
+ 'SetToolBar']}.
+
+{class, wxMiniFrame, wxFrame, [],
+ ['wxMiniFrame','~wxMiniFrame','Create']}.
+
+%% Hmm what do we do with these
+%% {class, wxValidator, root,[],
+%% ['wxValidator','~wxValidator','Clone','GetWindow','SetBellOnError','SetWindow',
+%% 'TransferFromWindow','TransferToWindow','Validate']}.
+%% {class, wxGenericValidator, wxValidator,[],
+%% ['wxGenericValidator','~wxGenericValidator','Clone',
+%% 'TransferFromWindow','TransferToWindow']}.
+%% {class, wxTextValidator, wxValidator,[],
+%% ['wxTextValidator','Clone','GetExcludes','GetIncludes','GetStyle',
+%% 'OnChar','SetExcludes','SetIncludes','SetStyle','TransferFromWindow',
+%% 'TransferToWindow','Validate']}.
+
+{class, wxSplashScreen, wxFrame, [],
+ ['wxSplashScreen','~wxSplashScreen',%'OnCloseWindow',
+ 'GetSplashStyle', %'GetSplashWindow',
+ 'GetTimeout']}.
+
+{class, wxPanel, wxWindow, [],
+ ['wxPanel','~wxPanel',%'Create',
+ %%'GetDefaultItem',
+ 'InitDialog'%,
+ %%'OnSysColourChanged', %'SetDefaultItem','SetFocus','SetFocusIgnoringChildren'
+ ]}.
+
+{class, wxScrolledWindow, wxPanel, [],
+ ['wxScrolledWindow','~wxScrolledWindow',
+ 'CalcScrolledPosition','CalcUnscrolledPosition',%'Create',
+ 'EnableScrolling','GetScrollPixelsPerUnit','GetViewStart',
+ %%'GetVirtualSize','IsRetained',
+ 'DoPrepareDC',%'OnDraw',
+ 'PrepareDC','Scroll','SetScrollbars',
+ 'SetScrollRate',{'SetTargetWindow',[{"pushEventHandler", nowhere}]}]}.
+
+{class, wxSashWindow, wxWindow, [],
+ ['wxSashWindow','~wxSashWindow','GetSashVisible','GetMaximumSizeX',
+ 'GetMaximumSizeY','GetMinimumSizeX','GetMinimumSizeY',
+ 'SetMaximumSizeX','SetMaximumSizeY','SetMinimumSizeX','SetMinimumSizeY',
+ 'SetSashVisible' %% ,'HasBorder', 'SetSashBorder' 2.6 only
+ ]}.
+
+{class, wxSashLayoutWindow, wxSashWindow, [],
+ ['wxSashLayoutWindow','Create','GetAlignment','GetOrientation',
+ %% 'OnCalculateLayout','OnQueryLayoutInfo', Requires events for overloading ?
+ 'SetAlignment','SetDefaultSize','SetOrientation'
+ ]}.
+
+{enum, {"wxGrid","wxGridSelectionModes"}, "wxGrid::wxGrid"}.
+{class, wxGrid, wxScrolledWindow, [],
+ ['wxGrid','~wxGrid','AppendCols','AppendRows','AutoSize',%'AutoSizeColOrRow',
+ 'AutoSizeColumn','AutoSizeColumns','AutoSizeRow','AutoSizeRows','BeginBatch',
+ 'BlockToDeviceRect','CanDragColSize','CanDragRowSize','CanDragGridSize',
+ 'CanEnableCellControl',%'CanHaveAttributes',
+ 'CellToRect','ClearGrid','ClearSelection','CreateGrid',
+ 'DeleteCols','DeleteRows','DisableCellEditControl',
+ 'DisableDragColSize','DisableDragGridSize','DisableDragRowSize',
+ 'EnableCellEditControl','EnableDragColSize','EnableDragGridSize',
+ 'EnableDragRowSize','EnableEditing','EnableGridLines','EndBatch','Fit',
+ 'ForceRefresh','GetBatchCount','GetCellAlignment','GetCellBackgroundColour',
+ 'GetCellEditor','GetCellFont','GetCellRenderer','GetCellTextColour','GetCellValue',
+ %'GetColLeft',
+ 'GetColLabelAlignment','GetColLabelSize','GetColLabelValue',
+ 'GetColMinimalAcceptableWidth',%'GetColMinimalWidth',
+ %'GetColRight','GetColSize',
+ 'GetDefaultCellAlignment','GetDefaultCellBackgroundColour','GetDefaultCellFont',
+ 'GetDefaultCellTextColour','GetDefaultColLabelSize','GetDefaultColSize',
+ 'GetDefaultEditor','GetDefaultEditorForCell','GetDefaultEditorForType',
+ 'GetDefaultRenderer','GetDefaultRendererForCell','GetDefaultRendererForType',
+ 'GetDefaultRowLabelSize','GetDefaultRowSize','GetGridCursorCol','GetGridCursorRow',
+ 'GetGridLineColour','GridLinesEnabled','GetLabelBackgroundColour','GetLabelFont',
+ 'GetLabelTextColour','GetNumberCols','GetNumberRows','GetOrCreateCellAttr',
+ 'GetRowMinimalAcceptableHeight',%'GetRowMinimalHeight',
+ 'GetRowLabelAlignment',
+ 'GetRowLabelSize','GetRowLabelValue','GetRowSize','GetScrollLineX','GetScrollLineY',
+ %'GetSelectionMode',
+ 'GetSelectedCells','GetSelectedCols','GetSelectedRows',
+ 'GetSelectionBackground','GetSelectionBlockTopLeft','GetSelectionBlockBottomRight',
+ 'GetSelectionForeground',%'GetTable',
+ 'GetViewWidth',
+ 'GetGridWindow', 'GetGridRowLabelWindow',
+ 'GetGridColLabelWindow', 'GetGridCornerLabelWindow',
+ 'HideCellEditControl',
+ %'InitColWidths','InitRowHeights',
+ 'InsertCols','InsertRows',
+ 'IsCellEditControlEnabled','IsCurrentCellReadOnly','IsEditable','IsInSelection',
+ 'IsReadOnly','IsSelection','IsVisible','MakeCellVisible','MoveCursorDown',
+ 'MoveCursorLeft','MoveCursorRight','MoveCursorUp','MoveCursorDownBlock',
+ 'MoveCursorLeftBlock','MoveCursorRightBlock','MoveCursorUpBlock','MovePageDown',
+ 'MovePageUp','RegisterDataType','SaveEditControlValue','SelectAll','SelectBlock',
+ 'SelectCol', %'SelectionToDeviceRect',
+ 'SelectRow','SetCellAlignment',
+ 'SetCellBackgroundColour','SetCellEditor','SetCellFont','SetCellRenderer',
+ 'SetCellTextColour','SetCellValue','SetColAttr','SetColFormatBool',
+ 'SetColFormatNumber','SetColFormatFloat','SetColFormatCustom',
+ 'SetColLabelAlignment','SetColLabelSize','SetColLabelValue','SetColMinimalWidth',
+ 'SetColMinimalAcceptableWidth','SetColSize','SetDefaultCellAlignment',
+ 'SetDefaultCellBackgroundColour','SetDefaultCellFont','SetDefaultCellTextColour',
+ 'SetDefaultEditor','SetDefaultRenderer','SetDefaultColSize','SetDefaultRowSize',
+ 'SetGridCursor','SetGridLineColour','SetLabelBackgroundColour','SetLabelFont',
+ 'SetLabelTextColour','SetMargins',%'SetOrCalcColumnSizes','SetOrCalcRowSizes',
+ 'SetReadOnly','SetRowAttr','SetRowLabelAlignment','SetRowLabelSize',
+ 'SetRowLabelValue','SetRowMinimalHeight','SetRowMinimalAcceptableHeight',
+ 'SetRowSize','SetScrollLineX','SetScrollLineY','SetSelectionBackground',
+ 'SetSelectionForeground','SetSelectionMode',%'SetTable',
+ 'ShowCellEditControl','XToCol','XToEdgeOfCol','YToEdgeOfRow','YToRow']}.
+
+{class, wxGridCellRenderer, root, [],
+ ['Draw','GetBestSize']}.
+{class, wxGridCellEditor, root, [],
+ ['Create',
+ 'IsCreated', 'SetSize', 'Show',
+ 'PaintBackground', 'BeginEdit', 'EndEdit', 'Reset', 'StartingKey',
+ 'StartingClick', 'HandleReturn'
+ %'Destroy','Clone','~wxGridCellEditor',
+ ]}.
+
+{class, wxGridCellBoolRenderer, wxGridCellRenderer, [],
+ ['wxGridCellBoolRenderer']}.
+{class, wxGridCellBoolEditor, wxGridCellEditor, [],
+ ['wxGridCellBoolEditor', 'IsTrueValue', 'UseStringValues']}.
+
+{class, wxGridCellFloatRenderer, wxGridCellStringRenderer, [],
+ ['wxGridCellFloatRenderer', 'GetPrecision', 'GetWidth',
+ 'SetParameters', 'SetPrecision', 'SetWidth']}.
+{class, wxGridCellFloatEditor, wxGridCellEditor, [],
+ ['wxGridCellFloatEditor', 'SetParameters' ]}.
+
+{class, wxGridCellStringRenderer, wxGridCellRenderer, [], ['wxGridCellStringRenderer']}.
+{class, wxGridCellTextEditor, wxGridCellEditor, [],
+ ['wxGridCellTextEditor','SetParameters']}.
+{class, wxGridCellChoiceEditor, wxGridCellEditor, [{skip, [{'wxGridCellChoiceEditor', 3}]}],
+ ['wxGridCellChoiceEditor','SetParameters']}.
+
+{class, wxGridCellNumberRenderer, wxGridCellStringRenderer, [],
+ ['wxGridCellNumberRenderer']}.
+{class, wxGridCellNumberEditor, wxGridCellTextEditor, [],
+ ['wxGridCellNumberEditor','GetValue','SetParameters']}.
+
+{class, wxGridCellAttr, root, [],
+ [%'wxGridCellAttr','Clone','IncRef','DecRef',
+ 'SetTextColour','SetBackgroundColour','SetFont','SetAlignment','SetReadOnly',
+ 'SetRenderer','SetEditor','HasTextColour','HasBackgroundColour','HasFont',
+ 'HasAlignment','HasRenderer','HasEditor','GetTextColour','GetBackgroundColour',
+ 'GetFont','GetAlignment','GetRenderer','GetEditor','IsReadOnly','SetDefAttr']}.
+
+{enum, wxDirection, "wx"}.
+{enum, wxLayoutDirection, "wxLayout_"}.
+
+{class, wxDC, object,
+ [{skip, [{'DrawEllipse',5},{'DrawRectangle',5},
+ {'DrawRoundedRectangle',6},{'SetClippingRegion',5}]}],
+ [{'Blit',7},'CalcBoundingBox','Clear','ComputeScaleAndOrigin',{'CrossHair',1},
+ 'DestroyClippingRegion','DeviceToLogicalX','DeviceToLogicalXRel',
+ 'DeviceToLogicalY','DeviceToLogicalYRel',{'DrawArc',3},{'DrawBitmap',3},
+ {'DrawCheckMark',1},{'DrawCircle',2},'DrawEllipse',{'DrawEllipticArc',4},
+ {'DrawIcon',2},{'DrawLabel',4},{'DrawLine',2},
+ {'DrawLines', [{"n",{c_only,{length,"points"}}}]},
+ {'DrawPolygon', [{"n",{c_only,{length,"points"}}}]}, %'DrawPolyPolygon',
+ {'DrawPoint',1},'DrawRectangle',
+ {'DrawRotatedText',3}, 'DrawRoundedRectangle',%'DrawSpline',
+ {'DrawText',2},
+ 'EndDoc','EndPage',{'FloodFill',3},'GetBackground','GetBackgroundMode',
+ 'GetBrush','GetCharHeight','GetCharWidth',{'GetClippingBox',1},'GetFont',
+ 'GetLayoutDirection','GetLogicalFunction','GetMapMode','GetMultiLineTextExtent',
+ 'GetPartialTextExtents','GetPen',{'GetPixel',2},'GetPPI','GetSize','GetSizeMM',
+ 'GetTextBackground','GetTextExtent','GetTextForeground',
+ 'GetUserScale','GradientFillConcentric','GradientFillLinear',
+ 'LogicalToDeviceX','LogicalToDeviceXRel','LogicalToDeviceY','LogicalToDeviceYRel',
+ 'MaxX','MaxY','MinX','MinY','IsOk','ResetBoundingBox','SetAxisOrientation',
+ 'SetBackground','SetBackgroundMode','SetBrush','SetClippingRegion','SetDeviceOrigin',
+ 'SetFont','SetLayoutDirection','SetLogicalFunction','SetMapMode', 'SetPalette',
+ 'SetPen','SetTextBackground','SetTextForeground','SetUserScale','StartDoc','StartPage']}.
+
+{class,wxMirrorDC, wxDC, [], ['wxMirrorDC', '~wxMirrorDC']}.
+{class,wxScreenDC, wxDC, [], ['wxScreenDC', '~wxScreenDC']}.
+{class,wxPostScriptDC,wxDC,[],['wxPostScriptDC','~wxPostScriptDC','SetResolution','GetResolution']}.
+{class,wxWindowDC, wxDC, [], ['wxWindowDC', '~wxWindowDC']}.
+{class,wxClientDC,wxWindowDC,[],['wxClientDC', '~wxClientDC']}.
+{class,wxPaintDC, wxWindowDC, [], ['wxPaintDC', '~wxPaintDC']}.
+%%{class,wxPrinterDC, wxDC, [], ['wxPrinterDC','GetPaperRect']}. Not in GTK
+{class,wxMemoryDC, wxDC, [], ['wxMemoryDC', '~wxMemoryDC','SelectObject','SelectObjectAsSource']}.
+{class,wxBufferedDC,wxMemoryDC,[],['wxBufferedDC','~wxBufferedDC','Init']}.
+{class,wxBufferedPaintDC,wxBufferedDC,[],['wxBufferedPaintDC', '~wxBufferedPaintDC']}.
+%% Only a typedef!
+%%{class,wxAutoBufferedPaintDC,wxBufferedPaintDC,[],['wxAutoBufferedPaintDC']}.
+
+{class, wxGraphicsObject, object, [{ifdef, wxUSE_GRAPHICS_CONTEXT}],
+ ['GetRenderer','IsNull']}.
+{class, wxGraphicsContext, wxGraphicsObject, [{ifdef, wxUSE_GRAPHICS_CONTEXT}],
+ ['Create', %%CreateFromNative CreateFromNativeWindow
+ 'CreatePen','CreateBrush','CreateRadialGradientBrush',
+ 'CreateLinearGradientBrush','CreateFont','CreateMatrix',
+ 'CreatePath','Clip','ResetClip',
+ 'DrawBitmap','DrawEllipse','DrawIcon','DrawLines','DrawPath',
+ 'DrawRectangle','DrawRoundedRectangle','DrawText','FillPath',
+ 'StrokePath','GetNativeContext','GetPartialTextExtents',
+ 'GetTextExtent','Rotate','Scale','Translate',
+ 'GetTransform','SetTransform','ConcatTransform',
+ 'SetBrush','SetFont','SetPen','StrokeLine','StrokeLines']}.
+{class, wxGraphicsMatrix, wxGraphicsObject, [{ifdef, wxUSE_GRAPHICS_CONTEXT}],
+ ['Concat','Get','GetNativeMatrix','Invert','IsEqual','IsIdentity',
+ 'Rotate','Scale','Translate','Set','TransformPoint','TransformDistance']}.
+{class, wxGraphicsPath, wxGraphicsObject, [{ifdef, wxUSE_GRAPHICS_CONTEXT}],
+ ['MoveToPoint','AddArc','AddArcToPoint','AddCircle','AddCurveToPoint',
+ 'AddEllipse','AddLineToPoint','AddPath','AddQuadCurveToPoint',
+ 'AddRectangle','AddRoundedRectangle','CloseSubpath','Contains',
+ 'GetBox','GetCurrentPoint','Transform'
+ %'GetNativePath','UnGetNativePath'
+ ]}.
+{class, wxGraphicsRenderer, object, [{ifdef, wxUSE_GRAPHICS_CONTEXT}],
+ ['GetDefaultRenderer','CreateContext',
+ %%'CreateContextFromNativeContext', 'CreateContextFromNativeWindow',
+ 'CreatePen','CreateBrush',
+ 'CreateLinearGradientBrush','CreateRadialGradientBrush','CreateFont',
+ 'CreateMatrix','CreatePath']}.
+
+{class, wxGraphicsPen, wxGraphicsObject,[{ifdef, wxUSE_GRAPHICS_CONTEXT}], []}.
+{class, wxGraphicsBrush,wxGraphicsObject,[{ifdef, wxUSE_GRAPHICS_CONTEXT}], []}.
+{class, wxGraphicsFont, wxGraphicsObject,[{ifdef, wxUSE_GRAPHICS_CONTEXT}], []}.
+
+{class, wxMenuBar, wxWindow, [{skip, [{wxMenuBar,4}]}],
+ [
+ 'wxMenuBar','~wxMenuBar','Append','Check','Enable','EnableTop',
+ 'FindMenu', 'FindMenuItem',{'FindItem', [{"menu",skip}]},'GetHelpString',
+ 'GetLabel','GetLabelTop','GetMenu','GetMenuCount','Insert','IsChecked',
+ 'IsEnabled',%'Refresh',
+ 'Remove','Replace','SetHelpString',
+ 'SetLabel','SetLabelTop']}.
+
+{class, wxControl, wxWindow, [], [% 'Command','GetLabelText',
+ 'GetLabel','SetLabel']}.
+
+{class, wxControlWithItems, wxControl,
+ [{skip, [{'GetClientObject',1},{'SetClientObject',2}]}],
+ [
+ {'Append',[{"clientData",[{skip_member, void}]},
+ {"strings", [{erl_func, "appendStrings"}]}]},
+ 'Clear','Delete','FindString',
+ %% 'GetClientData','SetClientData',
+ {'GetClientObject', [{"n", [{erl_func, "getClientData"}]}]},
+ {'SetClientObject', [{"n", [{erl_func, "setClientData"}]}]},
+ 'GetCount','GetSelection','GetString','GetStringSelection',
+ {'Insert',[{"clientData",[{skip_member, void}]}]},%'Number',
+ 'IsEmpty','Select','SetSelection','SetString','SetStringSelection'
+ ]}.
+
+{enum, wxItemKind, "wxITEM_"}.
+
+{class, wxMenu, wxEvtHandler, [],
+ ['wxMenu','~wxMenu',{'Append', [{"text",{def,none}}]},
+ 'AppendCheckItem','AppendRadioItem',
+ 'AppendSeparator','Break','Check','Delete','Destroy','Enable',
+ {'FindItem', [{"menu",skip}]},'FindItemByPosition','GetHelpString','GetLabel',
+ 'GetMenuItemCount','GetMenuItems','GetTitle','Insert',
+ 'InsertCheckItem','InsertRadioItem','InsertSeparator','IsChecked',
+ 'IsEnabled','Prepend','PrependCheckItem','PrependRadioItem',
+ 'PrependSeparator','Remove','SetHelpString','SetLabel','SetTitle']}.
+
+{class, wxMenuItem, object, [],
+ [{'wxMenuItem',[{"isCheckable",skip_member}]},
+ '~wxMenuItem','Check','Enable',
+ %%'GetBackgroundColour',
+ 'GetBitmap', %%'GetFont',
+ 'GetHelp','GetId','GetKind','GetLabel','GetLabelFromText',
+ %%'GetMarginWidth','GetTextColour',
+ 'GetMenu',%'GetName', class clash will not compile on windows
+ 'GetText',
+ 'GetSubMenu','IsCheckable','IsChecked','IsEnabled',
+ 'IsSeparator','IsSubMenu',
+ %%'SetBackgroundColour',
+ 'SetBitmap', %%'SetBitmaps',%%'SetFont',
+ 'SetHelp','SetMenu','SetSubMenu','SetText'
+ %%'SetTextColour',%'SetMarginWidth'
+ ]}.
+
+{class, wxToolBar, wxControl, [],
+ ['AddControl','AddSeparator','AddTool','AddCheckTool','AddRadioTool',
+ 'DeleteTool','DeleteToolByPos','EnableTool','FindById','FindControl',
+ 'FindToolForPosition','GetToolSize','GetToolBitmapSize','GetMargins',
+ %%'GetToolClientData' , %%'SetToolClientData',
+ 'GetToolEnabled','GetToolLongHelp','GetToolPacking',
+ 'GetToolPos','GetToolSeparation','GetToolShortHelp','GetToolState',
+ 'InsertControl','InsertSeparator','InsertTool',
+ %%'OnLeftClick','OnMouseEnter','OnRightClick',
+ 'Realize','RemoveTool', %'SetBitmapResource',
+ {'SetMargins',2},'SetToolBitmapSize',
+ 'SetToolLongHelp',
+ 'SetToolPacking','SetToolShortHelp','SetToolSeparation','ToggleTool'
+ ]}.
+
+{class, wxStatusBarGeneric, wxWindow,
+ [{alias, [{wxStatusBarGeneric, wxStatusBar}]}],
+ [{'wxStatusBar',[{"size", skip_member}]},
+ '~wxStatusBar',
+ {'Create',[{"size", skip_member}]},
+ 'GetFieldRect','GetFieldsCount','GetStatusText','PopStatusText',
+ 'PushStatusText',
+ {'SetFieldsCount', [{"number", {def,none}},
+ {"widths", [{single, array}, {def, "(int *) NULL"}]}]},
+ 'SetMinHeight','SetStatusText',
+ {'SetStatusWidths', [{"n",{c_only,{length,"widths_field"}}}]},
+ {'SetStatusStyles', [{"n",{c_only,{length,"styles"}}}]}
+ ]}.
+
+{class, wxBitmap, object,[],
+ [{'wxBitmap',[{"bits",[in,{base,binary}, {single,true}]},{{1,"bits"},skip_member}]},
+ '~wxBitmap',%'AddHandler','CleanUpHandlers',
+ 'ConvertToImage',
+ 'CopyFromIcon','Create',%'FindHandler',
+ 'GetDepth','GetHeight',%'GetHandlers',
+ 'GetPalette',
+ 'GetMask','GetWidth','GetSubBitmap',
+ %%'InitStandardHandlers','InsertHandler','RemoveHandler',
+ 'LoadFile','Ok','SaveFile','SetDepth',
+ 'SetHeight','SetMask','SetPalette',
+ 'SetWidth']}.
+
+{class, wxIcon, wxBitmap,[],
+ [%%{'wxIcon',[{"bits",[in,{base,binary}]}]},
+ {'wxIcon',[{"bits",skip_member}]}, %% bits is char** in gtk and char[] in mac!!!
+ 'CopyFromBitmap','~wxIcon']}.
+
+{class, wxIconBundle, root, [],
+ ['wxIconBundle','~wxIconBundle','AddIcon','GetIcon']}.
+
+{class, wxCursor, wxBitmap,[],
+ [{'wxCursor',[{"bits",[in,{base,binary},{single,true}]},
+ {"maskBits",nowhere},{"fg",nowhere},{"bg",nowhere}]},
+ '~wxCursor','Ok']}.
+
+{class, wxMask, object, [], ['wxMask','~wxMask','Create']}.
+
+{class, wxImage, object, [{doc,"All (default) image handlers are initialized."}],
+ [{'wxImage',[{"xpmData",skip_member},
+ {"data",[in,{base,binary}]},
+ {"alpha",[in,{base,binary}]},
+ {{4,pre_hook},
+ "if(!static_data) {"
+ "data = (unsigned char *) malloc(Ecmd.bin[0]->size);"
+ "memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"},
+ {{5,pre_hook},
+ "if(!static_data) {"
+ " data = (unsigned char *) malloc(Ecmd.bin[0]->size);"
+ " alpha = (unsigned char *) malloc(Ecmd.bin[1]->size);"
+ " memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);"
+ " memcpy(alpha,Ecmd.bin[1]->base,Ecmd.bin[1]->size);}"}
+ ]},
+ '~wxImage',%'AddHandler',
+ 'Blur','BlurHorizontal','BlurVertical',
+ %'CleanUpHandlers',%'ComputeHistogram',
+ 'ConvertAlphaToMask','ConvertToGreyscale',
+ 'ConvertToMono','Copy',
+ {'Create',[{"xpmData",skip_member},
+ {"data",[in,{base,binary}]},
+ {"alpha",[in,{base,binary}]},
+ {{4,pre_hook},
+ "if(!static_data) {"
+ "data = (unsigned char *) malloc(Ecmd.bin[0]->size);"
+ "memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"},
+ {{5,pre_hook},
+ "if(!static_data) {"
+ " data = (unsigned char *) malloc(Ecmd.bin[0]->size);"
+ " alpha = (unsigned char *) malloc(Ecmd.bin[1]->size);"
+ " memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);"
+ " memcpy(alpha,Ecmd.bin[1]->base,Ecmd.bin[1]->size);}"}
+ ]},
+ 'Destroy','FindFirstUnusedColour', % 'FindHandler',
+ 'GetImageExtWildcard',
+ {'GetAlpha',[{{0,return},{base,{binary,"(This->GetWidth()*This->GetHeight())"}}}]},
+ 'GetBlue',
+ {'GetData', [{return,{base,{binary,"(This->GetWidth()*This->GetHeight()*3)"}}}]},
+ 'GetGreen', 'GetImageCount', %'GetHandlers',
+ 'GetHeight','GetMaskBlue','GetMaskGreen',
+ 'GetMaskRed','GetOrFindMaskColour','GetPalette',
+ 'GetRed','GetSubImage', 'GetWidth',%%':HSVValue', 'HSVtoRGB',
+ 'HasAlpha','HasMask','GetOption','GetOptionInt','HasOption',
+ 'InitAlpha','InitStandardHandlers',%'InsertHandler',
+ 'IsTransparent', 'LoadFile','Ok',%%RGBValue 'RGBtoHSV',
+ 'RemoveHandler','Mirror','Replace','Rescale','Resize',
+ 'Rotate', 'RotateHue',
+ 'Rotate90','SaveFile','Scale','Size',
+ {'SetAlpha', [{{2,"alpha"},[in,{base,binary}, {def, none}]},
+ {{2,pre_hook},
+ "if(!static_data) {"
+ "alpha = (unsigned char *) malloc(Ecmd.bin[0]->size);"
+ "memcpy(alpha,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"}
+ ]},
+ {'SetData', [{"data",[in,{base,binary}]},
+ {pre_hook,
+ "if(!static_data) {"
+ "data = (unsigned char *) malloc(Ecmd.bin[0]->size);"
+ "memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"}
+ ]},
+ 'SetMask','SetMaskColour','SetMaskFromImage','SetOption',
+ 'SetPalette',
+ 'SetRGB']}.
+
+{class, wxBrush, object, [],
+ ['wxBrush','~wxBrush','GetColour','GetStipple','GetStyle',
+ 'IsHatch','IsOk','SetColour','SetStipple','SetStyle']}.
+
+{class, wxPen, object, [],
+ ['wxPen','~wxPen','GetCap','GetColour',
+ %%'GetDashes', %'GetStipple',
+ 'GetJoin', 'GetStyle','GetWidth','IsOk','SetCap','SetColour',
+ %%'SetDashes', %'SetStipple',
+ 'SetJoin', 'SetStyle','SetWidth']}.
+
+{enum, wxRegionContain, "wx"}.
+
+{class, wxRegion, object,
+ [{skip, [{wxRegion,3}]}], % Hmm compiler can't handle that
+ [{'wxRegion',[{"region", [skip_member]}]},
+ '~wxRegion','Clear','Contains','ConvertToBitmap',
+ {'GetBox',0},'Intersect','IsEmpty','Subtract','Offset',
+ 'Union','Xor']}.
+
+{class, wxAcceleratorTable, object,
+ [{skip, [{wxAcceleratorTable,1}]}],
+ ['wxAcceleratorTable','~wxAcceleratorTable','Ok']}.
+
+{class, wxAcceleratorEntry, root, [],
+ ['wxAcceleratorEntry','GetCommand','GetFlags','GetKeyCode','Set']}.
+
+{class, wxCaret, root,
+ [{skip, [{wxCaret,0}]}],
+ ['wxCaret','~wxCaret','Create','GetBlinkTime','GetPosition','GetSize','GetWindow','Hide','IsOk',
+ 'IsVisible','Move','SetBlinkTime','SetSize','Show']}.
+
+{enum, wxFlexSizerGrowMode, "wxFLEX_GROWMODE_"}.
+
+{class, wxSizer, object, [],
+ [{'Add',[{"item", skip_member}]},
+ 'AddSpacer','AddStretchSpacer','CalcMin','Clear','Detach','Fit','FitInside',
+ 'GetChildren',%'GetContainingWindow',
+ 'GetItem','GetSize','GetPosition','GetMinSize',
+ 'Hide','Insert','InsertSpacer','InsertStretchSpacer','IsShown','Layout','Prepend',
+ 'PrependSpacer','PrependStretchSpacer','RecalcSizes','Remove', 'Replace',
+ 'SetDimension','SetMinSize','SetItemMinSize','SetSizeHints',
+ 'SetVirtualSizeHints','Show']}.
+
+{class, wxSizerFlags, root, [],
+ ['wxSizerFlags','Align','Border','Center','Centre',%'DoubleBorder','DoubleHorzBorder',
+ 'Expand',%'GetDefaultBorder',
+ 'Left','Proportion','Right'%,'TripleBorder'
+ ]}.
+
+{class, wxSizerItem, object, [],
+ ['wxSizerItem','~wxSizerItem','CalcMin','DeleteWindows','DetachSizer','GetBorder',
+ 'GetFlag','GetMinSize','GetPosition','GetProportion','GetRatio','GetRect','GetSize',
+ 'GetSizer','GetSpacer','GetUserData','GetWindow','IsSizer','IsShown','IsSpacer',
+ 'IsWindow','SetBorder','SetDimension','SetFlag','SetInitSize','SetMinSize',
+ 'SetProportion','SetRatio','SetSizer','SetSpacer','SetWindow','Show']}.
+
+{class,wxBoxSizer,wxSizer,[],['wxBoxSizer','GetOrientation']}.
+{class,wxStaticBoxSizer,wxBoxSizer,[],['wxStaticBoxSizer','GetStaticBox']}.
+
+{class,wxGridSizer,wxSizer,[],
+ ['wxGridSizer','GetCols','GetHGap','GetRows','GetVGap','SetCols','SetHGap',
+ 'SetRows','SetVGap']}.
+
+{class,wxFlexGridSizer,wxGridSizer,[],
+ ['wxFlexGridSizer','AddGrowableCol','AddGrowableRow','GetFlexibleDirection',
+ 'GetNonFlexibleGrowMode','RemoveGrowableCol','RemoveGrowableRow',
+ 'SetFlexibleDirection','SetNonFlexibleGrowMode']}.
+
+{class,wxGridBagSizer,wxFlexGridSizer,[],
+ ['wxGridBagSizer','Add','CalcMin','CheckForIntersection','FindItem',
+ 'FindItemAtPoint','FindItemAtPosition','FindItemWithData','GetCellSize',
+ 'GetEmptyCellSize','GetItemPosition','GetItemSpan',
+ 'SetEmptyCellSize','SetItemPosition','SetItemSpan']}.
+
+{class,wxGBSizerItem,wxSizerItem,[],[]}.
+%% [{skip, [{'GetEndPos',3},{'GetPos',3},{'GetSpan',3}]}],
+%% ['wxGBSizerItem','GetEndPos','GetPos','GetSpan','Intersects','SetPos','SetSpan']}.
+
+{class,wxStdDialogButtonSizer,wxBoxSizer,[],
+ ['wxStdDialogButtonSizer','~wxStdDialogButtonSizer','AddButton','Realize',
+ 'SetAffirmativeButton','SetCancelButton','SetNegativeButton']}.
+
+{enum, wxFontFamily, "wxFONTFAMILY_"}.
+{enum, wxFontStyle, "wxFONTSTYLE_"}.
+{enum, wxFontEncoding,"wxFONTENCODING_"}.
+
+{class, wxFont, object, [],
+ [{'wxFont',[{"info", [skip_member]},{"family",{base,{enum,"wxFontFamily"}}},
+ {"style",{base,{enum,"wxFontStyle"}}}]},
+ '~wxFont','IsFixedWidth','GetDefaultEncoding','GetFaceName',
+ {'GetFamily',[{return, {base,{enum,"wxFontFamily"}}}]},
+ 'GetNativeFontInfoDesc','GetNativeFontInfoUserDesc','GetPointSize',
+ {'GetStyle',[{return, {base,{enum,"wxFontStyle"}}}]},
+ 'GetUnderlined','GetWeight',%% {'New',[{"nativeFontDesc", [skip_member]}]},
+ 'Ok','SetDefaultEncoding','SetFaceName',
+ {'SetFamily',[{"family", {base,{enum,"wxFontFamily"}}}]},
+ %%'SetNativeFontInfo','SetNativeFontInfoUserDesc',
+ 'SetPointSize',
+ {'SetStyle', [{"style", {base,{enum,"wxFontStyle"}}}]},
+ 'SetUnderlined','SetWeight']}.
+
+{class, wxToolTip, object, [],
+ ['Enable','SetDelay','wxToolTip','SetTip','GetTip','GetWindow']}.
+{class, wxButton, wxControl, [],
+ ['wxButton','~wxButton','Create',%'GetLabel',
+ 'GetDefaultSize', 'SetDefault','SetLabel']}.
+{class, wxBitmapButton, wxButton, [],
+ ['wxBitmapButton','~wxBitmapButton','Create','GetBitmapDisabled',
+ 'GetBitmapFocus','GetBitmapLabel','GetBitmapSelected',
+ 'SetBitmapDisabled','SetBitmapFocus','SetBitmapLabel','SetBitmapSelected']}.
+{class, wxToggleButton, wxControl, [],
+ ['wxToggleButton','~wxToggleButton','Create','GetValue','SetValue']}.
+
+%%{enum, {"wxDateTime", "WeekDay"}, "wxDateTime::WeekDay"}.
+{class, wxDateTime, root, [ignore], []}. %% Only for ifdefs and enums
+
+{class, wxCalendarCtrl, wxControl, [],
+ ['wxCalendarCtrl','Create','~wxCalendarCtrl','SetDate','GetDate',
+ 'EnableYearChange','EnableMonthChange','EnableHolidayDisplay',
+ 'SetHeaderColours','GetHeaderColourFg','GetHeaderColourBg',
+ 'SetHighlightColours','GetHighlightColourFg','GetHighlightColourBg',
+ 'SetHolidayColours','GetHolidayColourFg','GetHolidayColourBg',
+ 'GetAttr','SetAttr','SetHoliday','ResetAttr',
+ {'HitTest', [{"date", [out]}, {"wd", [out]}]}
+ ]}.
+
+{class, wxCalendarDateAttr, root, [],
+ ['wxCalendarDateAttr',
+ 'SetTextColour','SetBackgroundColour','SetBorderColour',
+ 'SetFont','SetBorder','SetHoliday',
+ 'HasTextColour','HasBackgroundColour','HasBorderColour',
+ 'HasFont','HasBorder','IsHoliday','GetTextColour',
+ 'GetBackgroundColour','GetBorderColour','GetFont','GetBorder']}.
+
+{enum, wxCheckBoxState, "wxCHK_"}.
+
+{class, wxCheckBox, wxControl, [],
+ ['wxCheckBox','~wxCheckBox','Create','GetValue','Get3StateValue',
+ 'Is3rdStateAllowedForUser','Is3State','IsChecked','SetValue',
+ 'Set3StateValue']}.
+{class, wxCheckListBox, wxListBox, [{skip,[{wxCheckListBox,8}]}],
+ [{'wxCheckListBox',[{"pos",{def, "wxDefaultPosition"}},
+ {"size",{def, "wxDefaultSize"}},
+ {"choices",{def, ""}}]},
+ '~wxCheckListBox','Check','IsChecked']}.
+{class, wxChoice, wxControlWithItems, [{skip,[{wxChoice,8}, {'Create',9}]}],
+ [{'wxChoice', [{"pos",{def, "wxDefaultPosition"}},
+ {"size",{def, "wxDefaultSize"}},
+ {"choices",{def, ""}}]},
+ '~wxChoice','Create','Delete','GetColumns',
+ %%'GetCurrentSelection',
+ 'SetColumns']}.
+{class, wxComboBox, wxControlWithItems, [{skip,[{wxComboBox,9},{'Create',10}]}],
+ [{'wxComboBox',
+ [{"pos",{def, "wxDefaultPosition"}},
+ {"size",{def, "wxDefaultSize"}},
+ {"value", {def, "wxEmptyString"}},
+ {"choices",{def, ""}}]},
+ '~wxComboBox','Create','CanCopy','CanCut','CanPaste',
+ 'CanRedo','CanUndo','Copy','Cut','GetInsertionPoint','GetLastPosition',
+ 'GetValue','Paste','Redo','Replace','Remove','SetInsertionPoint',
+ 'SetInsertionPointEnd','SetSelection','SetValue','Undo']}.
+{class, wxGauge, wxControl, [],
+ ['wxGauge','~wxGauge','Create','GetBezelFace','GetRange','GetShadowWidth',
+ 'GetValue','IsVertical','SetBezelFace','SetRange','SetShadowWidth','SetValue',
+ 'Pulse']}.
+{class, wxGenericDirCtrl, wxControl, [],
+ ['wxGenericDirCtrl','~wxGenericDirCtrl','Create','Init','CollapseTree',
+ 'ExpandPath','GetDefaultPath','GetPath','GetFilePath', 'GetFilter',
+ 'GetFilterIndex',%'GetFilterListCtrl',
+ 'GetRootId','GetTreeCtrl',
+ 'ReCreateTree','SetDefaultPath','SetFilter','SetFilterIndex','SetPath']}.
+%% {class, wxHtmlListBox, wxControl, [], []}.
+{class, wxStaticBox, wxControl, [], ['wxStaticBox','~wxStaticBox','Create']}.
+{class, wxStaticLine, wxControl, [], ['wxStaticLine','~wxStaticLine','Create',
+ 'IsVertical', 'GetDefaultSize']}.
+
+{enum, wxListColumnFormat, "wxLIST_"}.
+
+{class, wxListBox, wxControlWithItems,
+ [{skip,[{wxListBox,8}, {'Create',9}, {'Set',4}]}],
+ [{'wxListBox',[{"pos",{def, "wxDefaultPosition"}},
+ {"size",{def, "wxDefaultSize"}},
+ {"choices",{def, ""}}]},
+ '~wxListBox','Create','Deselect',{'GetSelections',[{"aSelections", [out]}]},
+ {'InsertItems',2},'IsSelected',{'Set',[{"clientData",[skip]}]},
+ 'HitTest',
+ 'SetFirstItem']}.
+
+{class, wxListCtrl, wxControl, [],
+ ['wxListCtrl','~wxListCtrl','Arrange','AssignImageList','ClearAll','Create',
+ 'DeleteAllItems','DeleteColumn','DeleteItem',
+ {'EditLabel',[{"textControlClass",nowhere}]},
+ 'EnsureVisible',
+ {'FindItem',3},'GetColumn','GetColumnCount','GetColumnWidth','GetCountPerPage',
+ %%'GetEditControl',
+ 'GetImageList','GetItem','GetItemBackgroundColour',
+ 'GetItemCount',{'GetItemData', [{return, {base,int}}]},
+ 'GetItemFont','GetItemPosition','GetItemRect',
+ 'GetItemSpacing','GetItemState','GetItemText','GetItemTextColour',
+ 'GetNextItem','GetSelectedItemCount','GetTextColour','GetTopItem',
+ 'GetViewRect',{'HitTest',[{"pSubItem",nowhere}]},'InsertColumn','InsertItem',
+ %%'OnGetItemAttr', 'OnGetItemImage','OnGetItemText',
+ 'RefreshItem','RefreshItems','ScrollList',
+ 'SetBackgroundColour','SetColumn','SetColumnWidth','SetImageList','SetItem',
+ 'SetItemBackgroundColour','SetItemCount','SetItemData','SetItemFont',
+ 'SetItemImage','SetItemColumnImage','SetItemPosition','SetItemState',
+ 'SetItemText','SetItemTextColour','SetSingleStyle','SetTextColour',
+ 'SetWindowStyleFlag',{'SortItems', [{where, taylormade}]}
+ ]}.
+{class, wxListView, wxControl, [],
+ ['ClearColumnImage','Focus','GetFirstSelected','GetFocusedItem',
+ 'GetNextSelected','IsSelected','Select','SetColumnImage']}.
+
+{class, wxListItem, object, [],
+ ['wxListItem','~wxListItem','Clear','GetAlign','GetBackgroundColour','GetColumn', %'GetData',
+ 'GetFont','GetId','GetImage','GetMask','GetState',
+ 'GetText','GetTextColour','GetWidth','SetAlign','SetBackgroundColour',
+ 'SetColumn',%'SetData',
+ 'SetFont','SetId','SetImage','SetMask','SetState',
+ 'SetStateMask','SetText','SetTextColour','SetWidth']}.
+
+{class, wxImageList, object, [{skip, [{'Create',1}]}], %% No create/0 on windows
+ ['wxImageList','~wxImageList','Add','Create','Draw','GetBitmap','GetIcon','GetImageCount',
+ 'GetSize','Remove','RemoveAll','Replace']}.
+
+{enum, wxTextAttrAlignment, "wxTEXT_ALIGNMENT_"}.
+
+{class, wxTextAttr, root, [],
+ ['wxTextAttr','GetAlignment','GetBackgroundColour','GetFont','GetLeftIndent',
+ 'GetLeftSubIndent','GetRightIndent','GetTabs','GetTextColour',
+ 'HasBackgroundColour','HasFont','HasTextColour','GetFlags','IsDefault',
+ 'SetAlignment','SetBackgroundColour','SetFlags','SetFont','SetLeftIndent',
+ 'SetRightIndent','SetTabs','SetTextColour']}.
+
+{class, wxTextCtrl, wxControl, [],
+ ['wxTextCtrl','~wxTextCtrl','AppendText','CanCopy','CanCut','CanPaste',
+ 'CanRedo','CanUndo','Clear','Copy','Create','Cut','DiscardEdits',
+ 'EmulateKeyPress','GetDefaultStyle','GetInsertionPoint','GetLastPosition',
+ 'GetLineLength','GetLineText','GetNumberOfLines','GetRange','GetSelection',
+ 'GetStringSelection','GetStyle','GetValue',%'HitTest', %no Mac
+ 'IsEditable',
+ 'IsModified','IsMultiLine','IsSingleLine','LoadFile','MarkDirty',
+ %%'OnDropFiles',
+ 'Paste','PositionToXY','Redo','Remove','Replace',
+ 'SaveFile','SetDefaultStyle','SetEditable','SetInsertionPoint',
+ 'SetInsertionPointEnd','SetMaxLength','SetSelection','SetStyle',
+ 'SetValue','ShowPosition','Undo','WriteText','XYToPosition']}.
+
+{class,wxNotebook, wxControl, [],
+ ['wxNotebook','~wxNotebook','AddPage','AdvanceSelection',
+ 'AssignImageList','Create','DeleteAllPages',
+ %% Remove 'page' only defined for motif
+ {'DeletePage', [{"page", skip_member}]}, {'RemovePage', [{"page", skip_member}]},
+ 'GetCurrentPage','GetImageList','GetPage','GetPageCount',
+ 'GetPageImage','GetPageText','GetRowCount','GetSelection',
+ 'GetThemeBackgroundColour',
+ 'HitTest',
+ 'InsertPage',
+ %%'OnSelChange', callback
+ 'SetImageList','SetPadding','SetPageSize',
+ 'SetPageImage','SetPageText','SetSelection','ChangeSelection']}.
+
+{class,wxChoicebook, wxControl, [],
+ ['wxChoicebook','~wxChoicebook','AddPage','AdvanceSelection',
+ 'AssignImageList','Create','DeleteAllPages',
+ %% Remove 'page' only defined for motif
+ {'DeletePage', [{"page", skip_member}]}, {'RemovePage', [{"page", skip_member}]},
+ 'GetCurrentPage','GetImageList','GetPage','GetPageCount',
+ 'GetPageImage','GetPageText',
+ %% NOTEBOOK ONLY? 'GetRowCount', 'GetThemeBackgroundColour','SetPadding'
+ 'GetSelection',
+ 'HitTest',
+ 'InsertPage',
+ %%'OnSelChange', callback
+ 'SetImageList','SetPageSize',
+ 'SetPageImage','SetPageText','SetSelection','ChangeSelection']}.
+
+{class,wxToolbook, wxControl, [],
+ ['wxToolbook','~wxToolbook','AddPage','AdvanceSelection',
+ 'AssignImageList','Create','DeleteAllPages',
+ %% Remove 'page' only defined for motif
+ {'DeletePage', [{"page", skip_member}]}, {'RemovePage', [{"page", skip_member}]},
+ 'GetCurrentPage','GetImageList','GetPage','GetPageCount',
+ 'GetPageImage','GetPageText',
+ %% NOTEBOOK ONLY? 'GetRowCount', 'GetThemeBackgroundColour','SetPadding'
+ 'GetSelection',
+ 'HitTest',
+ 'InsertPage',
+ %%'OnSelChange', callback
+ 'SetImageList','SetPageSize',
+ 'SetPageImage','SetPageText','SetSelection','ChangeSelection']}.
+
+{class,wxListbook, wxControl, [],
+ ['wxListbook','~wxListbook','AddPage','AdvanceSelection',
+ 'AssignImageList','Create','DeleteAllPages',
+ %% Remove 'page' only defined for motif
+ {'DeletePage', [{"page", skip_member}]}, {'RemovePage', [{"page", skip_member}]},
+ 'GetCurrentPage','GetImageList','GetPage','GetPageCount',
+ 'GetPageImage','GetPageText',
+ %% NOTEBOOK ONLY? 'GetRowCount', 'GetThemeBackgroundColour','SetPadding'
+ 'GetSelection',
+ 'HitTest',
+ 'InsertPage',
+ %%'OnSelChange', callback
+ 'SetImageList','SetPageSize',
+ 'SetPageImage','SetPageText','SetSelection','ChangeSelection']}.
+
+{class,wxTreebook, wxControl, [],
+ ['wxTreebook','~wxTreebook','AddPage','AdvanceSelection',
+ 'AssignImageList','Create','DeleteAllPages',
+ %% Remove 'page' only defined for motif
+ {'DeletePage', [{"page", skip_member}]}, {'RemovePage', [{"page", skip_member}]},
+ 'GetCurrentPage','GetImageList','GetPage','GetPageCount',
+ 'GetPageImage','GetPageText',
+ %% NOTEBOOK ONLY? 'GetRowCount', 'GetThemeBackgroundColour','SetPadding'
+ 'GetSelection',
+ 'ExpandNode', 'IsNodeExpanded',
+ 'HitTest',
+ 'InsertPage','InsertSubPage',
+ %%'OnSelChange', callback
+ 'SetImageList','SetPageSize',
+ 'SetPageImage','SetPageText','SetSelection','ChangeSelection']}.
+
+
+{enum, wxTreeItemIcon, "wxTreeItemIcon_"}.
+
+{class, wxTreeCtrl, wxControl, [],
+ ['wxTreeCtrl','~wxTreeCtrl','AddRoot','AppendItem',
+ %% Not on Windows 'AssignButtonsImageList','GetButtonsImageList','SetButtonsImageList'
+ 'AssignImageList','AssignStateImageList','Collapse','CollapseAndReset',
+ 'Create','Delete','DeleteAllItems','DeleteChildren',{'EditLabel',1},
+ %'EndEditLabel',
+ 'EnsureVisible','Expand','GetBoundingRect',
+ 'GetChildrenCount','GetCount','GetEditControl',
+ %'GetFirstChild',
+ 'GetFirstVisibleItem',{'GetImageList',0},'GetIndent',
+ 'GetItemBackgroundColour','GetItemData','GetItemFont','GetItemImage',
+ 'GetItemText','GetItemTextColour','GetLastChild', % 'GetNextChild',
+ 'GetNextSibling','GetNextVisible','GetItemParent',%'GetParent',
+ 'GetPrevSibling','GetPrevVisible','GetRootItem',
+ 'GetSelection',{'GetSelections', [{return, nowhere},{"val",out}]},
+ 'GetStateImageList',{'HitTest', 1},
+ {'InsertItem',[{"insertAfter", skip_member}]},
+ 'IsBold','IsExpanded','IsSelected','IsVisible','ItemHasChildren',
+ %%'OnCompareItems',
+ 'PrependItem','ScrollTo','SelectItem',
+ 'SetIndent',{'SetImageList',1},'SetItemBackgroundColour',
+ 'SetItemBold','SetItemData','SetItemDropHighlight','SetItemFont',
+ 'SetItemHasChildren','SetItemImage','SetItemText',
+ 'SetItemTextColour','SetStateImageList','SetWindowStyle',{'SortChildren',1},
+ 'Toggle','ToggleItemSelection','Unselect','UnselectAll','UnselectItem']}.
+
+{class, wxScrollBar, wxControl, [],
+ ['wxScrollBar','~wxScrollBar','Create','GetRange','GetPageSize',
+ 'GetThumbPosition','GetThumbSize','SetThumbPosition','SetScrollbar']}.
+{class, wxSpinButton, wxControl, [],
+ ['wxSpinButton','~wxSpinButton','Create','GetMax','GetMin','GetValue','SetRange','SetValue']}.
+{class, wxSpinCtrl, wxControl, [],
+ ['wxSpinCtrl','Create','SetValue','GetValue','SetRange','SetSelection','GetMin','GetMax']}.
+
+{class, wxStaticText, wxControl, [],
+ ['wxStaticText','Create','GetLabel','SetLabel','Wrap']}.
+{class, wxStaticBitmap, wxControl, [],
+ ['wxStaticBitmap','Create','GetBitmap','SetBitmap'
+ %%wxStaticIcon::GetIcon wxStaticIcon::SetIcon
+ ]}.
+{class, wxRadioBox, wxControl, [],
+ [{'wxRadioBox',9},'~wxRadioBox',{'Create',9},'Enable',
+ 'GetSelection','GetString', 'SetSelection','Show',
+ 'GetColumnCount','GetItemHelpText','GetItemToolTip','GetItemFromPoint',
+ 'GetRowCount', 'IsItemEnabled','IsItemShown','SetItemHelpText','SetItemToolTip'
+ ]}.
+{class, wxRadioButton, wxControl, [],
+ ['wxRadioButton','~wxRadioButton','Create','GetValue','SetValue']}.
+
+{class, wxSlider, wxControl, [],
+ ['wxSlider','~wxSlider', %'ClearSel','ClearTicks',
+ 'Create','GetLineSize','GetMax','GetMin',
+ 'GetPageSize',%'GetSelEnd','GetSelStart',
+ 'GetThumbLength',%'GetTickFreq',
+ 'GetValue',
+ 'SetLineSize','SetPageSize','SetRange',%'SetSelection',
+ 'SetThumbLength',%'SetTick', 'SetTickFreq',
+ 'SetValue']}.
+
+{class, wxDialog, wxTopLevelWindow, [],
+ ['wxDialog','~wxDialog',%'Centre',
+ 'Create','CreateButtonSizer',
+ 'CreateStdDialogButtonSizer',%'DoOK',
+ 'EndModal','GetAffirmativeId',
+ 'GetReturnCode', %'GetTitle','GetToolBar','Iconize','IsIconized',
+ 'IsModal',
+ %%'OnApply','OnCancel','OnOK', 'OnSysColourChanged',
+ 'SetAffirmativeId', %'SetIcon','SetIcons','SetTitle',
+ %% 'SetModal', Deprecated
+ 'SetReturnCode','Show','ShowModal']}.
+
+{class, wxColourDialog, wxDialog, [],
+ ['wxColourDialog','~wxColourDialog','Create','GetColourData']}.
+
+{class, wxColourData, object, [],
+ ['wxColourData','~wxColourData','GetChooseFull','GetColour','GetCustomColour',
+ 'SetChooseFull','SetColour','SetCustomColour']}.
+
+{class, wxPalette, object, [],
+ [{'wxPalette',[{"n", {c_only,{size,0}}},{"red",[in,{base,binary}]},
+ {"green", [in,{base,binary}]},{"blue", [in,{base,binary}]}]},
+ '~wxPalette',
+ {'Create', [{"n", {c_only,{size,0}}},{"red",[in,{base,binary}]},
+ {"green", [in,{base,binary}]},{"blue", [in,{base,binary}]}]},
+ 'GetColoursCount','GetPixel',
+ 'GetRGB',
+ 'IsOk']}.
+
+{class, wxGenericDirDialog, wxDialog,
+ [{alias, [{wxGenericDirDialog,wxDirDialog}]}, {skip, [{wxDirDialog,0}]}],
+ ['wxDirDialog','~wxDirDialog','GetPath','GetMessage','SetMessage',
+ 'SetPath']}.
+
+{class, wxFileDialog, wxDialog, [{skip, [{wxFileDialog,0}]}],
+ ['wxFileDialog','~wxFileDialog','GetDirectory','GetFilename',
+ {'GetFilenames',[{"files", out}]},
+ 'GetFilterIndex','GetMessage','GetPath','GetPaths','GetWildcard',
+ 'SetDirectory','SetFilename','SetFilterIndex','SetMessage','SetPath',
+ 'SetWildcard']}.
+
+%% {class, wxGenericFileDialog, wxDialog, [],
+%% ['wxFileDialog','~wxFileDialog','GetDirectory','GetFilename','GetFilenames',
+%% 'GetFilterIndex','GetMessage','GetPath','GetPaths','GetStyle','GetWildcard',
+%% 'SetDirectory','SetFilename','SetFilterIndex','SetMessage','SetPath','SetStyle',
+%% 'SetWildcard']}.
+
+{class, wxPickerBase, wxControl, [],
+ ['SetInternalMargin','GetInternalMargin','SetTextCtrlProportion',
+ 'SetPickerCtrlProportion','GetTextCtrlProportion','GetPickerCtrlProportion',
+ 'HasTextCtrl','GetTextCtrl','IsTextCtrlGrowable','SetPickerCtrlGrowable',
+ 'SetTextCtrlGrowable','IsPickerCtrlGrowable']}.
+
+{class, wxFilePickerCtrl, wxPickerBase, [],
+ ['wxFilePickerCtrl','Create','GetPath','SetPath']}.
+
+{class, wxDirPickerCtrl, wxPickerBase, [],
+ ['wxDirPickerCtrl','Create','GetPath','SetPath']}.
+
+{class, wxColourPickerCtrl, wxPickerBase, [],
+ ['wxColourPickerCtrl','Create','GetColour','SetColour']}.
+
+{class, wxDatePickerCtrl, wxPickerBase, [],
+ ['wxDatePickerCtrl', %'Create',
+ 'GetRange', 'GetValue', %'SetFormat', Not always available
+ 'SetRange', 'SetValue']}.
+
+{class, wxFontPickerCtrl, wxPickerBase, [],
+ ['wxFontPickerCtrl','Create','GetSelectedFont','SetSelectedFont',
+ 'GetMaxPointSize','SetMaxPointSize']}.
+
+{class, wxGenericFindReplaceDialog, wxDialog,
+ [{alias, [{wxGenericFindReplaceDialog,wxFindReplaceDialog}]}],
+ ['wxFindReplaceDialog','~wxFindReplaceDialog','Create','GetData']}.
+
+{class, wxFindReplaceData, object, [],
+ ['wxFindReplaceData','~wxFindReplaceData','GetFindString','GetReplaceString',
+ 'GetFlags','SetFlags','SetFindString','SetReplaceString']}.
+
+{class, wxMultiChoiceDialog, wxDialog, [{skip, [{wxMultiChoiceDialog, 7}]}],
+ ['wxMultiChoiceDialog','GetSelections','SetSelections']}.
+{class, wxSingleChoiceDialog, wxDialog, [{skip, [{wxSingleChoiceDialog, 8}]}],
+ [{'wxSingleChoiceDialog', [{"clientData", [skip,in]}]},
+ 'GetSelection', %% 'GetSelectionClientData', obsolete
+ 'GetStringSelection','SetSelection']}.
+
+{class, wxTextEntryDialog, wxDialog, [],
+ ['wxTextEntryDialog','~wxTextEntryDialog','GetValue','SetValue']}.
+
+{class, wxPasswordEntryDialog, wxTextEntryDialog, [], ['wxPasswordEntryDialog']}.
+
+{class, wxFontData, object, [],
+ ['wxFontData','~wxFontData',
+ 'EnableEffects','GetAllowSymbols','GetColour','GetChosenFont',
+ 'GetEnableEffects','GetInitialFont','GetShowHelp','SetAllowSymbols',
+ 'SetChosenFont','SetColour','SetInitialFont','SetRange','SetShowHelp']}.
+
+{class, wxFontDialog, wxDialog,
+ [{skip, [{'wxFontDialog',1}, {'Create',2}]}], %% Not available on Mac!!
+ ['wxFontDialog','Create','GetFontData']}.
+
+{class, wxProgressDialog, wxDialog, [],
+ ['wxProgressDialog','~wxProgressDialog','Resume',{'Update', [{"skip", nowhere}]}]}.
+{class, wxMessageDialog, wxDialog, [],
+ ['wxMessageDialog', '~wxMessageDialog']}.
+
+{enum, wxPrintBin, "wxPRINTBIN_"}.
+{enum, wxDuplexMode, "wxDUPLEX_"}.
+{enum, wxPrintMode, "wxPRINT_MODE_"}.
+%%{enum, wxPaperSize,"wxPAPER_"}.
+
+{class, wxPageSetupDialog, object, [],
+ ['wxPageSetupDialog','~wxPageSetupDialog','GetPageSetupData', 'ShowModal']}.
+
+{class, wxPageSetupDialogData, object, [],
+ ['wxPageSetupDialogData','~wxPageSetupDialogData','EnableHelp','EnableMargins',
+ 'EnableOrientation','EnablePaper','EnablePrinter','GetDefaultMinMargins',
+ 'GetEnableMargins','GetEnableOrientation','GetEnablePaper','GetEnablePrinter',
+ 'GetEnableHelp','GetDefaultInfo','GetMarginTopLeft','GetMarginBottomRight',
+ 'GetMinMarginTopLeft','GetMinMarginBottomRight','GetPaperId','GetPaperSize',
+ 'GetPrintData','IsOk','SetDefaultInfo','SetDefaultMinMargins','SetMarginTopLeft',
+ 'SetMarginBottomRight','SetMinMarginTopLeft','SetMinMarginBottomRight',
+ 'SetPaperId','SetPaperSize','SetPrintData']}.
+{class, wxPrintDialog, wxDialog, [],
+ ['wxPrintDialog','~wxPrintDialog','GetPrintDialogData','GetPrintDC']}.
+{class,wxPrintDialogData, object, [],
+ ['wxPrintDialogData','~wxPrintDialogData','EnableHelp','EnablePageNumbers',
+ 'EnablePrintToFile','EnableSelection','GetAllPages','GetCollate','GetFromPage',
+ 'GetMaxPage','GetMinPage','GetNoCopies','GetPrintData','GetPrintToFile',
+ 'GetSelection','GetToPage','IsOk','SetCollate','SetFromPage','SetMaxPage',
+ 'SetMinPage','SetNoCopies','SetPrintData','SetPrintToFile','SetSelection',
+ %%'SetSetupDialog', not found
+ 'SetToPage']}.
+
+{class, wxPrintData, object, [],
+ ['wxPrintData','~wxPrintData','GetCollate','GetBin','GetColour',
+ 'GetDuplex','GetNoCopies','GetOrientation','GetPaperId','GetPrinterName',
+ 'GetQuality','IsOk','SetBin','SetCollate','SetColour','SetDuplex','SetNoCopies',
+ 'SetOrientation','SetPaperId','SetPrinterName','SetQuality']}.
+
+{class, wxPrintPreview, object, [],
+ ['wxPrintPreview','~wxPrintPreview','GetCanvas','GetCurrentPage',
+ 'GetFrame','GetMaxPage','GetMinPage','GetPrintout','GetPrintoutForPrinting',
+ 'IsOk','PaintPage','Print','RenderPage','SetCanvas','SetCurrentPage',
+ 'SetFrame','SetPrintout','SetZoom']}.
+
+{class, wxPreviewFrame, wxFrame, [],
+ ['wxPreviewFrame','~wxPreviewFrame','CreateControlBar','CreateCanvas',
+ 'Initialize','OnCloseWindow']}.
+
+{class, wxPreviewControlBar, wxPanel, [],
+['wxPreviewControlBar','~wxPreviewControlBar','CreateButtons','GetPrintPreview',
+ 'GetZoomControl','SetZoomControl']}.
+
+{class, wxPreviewCanvas, wxScrolledWindow, [], []}.
+
+{class, wxPrinter, object, [],
+ ['wxPrinter','CreateAbortWindow','GetAbort','GetLastError',
+ 'GetPrintDialogData','Print','PrintDialog','ReportError','Setup']}.
+
+{class, wxXmlResource, object, [],
+ ['wxXmlResource', '~wxXmlResource',
+ %%'AddHandler', removed wxXmlResourceHandler is not implemented yet
+ 'AttachUnknownControl',
+ 'ClearHandlers', 'CompareVersion',
+ 'Get', 'GetFlags', 'GetVersion',
+ {'GetXRCID', [{"str_id", [{single, array}]}]},
+ 'InitAllHandlers', 'Load',
+ 'LoadBitmap', 'LoadDialog', 'LoadFrame', 'LoadIcon', 'LoadMenu', 'LoadMenuBar', 'LoadPanel',
+ 'LoadToolBar', 'Set', 'SetFlags', 'Unload',
+ {xrcctrl,[{where, taylormade}]}
+ %,{'GetDomain', [{return, [{single, array}]}]}, 'SetDomain'
+ ]}.
+
+{class, wxHtmlEasyPrinting, object, [],
+ ['wxHtmlEasyPrinting','~wxHtmlEasyPrinting',
+ %'GetParentWindow', Not found
+ 'GetPrintData','GetPageSetupData','PreviewFile',
+ 'PreviewText','PrintFile','PrintText','PageSetup',
+ {'SetFonts',[{"sizes", [{single, array}, {def, "(int *) NULL"}]}]},
+ 'SetHeader','SetFooter'%,'SetParentWindow'
+ ]}.
+
+%%{class, wxVListBox, wxControl, [], []}.
+
+{class, wxGLCanvas, wxWindow,
+ [{skip, [{'SetCurrent', 2}]}], %% NA MAC
+ [{'wxGLCanvas', [{"attribList", [in, {single,array}]}]},
+ 'GetContext',
+ {'SetCurrent', [{post_hook,"if(This->GetContext()) setActiveGL(Ecmd.caller,This)"}]},
+ %%{'SetColour', [{"colour", [in, {single,array}]}]},
+ 'SwapBuffers']}.
+
+%% {class, wxGLContext, wxWindow, [], %% NA MAC or rather looks different on mac FIXME
+%% ['wxGLContext','SetCurrent']}.
+
+{class, wxAuiManager, wxEvtHandler, [{ifdef, wxUSE_AUI}],
+ ['wxAuiManager','~wxAuiManager','AddPane','DetachPane','GetAllPanes',
+ 'GetArtProvider','GetDockSizeConstraint','GetFlags','GetManagedWindow',
+ 'GetManager','GetPane','HideHint','InsertPane','LoadPaneInfo',
+ 'LoadPerspective',%'ProcessDockResult', Protected can be derived
+ 'SavePaneInfo','SavePerspective',
+ 'SetArtProvider','SetDockSizeConstraint','SetFlags','SetManagedWindow',
+ 'ShowHint','UnInit','Update']}.
+
+{class, wxAuiPaneInfo, root, [{ifdef, wxUSE_AUI}],
+ [
+ wxAuiPaneInfo,'~wxAuiPaneInfo',
+ 'BestSize','Bottom','BottomDockable','Caption','CaptionVisible',
+ 'Centre','CentrePane','CloseButton','DefaultPane','DestroyOnClose',
+ 'Direction','Dock',%'DockFixed',
+ 'Dockable','Fixed','Float',
+ 'Floatable','FloatingPosition','FloatingSize','Gripper','GripperTop',
+ 'HasBorder','HasCaption','HasCloseButton','HasFlag',
+ 'HasGripper','HasGripperTop','HasMaximizeButton','HasMinimizeButton',
+ 'HasPinButton','Hide','IsBottomDockable','IsDocked','IsFixed',
+ 'IsFloatable','IsFloating','IsLeftDockable','IsMovable','IsOk',
+ 'IsResizable','IsRightDockable','IsShown','IsToolbar','IsTopDockable',
+ 'Layer','Left','LeftDockable','MaxSize','MaximizeButton',
+ 'MinSize','MinimizeButton','Movable','Name',
+ 'PaneBorder','PinButton','Position','Resizable','Right',
+ 'RightDockable','Row','SafeSet','SetFlag','Show','ToolbarPane',
+ 'Top','TopDockable','Window']}.
+
+{class, wxAuiNotebook, wxControl, [{ifdef, wxUSE_AUI}],
+ ['wxAuiNotebook','AddPage',%'AdvanceSelection',
+ 'Create','DeletePage',
+ 'GetArtProvider',%%'GetHeightForPageHeight','GetTabCtrlHeight', not found
+ 'GetPage','GetPageBitmap',
+ 'GetPageCount','GetPageIndex','GetPageText','GetSelection',
+ 'InsertPage','RemovePage','SetArtProvider',
+ 'SetFont',%'SetNormalFont','SetSelectedFont','SetMeasuringFont',not found
+ 'SetPageBitmap','SetPageText','SetSelection','SetTabCtrlHeight',
+ 'SetUniformBitmapSize'%,'ShowWindowMenu'
+ ]}.
+
+{class,wxAuiTabArt, root, [{ifdef, wxUSE_AUI}],
+ [% Pure virtual funcs
+ %'Clone','DrawBackground','DrawButton','DrawTab','GetBestTabCtrlSize',
+ %'GetIndentSize','GetTabSize','SetFlags','SetMeasuringFont',
+ %'SetNormalFont','SetSelectedFont','SetSizingInfo'%,'ShowWindowList'
+ ]}.
+
+{class,wxAuiDockArt, root, [{ifdef, wxUSE_AUI}],
+ [%% 'wxAuiDockArt','~wxAuiDockArt' %,
+ %%'DrawBackground','DrawBorder','DrawCaption', %% Pure virtual funcs
+ %%'DrawGripper','DrawPaneButton','DrawSash',
+ %%'GetColor','GetColour','GetFont','GetMetric','SetColor','SetColour','SetFont','SetMetric'
+ ]}.
+
+{class, wxMDIParentFrame, wxFrame, [],
+ [
+ 'wxMDIParentFrame', '~wxMDIParentFrame', 'ActivateNext', 'ActivatePrevious',
+ 'ArrangeIcons', 'Cascade', 'Create',
+ %%'GetClientSize', 'GetToolBar', 'SetToolBar', defined in parent
+ 'GetActiveChild', 'GetClientWindow',
+ %% 'GetWindowMenu', 'SetWindowMenu', windows only
+ %%'OnCreateClient',
+ 'Tile']}.
+
+{class, wxMDIChildFrame, wxFrame, [],
+ ['wxMDIChildFrame','~wxMDIChildFrame','Activate','Create','Maximize','Restore']}.
+
+{class, wxMDIClientWindow, wxWindow, [],
+ ['wxMDIClientWindow','~wxMDIClientWindow','CreateClient']}.
+
+{class, wxLayoutAlgorithm, object, [],
+ ['wxLayoutAlgorithm', '~wxLayoutAlgorithm',
+ 'LayoutFrame', 'LayoutMDIFrame', 'LayoutWindow']}.
+
+%%%% EVENT's
+
+{class, wxEvent, object, [],
+ [%%'wxEvent','m','propagationLevel','Clone','GetEventObject','GetEventType',
+ 'GetId','GetSkipped',
+ {'GetTimestamp', [{return, [{mod,[unsigned]}]}]},
+ 'IsCommandEvent','ResumePropagation',
+ %% 'SetEventObject','SetEventType','SetId','SetTimestamp',
+ 'ShouldPropagate','Skip','StopPropagation'
+ ]}.
+
+{class, wxCommandEvent, wxEvent,
+ [{acc, [{m_cmdString, "GetString()"},
+ {m_commandInt, "GetInt()"}, {m_extraLong,"GetExtraLong()"}]},
+ {event,
+ [wxEVT_COMMAND_BUTTON_CLICKED,wxEVT_COMMAND_CHECKBOX_CLICKED,
+ wxEVT_COMMAND_CHOICE_SELECTED,wxEVT_COMMAND_LISTBOX_SELECTED,
+ wxEVT_COMMAND_LISTBOX_DOUBLECLICKED,wxEVT_COMMAND_TEXT_UPDATED,
+ wxEVT_COMMAND_TEXT_ENTER,wxEVT_COMMAND_MENU_SELECTED,
+ wxEVT_COMMAND_SLIDER_UPDATED,wxEVT_COMMAND_RADIOBOX_SELECTED,
+ wxEVT_COMMAND_RADIOBUTTON_SELECTED,wxEVT_COMMAND_SCROLLBAR_UPDATED,
+ wxEVT_COMMAND_VLBOX_SELECTED,wxEVT_COMMAND_COMBOBOX_SELECTED,
+ %% wxEVT_COMMAND_TOOL_CLICKED, This the exactly the same as command_menu_selected
+ %% I can't differ them
+ wxEVT_COMMAND_TOOL_RCLICKED,
+ wxEVT_COMMAND_TOOL_ENTER, wxEVT_COMMAND_CHECKLISTBOX_TOGGLED,
+ wxEVT_COMMAND_TOGGLEBUTTON_CLICKED,
+ wxEVT_COMMAND_LEFT_CLICK,wxEVT_COMMAND_LEFT_DCLICK,wxEVT_COMMAND_RIGHT_CLICK,
+ wxEVT_COMMAND_SET_FOCUS, wxEVT_COMMAND_KILL_FOCUS,
+ wxEVT_COMMAND_ENTER
+ ]}],
+ [{'GetClientObject',[{erl_func, "getClientData"}]},
+ 'GetExtraLong','GetInt','GetSelection','GetString','IsChecked',
+ 'IsSelection',%'SetClientData','SetClientObject','SetExtraLong',
+ 'SetInt','SetString'
+ ]}.
+
+{class, wxScrollEvent, wxCommandEvent,
+ [{acc, [{m_commandInt, "GetPosition()"}, {m_extraLong, "GetOrientation()"}]},
+ {mixed_event, wxSpinEvent},
+ {event,
+ [wxEVT_SCROLL_TOP,wxEVT_SCROLL_BOTTOM,wxEVT_SCROLL_LINEUP,
+ wxEVT_SCROLL_LINEDOWN,wxEVT_SCROLL_PAGEUP,
+ wxEVT_SCROLL_PAGEDOWN,wxEVT_SCROLL_THUMBTRACK,
+ wxEVT_SCROLL_THUMBRELEASE,wxEVT_SCROLL_CHANGED]}],
+ ['GetOrientation','GetPosition']}.
+{class, wxScrollWinEvent,wxEvent,
+ [{event,
+ [wxEVT_SCROLLWIN_TOP,wxEVT_SCROLLWIN_BOTTOM,wxEVT_SCROLLWIN_LINEUP,
+ wxEVT_SCROLLWIN_LINEDOWN,wxEVT_SCROLLWIN_PAGEUP,
+ wxEVT_SCROLLWIN_PAGEDOWN,wxEVT_SCROLLWIN_THUMBTRACK,
+ wxEVT_SCROLLWIN_THUMBRELEASE]}],
+ ['GetOrientation','GetPosition']}.
+
+{class, wxMouseEvent, wxEvent,
+ [{event,
+ [wxEVT_LEFT_DOWN,wxEVT_LEFT_UP,wxEVT_MIDDLE_DOWN,wxEVT_MIDDLE_UP,
+ wxEVT_RIGHT_DOWN,wxEVT_RIGHT_UP,wxEVT_MOTION,wxEVT_ENTER_WINDOW,
+ wxEVT_LEAVE_WINDOW,wxEVT_LEFT_DCLICK,wxEVT_MIDDLE_DCLICK,
+ wxEVT_RIGHT_DCLICK,wxEVT_MOUSEWHEEL,
+ wxEVT_NC_LEFT_DOWN,wxEVT_NC_LEFT_UP,
+ wxEVT_NC_MIDDLE_DOWN,wxEVT_NC_MIDDLE_UP,wxEVT_NC_RIGHT_DOWN,
+ wxEVT_NC_RIGHT_UP,wxEVT_NC_MOTION,wxEVT_NC_ENTER_WINDOW,
+ wxEVT_NC_LEAVE_WINDOW,wxEVT_NC_LEFT_DCLICK,wxEVT_NC_MIDDLE_DCLICK,
+ wxEVT_NC_RIGHT_DCLICK]}],
+ ['AltDown','Button','ButtonDClick','ButtonDown','ButtonUp','CmdDown','ControlDown',
+ 'Dragging', 'Entering', 'GetButton', 'GetPosition', 'GetLogicalPosition',
+ 'GetLinesPerAction', 'GetWheelRotation', 'GetWheelDelta', 'GetX', 'GetY',
+ 'IsButton', 'IsPageScroll', 'Leaving',
+ 'LeftDClick', 'LeftDown', 'LeftIsDown', 'LeftUp',
+ 'MetaDown',
+ 'MiddleDClick', 'MiddleDown', 'MiddleIsDown', 'MiddleUp',
+ 'Moving',
+ 'RightDClick', 'RightDown', 'RightIsDown', 'RightUp',
+ 'ShiftDown'
+ ]}.
+
+{class, wxSetCursorEvent, wxEvent, [{event,[wxEVT_SET_CURSOR]}],
+ ['GetCursor','GetX','GetY','HasCursor','SetCursor']}.
+
+{class, wxKeyEvent, wxEvent,
+ [{event,[wxEVT_CHAR,wxEVT_CHAR_HOOK,
+ wxEVT_KEY_DOWN,wxEVT_KEY_UP %,wxEVT_HOTKEY
+ ]}],
+ ['AltDown','CmdDown','ControlDown','GetKeyCode',
+ 'GetModifiers','GetPosition','GetRawKeyCode','GetRawKeyFlags',
+ 'GetUnicodeKey','GetX','GetY','HasModifiers','MetaDown',
+ 'ShiftDown'
+ ]}.
+
+{class, wxSizeEvent, wxEvent, [{event,[wxEVT_SIZE]}],
+ ['GetSize']}.
+{class, wxMoveEvent, wxEvent, [{event,[wxEVT_MOVE]}],
+ ['GetPosition']}.
+{class, wxPaintEvent, wxEvent, [{event,[wxEVT_PAINT,wxEVT_PAINT_ICON]}],[]}.
+{class, wxNcPaintEvent, wxEvent, [{event,[wxEVT_NC_PAINT]}],[]}.
+{class, wxEraseEvent, wxEvent,
+ [{acc, [{m_dc, "GetDC()"}]},
+ {event, [wxEVT_ERASE_BACKGROUND]}],
+ ['GetDC']}.
+{class, wxFocusEvent, wxEvent,
+ [{event,[wxEVT_SET_FOCUS,wxEVT_KILL_FOCUS]}],
+ ['GetWindow']}.
+{class,wxChildFocusEvent,wxCommandEvent,
+ [{event,[wxEVT_CHILD_FOCUS]}],
+ ['GetWindow']}.
+
+%% {class, wxActivateEvent, wxEvent, [{event,
+%% [wxEVT_ACTIVATE,wxEVT_ACTIVATE_APP,wxEVT_HIBERNATE]}],[]}.
+
+%%{class, wxInitDialogEvent, wxEvent, [{event, []}],[]}.
+
+{class, wxMenuEvent, wxEvent,
+ [{event, [wxEVT_MENU_OPEN,wxEVT_MENU_CLOSE,wxEVT_MENU_HIGHLIGHT]}],
+ ['GetMenu','GetMenuId','IsPopup']}.
+{class, wxCloseEvent, wxEvent,
+ [{event, [wxEVT_CLOSE_WINDOW,wxEVT_END_SESSION,wxEVT_QUERY_END_SESSION]}],
+ ['CanVeto','GetLoggingOff','SetCanVeto','SetLoggingOff','Veto']}.
+{class, wxShowEvent, wxEvent, [{event,[wxEVT_SHOW]}],['SetShow','GetShow']}.
+{class, wxIconizeEvent, wxEvent, [{event,[wxEVT_ICONIZE]}],['Iconized']}.
+{class, wxMaximizeEvent, wxEvent, [{event,[wxEVT_MAXIMIZE]}],[]}.
+{class, wxJoystickEvent, wxEvent,
+ [{event,[wxEVT_JOY_BUTTON_DOWN,wxEVT_JOY_BUTTON_UP,
+ wxEVT_JOY_MOVE,wxEVT_JOY_ZMOVE]}],
+ ['ButtonDown','ButtonIsDown','ButtonUp','GetButtonChange','GetButtonState',
+ 'GetJoystick','GetPosition','GetZPosition','IsButton','IsMove','IsZMove']}.
+
+%% {class, wxDropFilesEvent, wxEvent, [{event,[wxEVT_DROP_FILES]}],[]}. %FIXME
+
+{enum, wxUpdateUIMode, "wxUPDATE_UI_"}.
+
+{class, wxUpdateUIEvent, wxCommandEvent,
+ [{event,[wxEVT_UPDATE_UI]}],
+ ['CanUpdate','Check','Enable','Show','GetChecked','GetEnabled','GetShown',
+ 'GetSetChecked','GetSetEnabled','GetSetShown','GetSetText','GetText',
+ 'GetMode','GetUpdateInterval','ResetUpdateTime','SetMode','SetText',
+ 'SetUpdateInterval']}.
+{class, wxSysColourChangedEvent, wxEvent,
+ [{event,[wxEVT_SYS_COLOUR_CHANGED]}],[]}.
+{class, wxMouseCaptureChangedEvent, wxEvent,
+ [{event,[wxEVT_MOUSE_CAPTURE_CHANGED]}],['GetCapturedWindow']}.
+{class, wxDisplayChangedEvent, wxEvent, [{event,[wxEVT_DISPLAY_CHANGED]}],[]}.
+{class, wxPaletteChangedEvent, wxEvent,
+ [{event,[wxEVT_PALETTE_CHANGED]}],['SetChangedWindow','GetChangedWindow']}.
+{class, wxQueryNewPaletteEvent, wxEvent,
+ [{event,[wxEVT_QUERY_NEW_PALETTE]}],['SetPaletteRealized','GetPaletteRealized']}.
+{class, wxNavigationKeyEvent, wxEvent, [{event,[wxEVT_NAVIGATION_KEY]}],
+ ['GetDirection','SetDirection','IsWindowChange','SetWindowChange',
+ 'IsFromTab','SetFromTab','GetCurrentFocus','SetCurrentFocus']}.
+{class, wxWindowCreateEvent, wxCommandEvent, [{event,[wxEVT_CREATE]}],[]}.
+{class, wxWindowDestroyEvent, wxCommandEvent, [{event,[wxEVT_DESTROY]}],[]}.
+{enum, {"wxHelpEvent","Origin"}, "wxHelpEvent::Origin_"}.
+{class, wxHelpEvent, wxEvent, [{event,[wxEVT_HELP,wxEVT_DETAILED_HELP]}],
+ [%%{'GetOrigin', [{return, [{type,"wxHelpEvent::Origin"}]}]},
+ 'GetOrigin',
+ 'GetPosition',
+ %%{'SetOrigin', [{"origin", [{type,"wxHelpEvent::Origin"}]}]},
+ 'SetOrigin',
+ 'SetPosition']}.
+
+{class, wxContextMenuEvent, wxCommandEvent, [{event,[wxEVT_CONTEXT_MENU]}],
+ ['GetPosition','SetPosition']}.
+{enum, wxIdleMode, "wxIDLE_"}.
+{class, wxIdleEvent, wxEvent, [{event,[wxEVT_IDLE]}],
+ ['CanSend','GetMode','RequestMore','MoreRequested','SetMode']}.
+{class, wxGridEvent, wxNotifyEvent,
+ [{acc, [{m_row, "GetRow()"}, {m_col, "GetCol()"}, {m_x, "GetPosition().x"},{m_y, "GetPosition().y"},
+ {m_selecting, "Selecting()"},{m_control,"ControlDown()"},
+ {m_meta, "MetaDown()"}, {m_shift, "ShiftDown()"},{m_alt,"AltDown()"}]},
+ {event,[wxEVT_GRID_CELL_LEFT_CLICK, wxEVT_GRID_CELL_RIGHT_CLICK, wxEVT_GRID_CELL_LEFT_DCLICK,
+ wxEVT_GRID_CELL_RIGHT_DCLICK, wxEVT_GRID_LABEL_LEFT_CLICK, wxEVT_GRID_LABEL_RIGHT_CLICK,
+ wxEVT_GRID_LABEL_LEFT_DCLICK, wxEVT_GRID_LABEL_RIGHT_DCLICK, wxEVT_GRID_ROW_SIZE,
+ wxEVT_GRID_COL_SIZE, wxEVT_GRID_RANGE_SELECT, wxEVT_GRID_CELL_CHANGE, wxEVT_GRID_SELECT_CELL,
+ wxEVT_GRID_EDITOR_SHOWN, wxEVT_GRID_EDITOR_HIDDEN, wxEVT_GRID_EDITOR_CREATED,
+ wxEVT_GRID_CELL_BEGIN_DRAG]}],
+ ['AltDown','ControlDown','GetCol','GetPosition','GetRow','MetaDown','Selecting','ShiftDown']}.
+
+{class, wxNotifyEvent, wxCommandEvent, [], ['Allow','IsAllowed','Veto']}.
+
+{enum, wxSashDragStatus, ""}.
+{enum, wxSashEdgePosition, ""}.
+{class, wxSashEvent, wxCommandEvent,
+ [{acc, [{m_edge, "GetEdge()"}, {m_dragStatus,"GetDragStatus()"}, {m_dragRect,"GetDragRect()"}]},
+ {event,[wxEVT_SASH_DRAGGED
+ %% , wxEVT_SASH_DRAGGED_RANGE Non exitent use connect with id, lastId
+ ]}],
+ ['GetEdge','GetDragRect','GetDragStatus']}.
+
+{class, wxListEvent, wxNotifyEvent,
+ [{acc, [{m_itemIndex, "GetIndex()"}, {m_code, "GetKeyCode()"},
+ {m_pointDrag, "GetPoint()"}, {m_item, skip}]},
+ {event, [wxEVT_COMMAND_LIST_BEGIN_DRAG,wxEVT_COMMAND_LIST_BEGIN_RDRAG,
+ wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT,wxEVT_COMMAND_LIST_END_LABEL_EDIT,
+ wxEVT_COMMAND_LIST_DELETE_ITEM,wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS,
+ wxEVT_COMMAND_LIST_KEY_DOWN,
+ wxEVT_COMMAND_LIST_INSERT_ITEM,
+ wxEVT_COMMAND_LIST_COL_CLICK,wxEVT_COMMAND_LIST_COL_RIGHT_CLICK,
+ wxEVT_COMMAND_LIST_COL_BEGIN_DRAG,wxEVT_COMMAND_LIST_COL_DRAGGING,
+ wxEVT_COMMAND_LIST_COL_END_DRAG,
+
+ wxEVT_COMMAND_LIST_ITEM_SELECTED,wxEVT_COMMAND_LIST_ITEM_DESELECTED,
+ wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK,wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK,
+ wxEVT_COMMAND_LIST_ITEM_ACTIVATED,wxEVT_COMMAND_LIST_ITEM_FOCUSED,
+
+ wxEVT_COMMAND_LIST_CACHE_HINT]}],
+ [
+ 'GetCacheFrom','GetCacheTo','GetKeyCode','GetIndex','GetColumn',
+ 'GetPoint','GetLabel','GetText','GetImage','GetData','GetMask','GetItem',
+ 'IsEditCancelled'
+ ]}.
+
+{class, wxDateEvent, wxCommandEvent,
+ [{acc, [{m_date, "GetDate()"}]}, {event,[wxEVT_DATE_CHANGED]}],
+ [
+ 'GetDate'
+ ]}.
+
+{class, wxCalendarEvent, wxDateEvent,
+ [{event,[wxEVT_CALENDAR_SEL_CHANGED, wxEVT_CALENDAR_DAY_CHANGED,
+ wxEVT_CALENDAR_MONTH_CHANGED, wxEVT_CALENDAR_YEAR_CHANGED,
+ wxEVT_CALENDAR_DOUBLECLICKED, wxEVT_CALENDAR_WEEKDAY_CLICKED]}],
+ [
+ 'GetWeekDay'
+ ]}.
+
+{class, wxFileDirPickerEvent, wxCommandEvent,
+ [{event, [wxEVT_COMMAND_FILEPICKER_CHANGED, wxEVT_COMMAND_DIRPICKER_CHANGED]},
+ {acc, [{m_path, "GetPath()"}]}],
+ ['GetPath']}.
+
+{class, wxColourPickerEvent, wxCommandEvent,
+ [{event, [wxEVT_COMMAND_COLOURPICKER_CHANGED]},
+ {acc, [{m_colour, "GetColour()"}]}],
+ ['GetColour']}.
+
+{class, wxFontPickerEvent, wxCommandEvent,
+ [{event, [wxEVT_COMMAND_FONTPICKER_CHANGED]},
+ {acc, [{m_font, "GetFont()"}]}],
+ ['GetFont']}.
+
+{class, wxStyledTextEvent, wxCommandEvent,
+ [{event, [wxEVT_STC_CHANGE, wxEVT_STC_STYLENEEDED, wxEVT_STC_CHARADDED,
+ wxEVT_STC_SAVEPOINTREACHED, wxEVT_STC_SAVEPOINTLEFT, wxEVT_STC_ROMODIFYATTEMPT,
+ wxEVT_STC_KEY,wxEVT_STC_DOUBLECLICK,wxEVT_STC_UPDATEUI,wxEVT_STC_MODIFIED,
+ wxEVT_STC_MACRORECORD,wxEVT_STC_MARGINCLICK,wxEVT_STC_NEEDSHOWN,wxEVT_STC_PAINTED,
+ wxEVT_STC_USERLISTSELECTION,wxEVT_STC_URIDROPPED,wxEVT_STC_DWELLSTART,
+ wxEVT_STC_DWELLEND,wxEVT_STC_START_DRAG,wxEVT_STC_DRAG_OVER,wxEVT_STC_DO_DROP,
+ wxEVT_STC_ZOOM,wxEVT_STC_HOTSPOT_CLICK,wxEVT_STC_HOTSPOT_DCLICK,
+ wxEVT_STC_CALLTIP_CLICK,wxEVT_STC_AUTOCOMP_SELECTION]},
+ {acc, [{m_position,"GetPosition()"},{m_key,"GetKey()"}, {m_modifiers,"GetModifiers()"},
+ {m_modificationType,"GetModificationType()"},{m_text,"GetText()"},
+ {m_length,"GetLength()"},{m_linesAdded,"GetLinesAdded()"},{m_line,"GetLine()"},
+ {m_foldLevelNow,"GetFoldLevelNow()"}, {m_foldLevelPrev,"GetFoldLevelPrev()"},
+ {m_margin,"GetMargin()"}, {m_message,"GetMessage()"}, {m_wParam,"GetWParam()"},
+ {m_lParam,"GetLParam()"}, {m_listType,"GetListType()"},{m_x,"GetX()"},
+ {m_y,"GetY()"}, {m_dragText,"GetDragText()"}, {m_dragAllowMove,"GetDragAllowMove()"},
+ {m_dragResult,"GetDragResult()"}]}],
+ ['GetPosition','GetKey','GetModifiers','GetModificationType','GetText','GetLength',
+ 'GetLinesAdded','GetLine','GetFoldLevelNow','GetFoldLevelPrev','GetMargin',
+ 'GetMessage','GetWParam','GetLParam','GetListType','GetX','GetY',
+ 'GetDragText','GetDragAllowMove','GetDragResult','GetShift','GetControl','GetAlt']}.
+
+%%{class, , wxEvent, [{event,[]}],[]}.
+
+
+%% Testing generation on static classless funcs
+{class, utils, static, [],
+ ['wxGetKeyState', 'wxGetMousePosition', 'wxGetMouseState',
+ 'wxSetDetectableAutoRepeat',
+ 'wxBell',
+ 'wxFindMenuItemId', 'wxGenericFindWindowAtPoint', 'wxFindWindowAtPoint',
+ 'wxBeginBusyCursor', 'wxEndBusyCursor', 'wxIsBusy',
+ 'wxShutdown', {'wxShell', 1}, 'wxLaunchDefaultBrowser',
+ {'wxGetEmailAddress',0}, {'wxGetUserId',0}, {'wxGetHomeDir',0},
+ 'wxNewId', 'wxRegisterId', 'wxGetCurrentId',
+ 'wxGetOsDescription', 'wxIsPlatformLittleEndian', 'wxIsPlatform64Bit'
+ ]}.
+
+{class, wxPrintout, object, [{alias, [{wxePrintout, wxePrintout}]}],
+ [{'wxPrintout', [{where, taylormade}]},'~wxPrintout',
+ 'GetDC', %% 'GetPageInfo',Callback
+ 'GetPageSizeMM','GetPageSizePixels','GetPaperRectPixels',
+ 'GetPPIPrinter','GetPPIScreen','GetTitle', %% 'HasPage', Callback
+ 'IsPreview',
+ 'FitThisSizeToPaper','FitThisSizeToPage','FitThisSizeToPageMargins',
+ 'MapScreenSizeToPaper','MapScreenSizeToPage','MapScreenSizeToPageMargins','MapScreenSizeToDevice',
+ 'GetLogicalPaperRect','GetLogicalPageRect','GetLogicalPageMarginsRect','SetLogicalOrigin',
+ 'OffsetLogicalOrigin']}.
+
+%%%%%%%%%%%%%%%%
+%% Test requires stc
+{class, wxStyledTextCtrl, wxControl, [],
+ ['wxStyledTextCtrl','~wxStyledTextCtrl','Create', 'AddText', 'AddStyledText', 'InsertText',
+ 'ClearAll', 'ClearDocumentStyle', 'GetLength', 'GetCharAt', 'GetCurrentPos', 'GetAnchor',
+ 'GetStyleAt', 'Redo', 'SetUndoCollection', 'SelectAll', 'SetSavePoint', 'GetStyledText',
+ 'CanRedo', 'MarkerLineFromHandle', 'MarkerDeleteHandle', 'GetUndoCollection',
+ 'GetViewWhiteSpace', 'SetViewWhiteSpace',
+ 'PositionFromPoint', 'PositionFromPointClose', 'GotoLine', 'GotoPos', 'SetAnchor',
+ {'GetCurLine', [{"linePos", [out]}]}, 'GetEndStyled', 'ConvertEOLs', 'GetEOLMode', 'SetEOLMode',
+ 'StartStyling', 'SetStyling', 'GetBufferedDraw', 'SetBufferedDraw', 'SetTabWidth', 'GetTabWidth',
+ 'SetCodePage', 'MarkerDefine', 'MarkerSetForeground', 'MarkerSetBackground', 'MarkerAdd', 'MarkerDelete',
+ 'MarkerDeleteAll', 'MarkerGet', 'MarkerNext', 'MarkerPrevious', 'MarkerDefineBitmap', 'MarkerAddSet',
+ 'MarkerSetAlpha', 'SetMarginType', 'GetMarginType', 'SetMarginWidth', 'GetMarginWidth', 'SetMarginMask',
+ 'GetMarginMask', 'SetMarginSensitive', 'GetMarginSensitive', 'StyleClearAll', 'StyleSetForeground',
+ 'StyleSetBackground', 'StyleSetBold', 'StyleSetItalic', 'StyleSetSize', 'StyleSetFaceName',
+ 'StyleSetEOLFilled', 'StyleResetDefault', 'StyleSetUnderline', 'StyleSetCase', 'StyleSetHotSpot',
+ 'SetSelForeground', 'SetSelBackground', 'GetSelAlpha', 'SetSelAlpha', 'SetCaretForeground',
+ 'CmdKeyAssign', 'CmdKeyClear', 'CmdKeyClearAll', 'SetStyleBytes', 'StyleSetVisible', 'GetCaretPeriod',
+ 'SetCaretPeriod', 'SetWordChars', 'BeginUndoAction', 'EndUndoAction', 'IndicatorSetStyle',
+ 'IndicatorGetStyle', 'IndicatorSetForeground', 'IndicatorGetForeground', 'SetWhitespaceForeground',
+ 'SetWhitespaceBackground', 'GetStyleBits', 'SetLineState', 'GetLineState', 'GetMaxLineState',
+ 'GetCaretLineVisible', 'SetCaretLineVisible', 'GetCaretLineBackground', 'SetCaretLineBackground',
+ 'AutoCompShow', 'AutoCompCancel', 'AutoCompActive', 'AutoCompPosStart', 'AutoCompComplete',
+ 'AutoCompStops', 'AutoCompSetSeparator', 'AutoCompGetSeparator', 'AutoCompSelect',
+ 'AutoCompSetCancelAtStart', 'AutoCompGetCancelAtStart', 'AutoCompSetFillUps', 'AutoCompSetChooseSingle',
+ 'AutoCompGetChooseSingle', 'AutoCompSetIgnoreCase', 'AutoCompGetIgnoreCase', 'UserListShow',
+ 'AutoCompSetAutoHide', 'AutoCompGetAutoHide', 'AutoCompSetDropRestOfWord', 'AutoCompGetDropRestOfWord',
+ 'RegisterImage', 'ClearRegisteredImages', 'AutoCompGetTypeSeparator', 'AutoCompSetTypeSeparator',
+ 'AutoCompSetMaxWidth', 'AutoCompGetMaxWidth', 'AutoCompSetMaxHeight', 'AutoCompGetMaxHeight',
+ 'SetIndent', 'GetIndent', 'SetUseTabs', 'GetUseTabs', 'SetLineIndentation', 'GetLineIndentation',
+ 'GetLineIndentPosition', 'GetColumn', 'SetUseHorizontalScrollBar', 'GetUseHorizontalScrollBar',
+ 'SetIndentationGuides', 'GetIndentationGuides', 'SetHighlightGuide', 'GetHighlightGuide',
+ 'GetLineEndPosition', 'GetCodePage', 'GetCaretForeground', 'GetReadOnly', 'SetCurrentPos',
+ 'SetSelectionStart', 'GetSelectionStart', 'SetSelectionEnd', 'GetSelectionEnd', 'SetPrintMagnification',
+ 'GetPrintMagnification', 'SetPrintColourMode', 'GetPrintColourMode', 'FindText', 'FormatRange',
+ 'GetFirstVisibleLine', 'GetLine', 'GetLineCount', 'SetMarginLeft', 'GetMarginLeft', 'SetMarginRight',
+ 'GetMarginRight', 'GetModify', 'SetSelection', 'GetSelectedText', 'GetTextRange', 'HideSelection',
+ 'LineFromPosition', 'PositionFromLine', 'LineScroll', 'EnsureCaretVisible', 'ReplaceSelection',
+ 'SetReadOnly', 'CanPaste', 'CanUndo', 'EmptyUndoBuffer', 'Undo', 'Cut', 'Copy', 'Paste', 'Clear',
+ 'SetText', 'GetText', 'GetTextLength', 'GetOvertype', 'SetCaretWidth', 'GetCaretWidth',
+ 'SetTargetStart', 'GetTargetStart', 'SetTargetEnd', 'GetTargetEnd', 'ReplaceTarget', 'SearchInTarget',
+ 'SetSearchFlags', 'GetSearchFlags', 'CallTipShow', 'CallTipCancel', 'CallTipActive', 'CallTipPosAtStart',
+ 'CallTipSetHighlight', 'CallTipSetBackground', 'CallTipSetForeground', 'CallTipSetForegroundHighlight',
+ 'CallTipUseStyle', 'VisibleFromDocLine', 'DocLineFromVisible', 'WrapCount', 'SetFoldLevel', 'GetFoldLevel',
+ 'GetLastChild', 'GetFoldParent', 'ShowLines', 'HideLines', 'GetLineVisible', 'SetFoldExpanded',
+ 'GetFoldExpanded', 'ToggleFold', 'EnsureVisible', 'SetFoldFlags', 'EnsureVisibleEnforcePolicy',
+ 'SetTabIndents', 'GetTabIndents', 'SetBackSpaceUnIndents', 'GetBackSpaceUnIndents', 'SetMouseDwellTime',
+ 'GetMouseDwellTime', 'WordStartPosition', 'WordEndPosition', 'SetWrapMode', 'GetWrapMode',
+ 'SetWrapVisualFlags', 'GetWrapVisualFlags', 'SetWrapVisualFlagsLocation', 'GetWrapVisualFlagsLocation',
+ 'SetWrapStartIndent', 'GetWrapStartIndent', 'SetLayoutCache', 'GetLayoutCache', 'SetScrollWidth',
+ 'GetScrollWidth', 'TextWidth', 'GetEndAtLastLine', 'TextHeight', 'SetUseVerticalScrollBar',
+ 'GetUseVerticalScrollBar', 'AppendText', 'GetTwoPhaseDraw', 'SetTwoPhaseDraw', 'TargetFromSelection',
+ 'LinesJoin', 'LinesSplit', 'SetFoldMarginColour', 'SetFoldMarginHiColour', 'LineDown', 'LineDownExtend',
+ 'LineUp', 'LineUpExtend', 'CharLeft', 'CharLeftExtend', 'CharRight', 'CharRightExtend', 'WordLeft',
+ 'WordLeftExtend', 'WordRight', 'WordRightExtend', 'Home', 'HomeExtend', 'LineEnd', 'LineEndExtend',
+ 'DocumentStart', 'DocumentStartExtend', 'DocumentEnd', 'DocumentEndExtend', 'PageUp', 'PageUpExtend',
+ 'PageDown', 'PageDownExtend', 'EditToggleOvertype', 'Cancel', 'DeleteBack', 'Tab', 'BackTab', 'NewLine',
+ 'FormFeed', 'VCHome', 'VCHomeExtend', 'ZoomIn', 'ZoomOut', 'DelWordLeft', 'DelWordRight', 'LineCut',
+ 'LineDelete', 'LineTranspose', 'LineDuplicate', 'LowerCase', 'UpperCase', 'LineScrollDown', 'LineScrollUp',
+ 'DeleteBackNotLine', 'HomeDisplay', 'HomeDisplayExtend', 'LineEndDisplay', 'LineEndDisplayExtend',
+ 'HomeWrapExtend', 'LineEndWrap', 'LineEndWrapExtend', 'VCHomeWrap', 'VCHomeWrapExtend', 'LineCopy',
+ 'MoveCaretInsideView', 'LineLength', 'BraceHighlight', 'BraceBadLight', 'BraceMatch', 'GetViewEOL',
+ 'SetViewEOL', %'GetDocPointer', 'SetDocPointer', Hmm void pointers
+ 'SetModEventMask', 'GetEdgeColumn', 'SetEdgeColumn',
+ 'GetEdgeMode', 'GetEdgeColour', 'SetEdgeColour', 'SearchAnchor', 'SearchNext',
+ 'SearchPrev', 'LinesOnScreen',
+ 'UsePopUp', 'SelectionIsRectangle', 'SetZoom', 'GetZoom',
+ %%'CreateDocument', 'AddRefDocument', 'ReleaseDocument', Hmm void pointers
+ 'GetModEventMask', 'SetSTCFocus', 'GetSTCFocus', 'SetStatus', 'GetStatus',
+ 'SetMouseDownCaptures', 'GetMouseDownCaptures', 'SetSTCCursor', 'GetSTCCursor',
+ 'SetControlCharSymbol', 'GetControlCharSymbol', 'WordPartLeft',
+ 'WordPartLeftExtend', 'WordPartRight', 'WordPartRightExtend',
+ 'SetVisiblePolicy', 'DelLineLeft', 'DelLineRight',
+ 'GetXOffset', 'ChooseCaretX', 'SetXCaretPolicy',
+ 'SetYCaretPolicy', 'GetPrintWrapMode',
+ 'SetHotspotActiveForeground', 'SetHotspotActiveBackground',
+ 'SetHotspotActiveUnderline', 'SetHotspotSingleLine',
+ 'ParaDownExtend', 'ParaUp', 'ParaUpExtend',
+ 'PositionBefore', 'PositionAfter', 'CopyRange', 'CopyText',
+ 'SetSelectionMode', 'GetSelectionMode', 'LineDownRectExtend',
+ 'LineUpRectExtend', 'CharLeftRectExtend', 'CharRightRectExtend',
+ 'HomeRectExtend', 'VCHomeRectExtend',
+ 'LineEndRectExtend', 'PageUpRectExtend', 'PageDownRectExtend',
+ 'StutteredPageUp', 'StutteredPageUpExtend', 'StutteredPageDown', 'StutteredPageDownExtend',
+ 'WordLeftEnd', 'WordLeftEndExtend', 'WordRightEnd',
+ 'WordRightEndExtend', 'SetWhitespaceChars', 'SetCharsDefault', 'AutoCompGetCurrent', 'Allocate',
+ 'FindColumn', 'GetCaretSticky', 'SetCaretSticky', 'ToggleCaretSticky', 'SetPasteConvertEndings',
+ 'GetPasteConvertEndings', 'SelectionDuplicate', 'SetCaretLineBackAlpha', 'GetCaretLineBackAlpha',
+ 'StartRecord', 'StopRecord', 'SetLexer', 'GetLexer', 'Colourise', 'SetProperty', 'SetKeyWords',
+ 'SetLexerLanguage', 'GetProperty', 'GetStyleBitsNeeded', 'GetCurrentLine', 'StyleSetSpec',
+ 'StyleSetFont', 'StyleSetFontAttr', 'StyleSetCharacterSet', 'StyleSetFontEncoding',
+ 'CmdKeyExecute',
+ 'SetMargins', {'GetSelection', [{"startPos", [out]}, {"endPos",[out]}]},
+ 'PointFromPosition', 'ScrollToLine', 'ScrollToColumn', 'SendMsg',
+ 'SetVScrollBar', 'SetHScrollBar', 'GetLastKeydownProcessed', 'SetLastKeydownProcessed',
+ 'SaveFile', 'LoadFile', 'DoDragOver', 'DoDropText', 'GetUseAntiAliasing',
+ {'AddTextRaw', [{"text", [in, {base, binary}]}]},
+ {'InsertTextRaw', [{"text", [in, {base, binary}]}]},
+ {'GetCurLineRaw', [{return,{base,{binary,"strlen(Result)"}}}, {"linePos", [out]}]},
+ {'GetLineRaw',[{return,{base,{binary,"strlen(Result)"}}}]},
+ {'GetSelectedTextRaw', [{return,{base,{binary,"strlen(Result)"}}}]},
+ {'GetTextRangeRaw', [{return,{base,{binary,"strlen(Result)"}}}]},
+ {'SetTextRaw', [{"text", [in, {base, binary}]}]},
+ {'GetTextRaw', [{return,{base,{binary,"strlen(Result)"}}}]},
+ {'AppendTextRaw', [{"text", [in, {base, binary}]}]}]}.
+
+{class, wxArtProvider, object, [],
+ [{'GetBitmap', [{"client", {def,"wxART_OTHER"}}]},
+ {'GetIcon', [{"client", {def,"wxART_OTHER"}}]}]}.
+
+{class, wxTreeEvent, wxNotifyEvent,
+ [{acc, [{m_item, "GetItem()"}, {m_itemOld, "GetOldItem()"},
+ {m_pointDrag, "GetPoint()"}]},
+ {event, [wxEVT_COMMAND_TREE_BEGIN_DRAG, wxEVT_COMMAND_TREE_BEGIN_RDRAG,
+ wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT, wxEVT_COMMAND_TREE_END_LABEL_EDIT,
+ wxEVT_COMMAND_TREE_DELETE_ITEM, wxEVT_COMMAND_TREE_GET_INFO,
+ wxEVT_COMMAND_TREE_SET_INFO, wxEVT_COMMAND_TREE_ITEM_EXPANDED,
+ wxEVT_COMMAND_TREE_ITEM_EXPANDING, wxEVT_COMMAND_TREE_ITEM_COLLAPSED,
+ wxEVT_COMMAND_TREE_ITEM_COLLAPSING, wxEVT_COMMAND_TREE_SEL_CHANGED,
+ wxEVT_COMMAND_TREE_SEL_CHANGING, wxEVT_COMMAND_TREE_KEY_DOWN,
+ wxEVT_COMMAND_TREE_ITEM_ACTIVATED, wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK,
+ wxEVT_COMMAND_TREE_ITEM_MIDDLE_CLICK, wxEVT_COMMAND_TREE_END_DRAG,
+ wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK, wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP,
+ wxEVT_COMMAND_TREE_ITEM_MENU]}
+ ],
+ ['GetKeyCode','GetItem','GetKeyEvent','GetLabel','GetOldItem','GetPoint',
+ 'IsEditCancelled','SetToolTip']}.
+
+{class, wxNotebookEvent, wxNotifyEvent,
+ [{event, [wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
+ wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING]}],
+ ['GetOldSelection','GetSelection','SetOldSelection','SetSelection']}.
+
+
+{class, wxDataObject, root, [], []}.
+
+{class, wxFileDataObject, wxDataObject, [],
+ ['wxFileDataObject', 'AddFile','GetFilenames']}.
+{class, wxTextDataObject, wxDataObject, [],
+ ['wxTextDataObject', 'GetTextLength', 'GetText', 'SetText']}.
+{class, wxBitmapDataObject, wxDataObject, [],
+ [{'wxBitmapDataObject',1}, 'GetBitmap','SetBitmap']}.
+
+{class, wxClipboard, object, [],
+ ['wxClipboard','~wxClipboard','AddData','Clear','Close',
+ 'Flush','GetData','IsOpened',
+ 'Open','SetData','UsePrimarySelection'
+ , {'IsSupported', [{"format", [{type, "wxDataFormatId"}, {single,true}]}]},
+ 'Get'
+ ]}.
+
+{class, wxSpinEvent, wxNotifyEvent,
+ [{acc, [{m_commandInt, "GetPosition()"}]},
+ {event, [wxEVT_COMMAND_SPINCTRL_UPDATED,
+ {wxEVT_SPIN_UP, wxEVT_SCROLL_LINEUP, wxScrollEvent},
+ {wxEVT_SPIN_DOWN, wxEVT_SCROLL_LINEDOWN, wxScrollEvent},
+ {wxEVT_SPIN, wxEVT_SCROLL_THUMBTRACK, wxScrollEvent}
+ ]}],
+ ['GetPosition', 'SetPosition']}.
+
+{class, wxSplitterWindow, wxWindow, [],
+ [
+ 'wxSplitterWindow', '~wxSplitterWindow', 'Create', 'GetMinimumPaneSize', 'GetSashGravity',
+ 'GetSashPosition', 'GetSplitMode', 'GetWindow1', 'GetWindow2', 'Initialize', 'IsSplit',
+ %% 'OnDoubleClickSash', 'OnUnsplit', 'OnSashPositionChange',
+ 'ReplaceWindow', 'SetSashGravity', 'SetSashPosition', 'SetSashSize', 'SetMinimumPaneSize',
+ 'SetSplitMode', 'SplitHorizontally', 'SplitVertically', 'Unsplit', 'UpdateSize'
+ ]}.
+
+
+{class, wxSplitterEvent, wxNotifyEvent,
+ [
+ {event,
+ [wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED,
+ wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING,
+ wxEVT_COMMAND_SPLITTER_DOUBLECLICKED,
+ wxEVT_COMMAND_SPLITTER_UNSPLIT
+ ]}],
+ ['GetSashPosition', 'GetX', 'GetY',
+ 'GetWindowBeingRemoved', 'SetSashPosition'
+ ]}.
+
+
+{class, wxHtmlWindow, wxScrolledWindow, [],
+ [
+ 'wxHtmlWindow',%'AddFilter',
+ 'AppendToPage',
+ %%'GetInternalRepresentation',
+ 'GetOpenedAnchor',
+ 'GetOpenedPage','GetOpenedPageTitle','GetRelatedFrame',
+ 'HistoryBack', 'HistoryCanBack','HistoryCanForward','HistoryClear','HistoryForward',
+ 'LoadFile','LoadPage',
+ %%'OnCellClicked','OnCellMouseHover','OnLinkClicked',OnOpeningURL, OnSetTitle
+ %'ReadCustomization',
+ 'SelectAll','SelectionToText','SelectLine','SelectWord',
+ 'SetBorders','SetFonts','SetPage','SetRelatedFrame','SetRelatedStatusBar',
+ 'ToText'
+ %%'WriteCustomization'
+ ]}.
+
+
+{class, wxHtmlLinkEvent, wxCommandEvent,
+ [{acc, [{m_linkInfo, "GetLinkInfo()"}]},
+ {event, [wxEVT_COMMAND_HTML_LINK_CLICKED]}],
+ ['GetLinkInfo']}.
+
+%% New No wxAuiToolBar yet..add when documentation exists
+%% {class, wxAuiToolBarEvent, wxNotifyEvent,
+%% [{acc, [{is_dropdown_clicked, "IsDropDownClicked()"},
+%% {click_pt, "GetClickPoint()"},
+%% {rect, "GetItemRect()"},
+%% {tool_id, "GetToolId()"}]},
+%% {event, [wxEVT_COMMAND_AUITOOLBAR_TOOL_DROPDOWN,
+%% wxEVT_COMMAND_AUITOOLBAR_OVERFLOW_CLICK,
+%% wxEVT_COMMAND_AUITOOLBAR_MIDDLE_CLICK,
+%% wxEVT_COMMAND_AUITOOLBAR_BEGIN_DRAG
+%% ]}],
+%% ['IsDropDownClicked', 'SetDropDownClicked', 'SetClickPoint',
+%% 'GetItemRect', 'SetItemRect', 'GetToolId', 'SetToolId'
+%% ]}.
+
+{class, wxAuiNotebookEvent, wxNotifyEvent,
+ [{acc, [{old_selection, "GetOldSelection()"},
+ {selection, "GetSelection()"},
+ {drag_source, "GetDragSource()"}]},
+ {event, [wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE,
+ wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED,
+ wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING,
+ wxEVT_COMMAND_AUINOTEBOOK_BUTTON,
+ wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG,
+ wxEVT_COMMAND_AUINOTEBOOK_END_DRAG,
+ wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION,
+ wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND,
+ {wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN, {test_if, "wxCHECK_VERSION(2,8,5)"}},
+ {wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP, {test_if, "wxCHECK_VERSION(2,8,5)"}},
+ {wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN, {test_if, "wxCHECK_VERSION(2,8,5)"}},
+ {wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP, {test_if, "wxCHECK_VERSION(2,8,5)"}},
+ {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED, {test_if, "wxCHECK_VERSION(2,8,5)"}},
+ {wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE, {test_if, "wxCHECK_VERSION(2,8,5)"}},
+ {wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK, {test_if, "wxCHECK_VERSION(2,8,5)"}}
+ ]}],
+ ['SetSelection', 'GetSelection', 'SetOldSelection', 'GetOldSelection',
+ 'SetDragSource', 'GetDragSource'
+ ]}.
+
+
+{class, wxAuiManagerEvent, wxEvent,
+ [{acc, [{button, "GetButton()"},
+ {dc, "GetDC()"},
+ {pane, "GetPane()"},
+ {manager, "GetManager()"}
+ ]},
+ {event, [wxEVT_AUI_PANE_BUTTON,
+ wxEVT_AUI_PANE_CLOSE,
+ wxEVT_AUI_PANE_MAXIMIZE,
+ wxEVT_AUI_PANE_RESTORE,
+ wxEVT_AUI_RENDER,
+ wxEVT_AUI_FIND_MANAGER
+ ]}],
+ [
+ 'SetManager', 'GetManager','SetPane','GetPane','SetButton','GetButton',
+ 'SetDC', 'GetDC', 'Veto', 'GetVeto', 'SetCanVeto', 'CanVeto'
+ ]}.
+
+{class, wxLogNull, root, [],
+ [wxLogNull, '~wxLogNull']}.
+