Commits

Daniel Holth committed 8081012

Version 0.2.0. Much improved wrapper with SDL and image, mixer, ttf bindings.

Comments (0)

Files changed (56)

 build
 dist
 autohelpers.py
+__pycache__
+docs/_build
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
-The pysdl-cffi license:
+pysdl2-cffi is a wrapper for SDL2, SDL2_image and SDL2_mixer, written
+with cffi. This library is free software licensed under the GPLv2+.
+If you would like to distribute pysdl2-cffi with software that is
+not GPL compatible then you may contact the author.::
 
-Except when otherwise stated (look for LICENSE files in directories or
-information at the beginning of each file) all software and
-documentation is licensed as follows: 
+    Copyright © 2014 Daniel Holth <dholth@fastmail.fm>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+The Python translations of the SDL2 tests/examples are offered under their
+original licenses, as marked in each individual file.
+
+pysdl2-cffi incorporates code from pysdl-cffi, written by Leonard Ritter,
+provided under the MIT License::
 
     The MIT License
 
-    Permission is hereby granted, free of charge, to any person 
-    obtaining a copy of this software and associated documentation 
-    files (the "Software"), to deal in the Software without 
-    restriction, including without limitation the rights to use, 
-    copy, modify, merge, publish, distribute, sublicense, and/or 
-    sell copies of the Software, and to permit persons to whom the 
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation
+    files (the "Software"), to deal in the Software without
+    restriction, including without limitation the rights to use,
+    copy, modify, merge, publish, distribute, sublicense, and/or
+    sell copies of the Software, and to permit persons to whom the
     Software is furnished to do so, subject to the following conditions:
 
-    The above copyright notice and this permission notice shall be included 
+    The above copyright notice and this permission notice shall be included
     in all copies or substantial portions of the Software.
 
-    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
-    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
-    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
-    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
-    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
-    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     DEALINGS IN THE SOFTWARE.
 
+pysdl2-cffi incorporates documentation and function signatures from the
+wrapped libraries.
+
+SDL2::
+
+    Simple DirectMedia Layer
+    Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
+
+    This software is provided 'as-is', without any express or implied
+    warranty.  In no event will the authors be held liable for any damages
+    arising from the use of this software.
+
+    Permission is granted to anyone to use this software for any purpose,
+    including commercial applications, and to alter it and redistribute it
+    freely, subject to the following restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not
+       claim that you wrote the original software. If you use this software
+       in a product, an acknowledgment in the product documentation would be
+       appreciated but is not required.
+    2. Altered source versions must be plainly marked as such, and must not be
+       misrepresented as being the original software.
+    3. This notice may not be removed or altered from any source distribution.
+
+SDL_image::
+
+    SDL_image:  An example image loading library for use with SDL
+    Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
+
+    This software is provided 'as-is', without any express or implied
+    warranty.  In no event will the authors be held liable for any damages
+    arising from the use of this software.
+
+    Permission is granted to anyone to use this software for any purpose,
+    including commercial applications, and to alter it and redistribute it
+    freely, subject to the following restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not
+       claim that you wrote the original software. If you use this software
+       in a product, an acknowledgment in the product documentation would be
+       appreciated but is not required.
+    2. Altered source versions must be plainly marked as such, and must not be
+       misrepresented as being the original software.
+    3. This notice may not be removed or altered from any source distribution.
+
+SDL_mixer::
+
+    SDL_mixer:  An audio mixer library based on the SDL library
+    Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
+
+    This software is provided 'as-is', without any express or implied
+    warranty.  In no event will the authors be held liable for any damages
+    arising from the use of this software.
+
+    Permission is granted to anyone to use this software for any purpose,
+    including commercial applications, and to alter it and redistribute it
+    freely, subject to the following restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not
+       claim that you wrote the original software. If you use this software
+       in a product, an acknowledgment in the product documentation would be
+       appreciated but is not required.
+    2. Altered source versions must be plainly marked as such, and must not be
+       misrepresented as being the original software.
+    3. This notice may not be removed or altered from any source distribution.
-recursive-include tests *.py
-include build.py
+recursive-include tests *.py *.bmp *.wav
+recursive-include builder *.py *.xsl *.json
+include build.sh
 include *.rst
+recursive-include docs Makefile *.py *.bat *.rst
+prune docs/_*
 https://bitbucket.org/duangle/pysdl-cffi, and
 PySDL2.
 
-My goal is to preserve a flat, faithful-to-C view of the SDL API, then make
-it more Pythonic by removing the SDL_ prefix, renaming each SDL_FunctionName to
-sdl.functionName, leaving the enum's capitalized. The wrapper will also
-convert "out" parameters (most of the time (int *) or other pointer arguments
-are passed) to returned tuples, and it will convert SDL_GetError() to an
-exception.
-
-It does not yet do all of these things.
+The goal is to provide a flat, consistent, faithful-to-C binding with some
+more-Pythonic renaming and conveniences.
 
 This wrapper won't contain anything that doesn't directly translate to part of
 the library's API. The goal is to be a dependency for something like pygame,

_sdl/builder.py

-# Quick, dirty way to generate wrapper functions by iterating over cffi's
-# parsed declarations.
-
-import os.path
-import cffi.model
-import collections
-
-def is_primitive(arg):
-    """Return true if arg is primitive or primitive*"""
-    if hasattr(arg, 'totype'):
-        arg = arg.totype # a pointer
-    if hasattr(arg, 'ALL_PRIMITIVE_TYPES') and \
-        arg.get_c_name() in arg.ALL_PRIMITIVE_TYPES:
-        print "primitive %s" % (arg.get_c_name())
-        return True
-    print "not primitive %s" % (arg.get_c_name())
-    return False
-
-def treatment(name, declaration):
-    for i, arg in enumerate(declaration.args):
-        c_name = arg.get_c_name()
-        if is_primitive(arg):
-            yield ('pass', arg, None)
-        elif i == 0 and c_name.startswith("SDL_") and c_name.endswith('*'):
-            yield ('self', arg, None)
-        elif c_name.endswith('*'):
-            yield ('new', arg, True)
-        else:
-            yield('', arg, None)
-
-class IndentedWriter(object):
-    def __init__(self, writer):
-        self.writer = writer
-        self.level = 0
-        self.indentation = "    "
-
-    def writeln(self, msg):
-        self.writer.write(self.indentation * self.level)
-        self.writer.write(msg)
-        self.writer.write("\n")
-
-    def indent(self):
-        self.level += 1
-
-    def dedent(self):
-        self.level -= 1
-
-def handle_enum(output, declaration_name, declaration):
-    if not hasattr(declaration, "enumerators"):
-        # it might be an anonymous struct
-        return
-    for name in declaration.enumerators:
-        output.writeln("%s = _LIB.%s" % (name, name))
-    output.writeln("")
-
-declarations_by_type = collections.defaultdict(list)
-
-def handle_struct(output, declaration_name, declaration):
-    output.writeln("class %s(Struct):" % declaration.name)
-    output.indent()
-    functions = declarations_by_type[declaration.name + " *"]
-    for fname in functions:
-        short_name = fname[4].lower() + fname[5:]
-        output.writeln("%s = %s" % (short_name, fname))
-    if not functions:
-        output.writeln("pass")
-    output.dedent()
-    output.writeln("")
-
-STRING_TYPES = ["char *", "char const *"]
-
-def handle_function(output, declaration_name, declaration):
-    fname = declaration_name.split(' ')[1]
-
-    returns_void = isinstance(declaration.result, cffi.model.VoidType)
-
-    if declaration.args:
-        declarations_by_type[declaration.args[0].get_c_name()].append(fname)
-
-    arg_names  = ["a%d" % i for i in range(len(declaration.args))]
-    arg_vars = ', '.join(arg_names)
-    output.writeln("def %s(%s):" % (fname, arg_vars))
-    output.indent()
-    output.writeln('"""' + declaration.get_c_name().replace("(*)", " " + fname) + '"""')
-
-    line = []
-    if not returns_void:
-        line.append("rc =")
-    line.append("_LIB.%s(%s)" % (fname,
-                                 ', '.join(["unbox(%s)" % name
-                                 for name in arg_names])))
-    output.writeln(" ".join(line))
-
-    if returns_void:
-        pass
-    elif declaration.result.get_c_name() in STRING_TYPES:
-        output.writeln("return ffi.string(rc)")
-    else:
-        output.writeln("return rc")
-    output.dedent()
-    output.writeln("")
-
-    return
-
-    returning = []
-    for i, (action, arg, returns) in enumerate(treatment(fname, declaration)):
-        if action in ("pass", "self"):
-            output.writeln("c_args[%d] = args[%d]" % (i, i))
-        elif action == "new":
-            output.writeln("c_args[%d] = ffi.new(%s)" % (i, repr(arg.get_c_name())))
-
-            if returns:
-                if isinstance(arg.totype, cffi.model.StructType):
-                    # later, wrap structs.
-                    returning.append("c_args[%d]" % (i,))
-                else:
-                    returning.append("c_args[%d][0]" % (i,))
-
-        else:
-            output.writeln("c_args[%d] = None" % (i, ))
-
-    output.writeln("rc = _LIB.%s(*c_args)" % (fname,))
-
-    if not returning:
-        if declaration.result.get_c_name() == "char *":
-            output.writeln("return ffi.string(rc)")
-        else:
-            output.writeln("return rc")
-    else:
-        if len(returning) == 1:
-            output.writeln("return %s" % returning[0])
-        else:
-            output.writeln("return (" + ", ".join(returning) + ")")
-
-    output.dedent()
-    output.writeln("")
-
-def get_declarations(ffi):
-    return ffi._parser._declarations
-
-def generate(output,
-             cdefs=None,
-             helpers=None,
-             filter=None):
-    """
-    Automatically generate libSDL2 wrappers by following some simple rules.
-    Only used during build time.
-    """
-    sort_order = {'anonymous' : 4,
-                  'function' : 1,
-                  'struct' : 2,
-                  'union' : 3 }
-
-    def sort_key(declaration_name):
-        kind, name = declaration_name.split()
-        return (sort_order.get(kind, kind), name)
-
-    declarations = get_declarations(cdefs.ffi)
-    output = IndentedWriter(output)
-    for declaration_name in sorted(declarations, key=sort_key):
-        if filter and not filter.match(declaration_name):
-            continue
-        declaration_kind, declaration_n = declaration_name.split(" ")
-        if declaration_kind == "function":
-            handle_function(output,
-                declaration_name,
-                declarations[declaration_name])
-
-        elif declaration_kind in ("struct", "union"):
-            handle_struct(output,
-                declaration_name,
-                declarations[declaration_name])
-
-        elif declaration_kind in ("anonymous",):
-            handle_enum(output,
-                        declaration_name,
-                        declarations[declaration_name])
-
-        else:
-            print(declaration_name)
-
-        # XXX do something about typedefs that are the friendly struct names
-
-        continue
-
-        # XXX unreachable code:
-        # The below may become a higher-level wrapper:
-
-        fname = declaration_name.split(' ')[1]
-
-        # Skip manually written helpers:
-        if hasattr(helpers, fname):
-            continue
-
-        declaration = declarations[declaration_name]
-
-        if declaration.args:
-            output.writeln("def %s(*args):" % fname)
-        else:
-            output.writeln("def %s():" % fname)
-
-        output.indent()
-        output.writeln('"""' + declaration.get_c_name().replace("(*)", " " + fname) + '"""')
-        output.writeln("c_args = %s" % (repr([None]*len(declaration.args))))
-
-        returning = []
-        for i, (action, arg, returns) in enumerate(treatment(fname, declaration)):
-            if action in ("pass", "self"):
-                output.writeln("c_args[%d] = args[%d]" % (i, i))
-            elif action == "new":
-                output.writeln("c_args[%d] = ffi.new(%s)" % (i, repr(arg.get_c_name())))
-
-                if returns:
-                    if isinstance(arg.totype, cffi.model.StructType):
-                        # later, wrap structs.
-                        returning.append("c_args[%d]" % (i,))
-                    else:
-                        returning.append("c_args[%d][0]" % (i,))
-
-            else:
-                output.writeln("c_args[%d] = None" % (i, ))
-
-        output.writeln("rc = _LIB.%s(*c_args)" % (fname,))
-
-        if not returning:
-            if declaration.result.get_c_name() == "char *":
-                output.writeln("return ffi.string(rc)")
-            else:
-                output.writeln("return rc")
-        else:
-            if len(returning) == 1:
-                output.writeln("return %s" % returning[0])
-            else:
-                output.writeln("return (" + ", ".join(returning) + ")")
-
-        output.dedent()
-        output.writeln("")
-
-header = """# Automatically generated wrappers.
-# Override by adding wrappers to helpers.py.
-from .dso import ffi, _LIB
-from .structs import Struct, unbox
-
-"""
-
-api = ["""# API
-import apipkg
-
-exports = """, """
-
-ns_dict = dict((s, '_sdl.renamed:%s' % s)
-               for s in exports if not s.startswith('_'))
-ns_dict['image'] = '_sdl_image.renamed'
-ns_dict['mixer'] = '_sdl_mixer.renamed'
-
-apipkg.initpkg(__name__, ns_dict)
-"""]
-
-def go():
-    from . import cdefs, helpers
-
-    output_filename = os.path.join(os.path.dirname(__file__), "autohelpers.py")
-    with open(output_filename, "w+") as output:
-        output.write(header)
-        generate(output, cdefs=cdefs, helpers=helpers)
-
-    import pprint
-    import _sdl.renamed
-    exports = pprint.pformat(sorted(dir(_sdl.renamed)))
-    api_filename = os.path.join(os.path.dirname(__file__), "..", "sdl", "__init__.py")
-    with open(api_filename, "w+") as output:
-        output.write(exports.join(api))
-
-if __name__ == "__main__":
-    go()
 
 ffi = cffi.FFI()
 
-ffi.cdef("""
+_cdefs = []
+
+_cdefs.append("""
 typedef struct _FILE FILE;
 
 typedef int32_t va_list; // XXX surely broken, but it makes it parse.
                      pfnSDL_CurrentEndThread pfnEndThread);
     """)
 else:
-    ffi.cdef("""
+    _cdefs.append("""
     SDL_Thread *
     SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data);
     """)
 
-ffi.cdef(r"""
+_cdefs.append(r"""
 const char * SDL_GetThreadName(SDL_Thread *thread);
 SDL_threadID SDL_ThreadID(void);
 SDL_threadID SDL_GetThreadID(SDL_Thread * thread);
 
 # main
 
-# Only for Windows:
-ffi.cdef("""
-int SDL_RegisterApp(char *name, Uint32 style,
-                    void *hInst);
-void SDL_UnregisterApp(void);
-   """)
+if False:
+    # Only for Windows:
+    _cdefs.append("""
+    int SDL_RegisterApp(char *name, Uint32 style,
+                        void *hInst);
+    void SDL_UnregisterApp(void);
+       """)
+
+ffi.cdef(''.join(_cdefs))
     return ffi.dlopen(names[0]) # pragma: no cover
 
 _LIB = dlopen(ffi,
+              'SDL2',
               'libSDL2.so',
-              'libSDL2-2.0.so.0',
-              'SDL2')
+              'libSDL2-2.0.so.0')
-# This file is mostly from pysdl-cffi, not pysdl2-cffi
-
-from __future__ import (print_function, division, absolute_import)
+# Handwritten helper methods for those hard-to-wrap functions.
+# Overrides same-named functions from autohelpers.py
 
 from .cdefs import ffi as _ffi
-from .dso import _LIB # XXX should probably use the error-checking ones
+from .dso import _LIB
 from .structs import unbox
 
-################################################################################
-
-def SDL_Init(*args):
-    result = _LIB.SDL_Init(*args)
-    _LIB.SDL_ClearError()
-    return result
-
-def SDL_GetWindowSize(window):
-    w = _ffi.new('int *')
-    h = _ffi.new('int *')
-    _LIB.SDL_GetWindowSize(window, w, h)
-    return w[0], h[0]
-
-def SDL_GetMouseState():
-    x = _ffi.new('int *')
-    y = _ffi.new('int *')
-    state = _LIB.SDL_GetMouseState(x, y)
-    return state, x[0], y[0]
-
-def SDL_GetCurrentDisplayMode(displayIndex):
-    mode = _ffi.new('SDL_DisplayMode *')
-    result = _LIB.SDL_GetCurrentDisplayMode(displayIndex, mode)
-    if result == 0:
-        return mode
-
-def SDL_GetDisplayMode(displayIndex, modeIndex):
-    mode = _ffi.new('SDL_DisplayMode *')
-    result = _LIB.SDL_GetDisplayMode(displayIndex, modeIndex, mode)
-    if result == 0:
-        return mode
-
-def SDL_GetDesktopDisplayMode(displayIndex):
-    mode = _ffi.new('SDL_DisplayMode *')
-    result = _LIB.SDL_GetDesktopDisplayMode(displayIndex, mode)
-    if result == 0:
-        return mode
-
-def SDL_GetDisplayBounds(displayIndex):
-    rect = _ffi.new('SDL_Rect *')
-    result = _LIB.SDL_GetDisplayBounds(displayIndex, rect)
-    if result == 0:
-        return (rect.x, rect.y, rect.w, rect.h)
-
-def SDL_GL_GetAttribute(attr):
-    value = _ffi.new('int *')
-    _LIB.SDL_GL_GetAttribute(attr, value)
-    return value[0]
-
-def SDL_GetClipboardText():
-    if not SDL_HasClipboardText():
-        return None
-    text = _LIB.SDL_GetClipboardText()
-    if text == _ffi.NULL:
-        return None
-    result = _ffi.string(text)
-    #SDL_free(text)
-    return result
-
-# begin pysdl2-cffi handwritten helpers:
-
 def SDL_CalculateGammaRamp(a0, a1=_ffi.NULL):
     """void SDL_CalculateGammaRamp(float, uint16_t *)
 

_sdl/internal.py

-# wrap SDL functions for error checking and shorter names.
-from __future__ import (print_function, division, absolute_import)
-
-from . import cdefs
-from .dso import _LIB
-
-class SDL_Error(Exception):
-    pass
-
-ignore_errors = False
-
-def check_error():
-    error = cdefs.ffi.string(_LIB.SDL_GetError())
-    if error:
-        _LIB.SDL_ClearError()
-        if ignore_errors:
-            return
-        raise SDL_Error, error
-
-def guard(func):
-    if not func:
-        return None
-    if isinstance(func, int):
-        return func
-    name = repr(func)
-    def newfunc(*args):
-        result = func(*args)
-        check_error()
-        return result
-    newfunc.func_name = name
-    newfunc.__doc__ = func.__doc__
-    return newfunc
 # Names to expose to the outside
 
 from .defines import *
-from .pixelformats import * # overwrite some missing def's from register() calls
+from .pixels import *
 from .constants import * # including things that would otherwise involve math in an enum declaration
 from .autohelpers import *
-from .helpers import *
+from .helpers import *
+
+SDL_BlitSurface = SDL_UpperBlit

_sdl/pixelformats.py

-# just the pixel formats & macros
-# from PySDL2
-
-from .dso import _LIB
-
-SDL_PIXELTYPE_UNKNOWN = _LIB.SDL_PIXELTYPE_UNKNOWN
-SDL_PIXELTYPE_INDEX1 = _LIB.SDL_PIXELTYPE_INDEX1
-SDL_PIXELTYPE_INDEX4 = _LIB.SDL_PIXELTYPE_INDEX4
-SDL_PIXELTYPE_INDEX8 = _LIB.SDL_PIXELTYPE_INDEX8
-SDL_PIXELTYPE_PACKED8 = _LIB.SDL_PIXELTYPE_PACKED8
-SDL_PIXELTYPE_PACKED16 = _LIB.SDL_PIXELTYPE_PACKED16
-SDL_PIXELTYPE_PACKED32 = _LIB.SDL_PIXELTYPE_PACKED32
-SDL_PIXELTYPE_ARRAYU8 = _LIB.SDL_PIXELTYPE_ARRAYU8
-SDL_PIXELTYPE_ARRAYU16 = _LIB.SDL_PIXELTYPE_ARRAYU16
-SDL_PIXELTYPE_ARRAYU32 = _LIB.SDL_PIXELTYPE_ARRAYU32
-SDL_PIXELTYPE_ARRAYF16 = _LIB.SDL_PIXELTYPE_ARRAYF16
-SDL_PIXELTYPE_ARRAYF32 = _LIB.SDL_PIXELTYPE_ARRAYF32
-
-SDL_BITMAPORDER_NONE = _LIB.SDL_BITMAPORDER_NONE
-SDL_BITMAPORDER_4321 = _LIB.SDL_BITMAPORDER_4321
-SDL_BITMAPORDER_1234 = _LIB.SDL_BITMAPORDER_1234
-
-SDL_PACKEDORDER_NONE = _LIB.SDL_PACKEDORDER_NONE
-SDL_PACKEDORDER_XRGB = _LIB.SDL_PACKEDORDER_XRGB
-SDL_PACKEDORDER_RGBX = _LIB.SDL_PACKEDORDER_RGBX
-SDL_PACKEDORDER_ARGB = _LIB.SDL_PACKEDORDER_ARGB
-SDL_PACKEDORDER_RGBA = _LIB.SDL_PACKEDORDER_RGBA
-SDL_PACKEDORDER_XBGR = _LIB.SDL_PACKEDORDER_XBGR
-SDL_PACKEDORDER_BGRX = _LIB.SDL_PACKEDORDER_BGRX
-SDL_PACKEDORDER_ABGR = _LIB.SDL_PACKEDORDER_ABGR
-SDL_PACKEDORDER_BGRA = _LIB.SDL_PACKEDORDER_BGRA
-
-SDL_ARRAYORDER_NONE = _LIB.SDL_ARRAYORDER_NONE
-SDL_ARRAYORDER_RGB = _LIB.SDL_ARRAYORDER_RGB
-SDL_ARRAYORDER_RGBA = _LIB.SDL_ARRAYORDER_RGBA
-SDL_ARRAYORDER_ARGB = _LIB.SDL_ARRAYORDER_ARGB
-SDL_ARRAYORDER_BGR = _LIB.SDL_ARRAYORDER_BGR
-SDL_ARRAYORDER_BGRA = _LIB.SDL_ARRAYORDER_BGRA
-SDL_ARRAYORDER_ABGR = _LIB.SDL_ARRAYORDER_ABGR
-
-SDL_PACKEDLAYOUT_NONE = _LIB.SDL_PACKEDLAYOUT_NONE
-SDL_PACKEDLAYOUT_332 = _LIB.SDL_PACKEDLAYOUT_332
-SDL_PACKEDLAYOUT_4444 = _LIB.SDL_PACKEDLAYOUT_4444
-SDL_PACKEDLAYOUT_1555 = _LIB.SDL_PACKEDLAYOUT_1555
-SDL_PACKEDLAYOUT_5551 = _LIB.SDL_PACKEDLAYOUT_5551
-SDL_PACKEDLAYOUT_565 = _LIB.SDL_PACKEDLAYOUT_565
-SDL_PACKEDLAYOUT_8888 = _LIB.SDL_PACKEDLAYOUT_8888
-SDL_PACKEDLAYOUT_2101010 = _LIB.SDL_PACKEDLAYOUT_2101010
-SDL_PACKEDLAYOUT_1010102 = _LIB.SDL_PACKEDLAYOUT_1010102
-
-# Macro re-implementations from PySDL2:
-SDL_FOURCC = lambda a, b, c, d: (ord(a) << 0) | (ord(b) << 8) | (ord(c) << 16) | (ord(d) << 24)
-SDL_DEFINE_PIXELFOURCC = SDL_FOURCC
-SDL_DEFINE_PIXELFORMAT = lambda ptype, order, layout, bits, pbytes: ((1 << 28) | ((ptype) << 24) | ((order) << 20) | ((layout) << 16) | ((bits) << 8) | ((pbytes) << 0))
-SDL_PIXELFLAG = lambda X: (((X) >> 28) & 0x0F)
-SDL_PIXELTYPE = lambda X: (((X) >> 24) & 0x0F)
-SDL_PIXELORDER = lambda X: (((X) >> 20) & 0x0F)
-SDL_PIXELLAYOUT = lambda X: (((X) >> 16) & 0x0F)
-SDL_BITSPERPIXEL = lambda X: (((X) >> 8) & 0xFF)
-def SDL_BYTESPERPIXEL(x):
-    valid = (SDL_PIXELFORMAT_YUY2, SDL_PIXELFORMAT_UYVY, SDL_PIXELFORMAT_YVYU)
-    if SDL_ISPIXELFORMAT_FOURCC(x):
-        if x in valid:
-            return 2
-        else:
-            return 1
-    else:
-        return(((x) >> 0) & 0xFF)
-def SDL_ISPIXELFORMAT_INDEXED(pformat):
-    """Checks, if the passed format value is an indexed format."""
-    return ((not SDL_ISPIXELFORMAT_FOURCC(pformat)) and
-            ((SDL_PIXELTYPE(pformat) == SDL_PIXELTYPE_INDEX1) or
-             (SDL_PIXELTYPE(pformat) == SDL_PIXELTYPE_INDEX4) or
-             (SDL_PIXELTYPE(pformat) == SDL_PIXELTYPE_INDEX8)))
-def SDL_ISPIXELFORMAT_ALPHA(pformat):
-    """Checks, if the passed format value is an alpha channel supporting
-    format.
-    """
-    return ((not SDL_ISPIXELFORMAT_FOURCC(pformat)) and
-            ((SDL_PIXELORDER(pformat) == SDL_PACKEDORDER_ARGB) or
-             (SDL_PIXELORDER(pformat) == SDL_PACKEDORDER_RGBA) or
-             (SDL_PIXELORDER(pformat) == SDL_PACKEDORDER_ABGR) or
-             (SDL_PIXELORDER(pformat) == SDL_PACKEDORDER_BGRA)))
-
-# XXX could change these all to #define SDL_X ... in the cdef and grab once with .verify()
-
-SDL_ISPIXELFORMAT_FOURCC = lambda fmt: ((fmt) and (SDL_PIXELFLAG(fmt) != 1))
-SDL_PIXELFORMAT_UNKNOWN = 0
-SDL_PIXELFORMAT_INDEX1LSB = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1,
-                                                   SDL_BITMAPORDER_4321,
-                                                   0, 1, 0)
-SDL_PIXELFORMAT_INDEX1MSB = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1,
-                                                   SDL_BITMAPORDER_1234,
-                                                   0, 1, 0)
-SDL_PIXELFORMAT_INDEX4LSB = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4,
-                                                   SDL_BITMAPORDER_4321,
-                                                   0, 4, 0)
-SDL_PIXELFORMAT_INDEX4MSB = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4,
-                                                   SDL_BITMAPORDER_1234,
-                                                   0, 4, 0)
-SDL_PIXELFORMAT_INDEX8 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX8, 0,
-                                                0, 8, 1)
-SDL_PIXELFORMAT_RGB332 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED8,
-                                                SDL_PACKEDORDER_XRGB,
-                                                SDL_PACKEDLAYOUT_332, 8, 1)
-SDL_PIXELFORMAT_RGB444 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16,
-                                                SDL_PACKEDORDER_XRGB,
-                                                SDL_PACKEDLAYOUT_4444, 12, 2)
-SDL_PIXELFORMAT_RGB555 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16,
-                                                SDL_PACKEDORDER_XRGB,
-                                                SDL_PACKEDLAYOUT_1555, 15, 2)
-SDL_PIXELFORMAT_BGR555 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16,
-                                                SDL_PACKEDORDER_XBGR,
-                                                SDL_PACKEDLAYOUT_1555, 15, 2)
-SDL_PIXELFORMAT_ARGB4444 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16,
-                                                  SDL_PACKEDORDER_ARGB,
-                                                  SDL_PACKEDLAYOUT_4444, 16, 2)
-SDL_PIXELFORMAT_RGBA4444 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16,
-                                                  SDL_PACKEDORDER_RGBA,
-                                                  SDL_PACKEDLAYOUT_4444, 16, 2)
-SDL_PIXELFORMAT_ABGR4444 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16,
-                                                  SDL_PACKEDORDER_ABGR,
-                                                  SDL_PACKEDLAYOUT_4444, 16, 2)
-SDL_PIXELFORMAT_BGRA4444 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16,
-                                                  SDL_PACKEDORDER_BGRA,
-                                                  SDL_PACKEDLAYOUT_4444, 16, 2)
-SDL_PIXELFORMAT_ARGB1555 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16,
-                                                  SDL_PACKEDORDER_ARGB,
-                                                  SDL_PACKEDLAYOUT_1555, 16, 2)
-SDL_PIXELFORMAT_RGBA5551 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16,
-                                                  SDL_PACKEDORDER_RGBA,
-                                                  SDL_PACKEDLAYOUT_5551, 16, 2)
-SDL_PIXELFORMAT_ABGR1555 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16,
-                                                  SDL_PACKEDORDER_ABGR,
-                                                  SDL_PACKEDLAYOUT_1555, 16, 2)
-SDL_PIXELFORMAT_BGRA5551 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16,
-                                                  SDL_PACKEDORDER_BGRA,
-                                                  SDL_PACKEDLAYOUT_5551, 16, 2)
-SDL_PIXELFORMAT_RGB565 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16,
-                                                SDL_PACKEDORDER_XRGB,
-                                                SDL_PACKEDLAYOUT_565, 16, 2)
-SDL_PIXELFORMAT_BGR565 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16,
-                                                SDL_PACKEDORDER_XBGR,
-                                                SDL_PACKEDLAYOUT_565, 16, 2)
-SDL_PIXELFORMAT_RGB24 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8,
-                                               SDL_ARRAYORDER_RGB, 0, 24, 3)
-SDL_PIXELFORMAT_BGR24 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8,
-                                               SDL_ARRAYORDER_BGR, 0, 24, 3)
-SDL_PIXELFORMAT_RGB888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32,
-                                                SDL_PACKEDORDER_XRGB,
-                                                SDL_PACKEDLAYOUT_8888, 24, 4)
-SDL_PIXELFORMAT_RGBX8888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32,
-                                                  SDL_PACKEDORDER_RGBX,
-                                                  SDL_PACKEDLAYOUT_8888, 24, 4)
-SDL_PIXELFORMAT_BGR888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32,
-                                                SDL_PACKEDORDER_XBGR,
-                                                SDL_PACKEDLAYOUT_8888, 24, 4)
-SDL_PIXELFORMAT_BGRX8888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32,
-                                                  SDL_PACKEDORDER_BGRX,
-                                                  SDL_PACKEDLAYOUT_8888, 24, 4)
-SDL_PIXELFORMAT_ARGB8888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32,
-                                                  SDL_PACKEDORDER_ARGB,
-                                                  SDL_PACKEDLAYOUT_8888, 32, 4)
-SDL_PIXELFORMAT_RGBA8888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32,
-                                                  SDL_PACKEDORDER_RGBA,
-                                                  SDL_PACKEDLAYOUT_8888, 32, 4)
-SDL_PIXELFORMAT_ABGR8888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32,
-                                                  SDL_PACKEDORDER_ABGR,
-                                                  SDL_PACKEDLAYOUT_8888, 32, 4)
-SDL_PIXELFORMAT_BGRA8888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32,
-                                                  SDL_PACKEDORDER_BGRA,
-                                                  SDL_PACKEDLAYOUT_8888, 32, 4)
-SDL_PIXELFORMAT_ARGB2101010 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32,
-                                                     SDL_PACKEDORDER_ARGB,
-                                                     SDL_PACKEDLAYOUT_2101010,
-                                                     32, 4)
-SDL_PIXELFORMAT_YV12 = SDL_DEFINE_PIXELFOURCC('Y', 'V', '1', '2')
-SDL_PIXELFORMAT_IYUV = SDL_DEFINE_PIXELFOURCC('I', 'Y', 'U', 'V')
-SDL_PIXELFORMAT_YUY2 = SDL_DEFINE_PIXELFOURCC('Y', 'U', 'Y', '2')
-SDL_PIXELFORMAT_UYVY = SDL_DEFINE_PIXELFOURCC('U', 'Y', 'V', 'Y')
-SDL_PIXELFORMAT_YVYU = SDL_DEFINE_PIXELFOURCC('Y', 'V', 'Y', 'U')
-
-ALL_PIXELFORMATS = (
-    SDL_PIXELFORMAT_INDEX1LSB,
-    SDL_PIXELFORMAT_INDEX1MSB,
-    SDL_PIXELFORMAT_INDEX4LSB,
-    SDL_PIXELFORMAT_INDEX4MSB,
-    SDL_PIXELFORMAT_INDEX8,
-    SDL_PIXELFORMAT_RGB332,
-    SDL_PIXELFORMAT_RGB444,
-    SDL_PIXELFORMAT_RGB555,
-    SDL_PIXELFORMAT_BGR555,
-    SDL_PIXELFORMAT_ARGB4444,
-    SDL_PIXELFORMAT_RGBA4444,
-    SDL_PIXELFORMAT_ABGR4444,
-    SDL_PIXELFORMAT_BGRA4444,
-    SDL_PIXELFORMAT_ARGB1555,
-    SDL_PIXELFORMAT_RGBA5551,
-    SDL_PIXELFORMAT_ABGR1555,
-    SDL_PIXELFORMAT_BGRA5551,
-    SDL_PIXELFORMAT_RGB565,
-    SDL_PIXELFORMAT_BGR565,
-    SDL_PIXELFORMAT_RGB24,
-    SDL_PIXELFORMAT_BGR24,
-    SDL_PIXELFORMAT_RGB888,
-    SDL_PIXELFORMAT_RGBX8888,
-    SDL_PIXELFORMAT_BGR888,
-    SDL_PIXELFORMAT_BGRX8888,
-    SDL_PIXELFORMAT_ARGB8888,
-    SDL_PIXELFORMAT_RGBA8888,
-    SDL_PIXELFORMAT_ABGR8888,
-    SDL_PIXELFORMAT_BGRA8888,
-    SDL_PIXELFORMAT_ARGB2101010,
-    SDL_PIXELFORMAT_YV12,
-    SDL_PIXELFORMAT_IYUV,
-    SDL_PIXELFORMAT_YUY2,
-    SDL_PIXELFORMAT_UYVY,
-    SDL_PIXELFORMAT_YVYU,
-    )
+# The parts of SDL_pixels.h that can't be parsed by cffi.
+
+from .autohelpers import (
+    SDL_PIXELTYPE_UNKNOWN,
+    SDL_PIXELTYPE_INDEX1,
+    SDL_PIXELTYPE_INDEX4,
+    SDL_PIXELTYPE_INDEX8,
+    SDL_PIXELTYPE_PACKED8,
+    SDL_PIXELTYPE_PACKED16,
+    SDL_PIXELTYPE_PACKED32,
+    SDL_PIXELTYPE_ARRAYU8,
+    SDL_PIXELTYPE_ARRAYU16,
+    SDL_PIXELTYPE_ARRAYU32,
+    SDL_PIXELTYPE_ARRAYF16,
+    SDL_PIXELTYPE_ARRAYF32,
+
+    SDL_BITMAPORDER_NONE,
+    SDL_BITMAPORDER_4321,
+    SDL_BITMAPORDER_1234,
+
+    SDL_PACKEDORDER_NONE,
+    SDL_PACKEDORDER_XRGB,
+    SDL_PACKEDORDER_RGBX,
+    SDL_PACKEDORDER_ARGB,
+    SDL_PACKEDORDER_RGBA,
+    SDL_PACKEDORDER_XBGR,
+    SDL_PACKEDORDER_BGRX,
+    SDL_PACKEDORDER_ABGR,
+    SDL_PACKEDORDER_BGRA,
+
+    SDL_ARRAYORDER_NONE,
+    SDL_ARRAYORDER_RGB,
+    SDL_ARRAYORDER_RGBA,
+    SDL_ARRAYORDER_ARGB,
+    SDL_ARRAYORDER_BGR,
+    SDL_ARRAYORDER_BGRA,
+    SDL_ARRAYORDER_ABGR,
+
+    SDL_PACKEDLAYOUT_NONE,
+    SDL_PACKEDLAYOUT_332,
+    SDL_PACKEDLAYOUT_4444,
+    SDL_PACKEDLAYOUT_1555,
+    SDL_PACKEDLAYOUT_5551,
+    SDL_PACKEDLAYOUT_565,
+    SDL_PACKEDLAYOUT_8888,
+    SDL_PACKEDLAYOUT_2101010,
+    SDL_PACKEDLAYOUT_1010102, )
+
+SDL_ALPHA_OPAQUE=255
+SDL_ALPHA_TRANSPARENT=0
+
+def SDL_FOURCC(A, B, C, D):
+    """Return a four-character code as a uint32."""
+    return ord(A) | (ord(B)<<8) | (ord(C)<<16) | (ord(D)<<24)
+
+SDL_DEFINE_PIXELFOURCC = SDL_FOURCC
+
+def SDL_DEFINE_PIXELFORMAT(type, order, layout, bits, bytes):
+    return ((1 << 28) | ((type) << 24) | ((order) << 20) | ((layout) << 16) |
+            ((bits) << 8) | ((bytes) << 0))
+def SDL_PIXELFLAG(X):
+    return (((X) >> 28) & 0x0F)
+def SDL_PIXELTYPE(X):
+    return (((X) >> 24) & 0x0F)
+def SDL_PIXELORDER(X):
+    return (((X) >> 20) & 0x0F)
+def SDL_PIXELLAYOUT(X):
+    return (((X) >> 16) & 0x0F)
+def SDL_BITSPERPIXEL(X):
+    return (((X) >> 8) & 0xFF)
+def SDL_BYTESPERPIXEL(X):
+    if SDL_ISPIXELFORMAT_FOURCC(X):
+        if (((X) == SDL_PIXELFORMAT_YUY2) or
+            ((X) == SDL_PIXELFORMAT_UYVY) or
+            ((X) == SDL_PIXELFORMAT_YVYU)):
+            return 2
+        return 1
+    else:
+        return (((X) >> 0) & 0xFF)
+
+def SDL_ISPIXELFORMAT_INDEXED(format):
+    return (not SDL_ISPIXELFORMAT_FOURCC(format) and
+     ((SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX1) or
+      (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX4) or
+      (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX8)))
+
+def SDL_ISPIXELFORMAT_ALPHA(format):
+    return (not SDL_ISPIXELFORMAT_FOURCC(format) and
+     ((SDL_PIXELORDER(format) == SDL_PACKEDORDER_ARGB) or
+      (SDL_PIXELORDER(format) == SDL_PACKEDORDER_RGBA) or
+      (SDL_PIXELORDER(format) == SDL_PACKEDORDER_ABGR) or
+      (SDL_PIXELORDER(format) == SDL_PACKEDORDER_BGRA)))
+
+# The flag is set to 1 because 0x1? is not in the printable ASCII range
+def SDL_ISPIXELFORMAT_FOURCC(format):
+    return ((format) and (SDL_PIXELFLAG(format) != 1))
+
+SDL_PIXELFORMAT_UNKNOWN = 0
+SDL_PIXELFORMAT_INDEX1LSB =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_4321, 0,
+                           1, 0)
+SDL_PIXELFORMAT_INDEX1MSB =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_1234, 0,
+                           1, 0)
+SDL_PIXELFORMAT_INDEX4LSB =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_4321, 0,
+                           4, 0)
+SDL_PIXELFORMAT_INDEX4MSB =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_1234, 0,
+                           4, 0)
+SDL_PIXELFORMAT_INDEX8 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX8, 0, 0, 8, 1)
+SDL_PIXELFORMAT_RGB332 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED8, SDL_PACKEDORDER_XRGB,
+                           SDL_PACKEDLAYOUT_332, 8, 1)
+SDL_PIXELFORMAT_RGB444 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB,
+                           SDL_PACKEDLAYOUT_4444, 12, 2)
+SDL_PIXELFORMAT_RGB555 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB,
+                           SDL_PACKEDLAYOUT_1555, 15, 2)
+SDL_PIXELFORMAT_BGR555 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR,
+                           SDL_PACKEDLAYOUT_1555, 15, 2)
+SDL_PIXELFORMAT_ARGB4444 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB,
+                           SDL_PACKEDLAYOUT_4444, 16, 2)
+SDL_PIXELFORMAT_RGBA4444 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_RGBA,
+                           SDL_PACKEDLAYOUT_4444, 16, 2)
+SDL_PIXELFORMAT_ABGR4444 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ABGR,
+                           SDL_PACKEDLAYOUT_4444, 16, 2)
+SDL_PIXELFORMAT_BGRA4444 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_BGRA,
+                           SDL_PACKEDLAYOUT_4444, 16, 2)
+SDL_PIXELFORMAT_ARGB1555 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB,
+                           SDL_PACKEDLAYOUT_1555, 16, 2)
+SDL_PIXELFORMAT_RGBA5551 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_RGBA,
+                           SDL_PACKEDLAYOUT_5551, 16, 2)
+SDL_PIXELFORMAT_ABGR1555 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ABGR,
+                           SDL_PACKEDLAYOUT_1555, 16, 2)
+SDL_PIXELFORMAT_BGRA5551 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_BGRA,
+                           SDL_PACKEDLAYOUT_5551, 16, 2)
+SDL_PIXELFORMAT_RGB565 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB,
+                           SDL_PACKEDLAYOUT_565, 16, 2)
+SDL_PIXELFORMAT_BGR565 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR,
+                           SDL_PACKEDLAYOUT_565, 16, 2)
+SDL_PIXELFORMAT_RGB24 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_RGB, 0,
+                           24, 3)
+SDL_PIXELFORMAT_BGR24 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_BGR, 0,
+                           24, 3)
+SDL_PIXELFORMAT_RGB888 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XRGB,
+                           SDL_PACKEDLAYOUT_8888, 24, 4)
+SDL_PIXELFORMAT_RGBX8888 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBX,
+                           SDL_PACKEDLAYOUT_8888, 24, 4)
+SDL_PIXELFORMAT_BGR888 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XBGR,
+                           SDL_PACKEDLAYOUT_8888, 24, 4)
+SDL_PIXELFORMAT_BGRX8888 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRX,
+                           SDL_PACKEDLAYOUT_8888, 24, 4)
+SDL_PIXELFORMAT_ARGB8888 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB,
+                           SDL_PACKEDLAYOUT_8888, 32, 4)
+SDL_PIXELFORMAT_RGBA8888 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBA,
+                           SDL_PACKEDLAYOUT_8888, 32, 4)
+SDL_PIXELFORMAT_ABGR8888 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ABGR,
+                           SDL_PACKEDLAYOUT_8888, 32, 4)
+SDL_PIXELFORMAT_BGRA8888 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRA,
+                           SDL_PACKEDLAYOUT_8888, 32, 4)
+SDL_PIXELFORMAT_ARGB2101010 =\
+    SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB,
+                           SDL_PACKEDLAYOUT_2101010, 32, 4)
+
+SDL_PIXELFORMAT_YV12 =\
+    SDL_DEFINE_PIXELFOURCC('Y', 'V', '1', '2')
+SDL_PIXELFORMAT_IYUV =\
+    SDL_DEFINE_PIXELFOURCC('I', 'Y', 'U', 'V')
+SDL_PIXELFORMAT_YUY2 =\
+    SDL_DEFINE_PIXELFOURCC('Y', 'U', 'Y', '2')
+SDL_PIXELFORMAT_UYVY =\
+    SDL_DEFINE_PIXELFOURCC('U', 'Y', 'V', 'Y')
+SDL_PIXELFORMAT_YVYU =\
+    SDL_DEFINE_PIXELFOURCC('Y', 'V', 'Y', 'U')
 
 from . import lib
 
-def _init(prefix="SDL_"):
+def _init():
+    # as an alternative, these names could go straight into sdl/__init__.py
     # allowed even though they don't start with prefix:
-    whitelist = ['ALL_PIXELFORMATS',
-                 'SDLError',
+    whitelist = ['SDLError',
                  'Struct',
                  'ffi']
     here = globals()
     import re
-    constant = re.compile(prefix + "[A-Z][A-Z]+")
+    constant = re.compile("(SDL_)(?P<pretty_name>[A-Z][A-Z].+)$")
     for name in dir(lib):
         value = getattr(lib, name)
         pretty_name = name
-        if not name.startswith(prefix):
+        match = constant.match(name)
+        if name.startswith('SDLK'):
+            pretty_name = name[3:]
+        elif not name.startswith('SDL_'):
             if not name in whitelist:
                 continue
-        elif constant.match(name) or isinstance(value, type):
+        elif isinstance(value, type):
             pretty_name = name[4:]
+        elif match:
+            pretty_name = match.group('pretty_name')
         else:
             pretty_name = name[4].lower() + name[5:]
         here[pretty_name] = value
     Wrap a cffi structure in a Python class, hiding allocation and
     dereferencing.
     """
-    def __init__(self, cdata=ffi.NULL):
-        if cdata == ffi.NULL:
-            cdata = ffi.new("%s *" % (self.__class__.__name__))
-        self.cdata = cdata
+    def __init__(self, data=None, ffi=ffi):
+        if not isinstance(data, ffi.CData):
+            self.cdata = ffi.new("%s *" % (self.__class__.__name__), data)
+	else:
+            self.cdata = data
 
     def __getattr__(self, attr):
         # XXX and if the attribute's value is another struct, return its wrapper
     def __nonzero__(self):
         return bool(self.cdata)
 
-def unbox(struct_or_cdata):
-    """Return a Struct's underlying storage to pass to low-level ffi calls."""
-    if isinstance(struct_or_cdata, Struct):
-        return struct_or_cdata.cdata
-    return struct_or_cdata
-
-def box(struct_or_cdata):
-    if isinstance(struct_or_cdata): pass
-
-    return struct_or_cdata
+def unbox(data, c_type=None, ffi=ffi):
+    """
+    Try to return something to pass to low-level ffi calls.
+    For a cffi type, return data.
+    For a Struct, return the wrapper's cdata.
+    Else try to use data as a ffi initializer for c_type.
+    """
+    if not isinstance(data, ffi.CData):
+        try:
+            return data.cdata
+        except AttributeError:
+            if c_type:
+                return ffi.new(c_type, data)
+    return data

_sdl_image/builder.py

-# Generate SDL_image wrappers.
-# Only used at build time.
-
-import os
-import re
-from _sdl import builder
-
-header = """# Automatically generated wrappers.
-# Override by adding wrappers to helpers.py.
-from .dso import ffi, _LIB
-from _sdl.structs import unbox
-
-"""
-
-def go():
-    from _sdl_image import cdefs
-    output_filename = os.path.join(os.path.dirname(__file__), "autohelpers.py")
-    with open(output_filename, "w+") as output:
-        output.write(header)
-        builder.generate(output,
-                         cdefs=cdefs,
-                         helpers=cdefs,
-                         filter=re.compile("^.* IMG_.*$"))
-
-if __name__ == "__main__":
-    go()

_sdl_image/dso.py

     return ffi.dlopen(names[0]) # pragma: no cover
 
 _LIB = dlopen(ffi,
+              'SDL2_image',
               'libSDL2_image.so',
-              'libSDL2_image-2.0.so.0',
-              'SDL2_image')
+              'libSDL2_image-2.0.so.0')

_sdl_image/renamed.py

 
 from _sdl_image import lib
 
+__all__ = []
+
 def _init():
     here = globals()
     import re
     constant = re.compile("IMG_[A-Z][A-Z]+")
     for name in dir(lib):
         if not name.startswith("IMG_"):
-            pass
+            continue
         elif constant.match(name):
             pretty_name = name[4:]
         else:
             pretty_name = name[4].lower() + name[5:]
         here[pretty_name] = getattr(lib, name)
+        __all__.append(pretty_name)
+        __all__.sort()
 
 _init()

_sdl_image/structs.py

+# Base class for struct helpers.
+
+import _sdl.structs
+from .dso import ffi
+
+class Struct(_sdl.structs.Struct):
+    """
+    Wrap a cffi structure in a Python class, hiding allocation and
+    dereferencing.
+    """
+    def __init__(self, cdata=ffi.NULL, ffi=ffi):
+        _sdl.structs.Struct(cdata, ffi)
+
+def unbox(data, c_type=None, ffi=ffi):
+    """
+    Try to return something to pass to low-level ffi calls.
+    For a cffi type, return data.
+    For a Struct, return the wrapper's cdata.
+    Else try to use data as a ffi initializer for c_type.
+    """
+    if not isinstance(data, ffi.CData):
+        try:
+            return data.cdata
+        except AttributeError:
+            if c_type:
+                return ffi.new(c_type, data)
+    return data

_sdl_mixer/builder.py

-# Generate SDL_image wrappers.
-# Only used at build time.
-
-import os
-import re
-from _sdl import builder
-
-header = """# Automatically generated wrappers.
-# Override by adding wrappers to helpers.py.
-from .dso import ffi, _LIB
-from _sdl.structs import unbox, Struct
-
-"""
-
-def go():
-    from _sdl_mixer import cdefs
-    output_filename = os.path.join(os.path.dirname(__file__), "autohelpers.py")
-    with open(output_filename, "w+") as output:
-        output.write(header)
-        builder.generate(output,
-                         cdefs=cdefs,
-                         helpers=cdefs,
-                         filter=re.compile("^.* (Mix_|MIX_).*$"))
-
-if __name__ == "__main__":
-    go()

_sdl_mixer/dso.py

     return ffi.dlopen(names[0]) # pragma: no cover
 
 _LIB = dlopen(ffi,
+              'SDL2_mixer',
               'libSDL2_mixer-2.0.so',
-              'libSDL2_mixer-2.0.so.0',
-              'SDL2_mixer')
+              'libSDL2_mixer-2.0.so.0')

_sdl_mixer/renamed.py

 from __future__ import absolute_import
 
 from _sdl_mixer import lib
+__all__ = []
 
 def _init():
     here = globals()
         else:
             pretty_name = name[4].lower() + name[5:]
         here[pretty_name] = getattr(lib, name)
+        __all__.append(pretty_name)
+        __all__.sort()
 
 _init()

_sdl_mixer/structs.py

+# Base class for struct helpers.
+
+import _sdl.structs
+from .dso import ffi
+
+class Struct(_sdl.structs.Struct):
+    """
+    Wrap a cffi structure in a Python class, hiding allocation and
+    dereferencing.
+    """
+    def __init__(self, cdata=ffi.NULL, ffi=ffi):
+        _sdl.structs.Struct(cdata, ffi)
+
+def unbox(data, c_type=None, ffi=ffi):
+    """
+    Try to return something to pass to low-level ffi calls.
+    For a cffi type, return data.
+    For a Struct, return the wrapper's cdata.
+    Else try to use data as a ffi initializer for c_type.
+    """
+    if not isinstance(data, ffi.CData):
+        try:
+            return data.cdata
+        except AttributeError:
+            if c_type:
+                return ffi.new(c_type, data)
+    return data

_sdl_ttf/__init__.py

+#

_sdl_ttf/cdefs.py

+# SDL2's SDL_ttf bindings for pysdl2-cffi.
+
+import cffi
+
+import _sdl.cdefs
+
+ffi = cffi.FFI()
+ffi.include(_sdl.cdefs.ffi)
+
+ffi.cdef("""
+extern  const SDL_version *  TTF_Linked_Version(void);
+extern  void  TTF_ByteSwappedUNICODE(int swapped);
+typedef struct _TTF_Font TTF_Font;
+extern  int  TTF_Init(void);
+extern  TTF_Font *  TTF_OpenFont(const char *file, int ptsize);
+extern  TTF_Font *  TTF_OpenFontIndex(const char *file, int ptsize, long index);
+extern  TTF_Font *  TTF_OpenFontRW(SDL_RWops *src, int freesrc, int ptsize);
+extern  TTF_Font *  TTF_OpenFontIndexRW(SDL_RWops *src, int freesrc, int ptsize, long index);
+extern  int  TTF_GetFontStyle(const TTF_Font *font);
+extern  void  TTF_SetFontStyle(TTF_Font *font, int style);
+extern  int  TTF_GetFontOutline(const TTF_Font *font);
+extern  void  TTF_SetFontOutline(TTF_Font *font, int outline);
+extern  int  TTF_GetFontHinting(const TTF_Font *font);
+extern  void  TTF_SetFontHinting(TTF_Font *font, int hinting);
+extern  int  TTF_FontHeight(const TTF_Font *font);
+extern  int  TTF_FontAscent(const TTF_Font *font);
+extern  int  TTF_FontDescent(const TTF_Font *font);
+extern  int  TTF_FontLineSkip(const TTF_Font *font);
+extern  int  TTF_GetFontKerning(const TTF_Font *font);
+extern  void  TTF_SetFontKerning(TTF_Font *font, int allowed);
+extern  long  TTF_FontFaces(const TTF_Font *font);
+extern  int  TTF_FontFaceIsFixedWidth(const TTF_Font *font);
+extern  char *  TTF_FontFaceFamilyName(const TTF_Font *font);
+extern  char *  TTF_FontFaceStyleName(const TTF_Font *font);
+extern  int  TTF_GlyphIsProvided(const TTF_Font *font, Uint16 ch);
+extern  int  TTF_GlyphMetrics(TTF_Font *font, Uint16 ch,
+                     int *minx, int *maxx,
+                                     int *miny, int *maxy, int *advance);
+extern  int  TTF_SizeText(TTF_Font *font, const char *text, int *w, int *h);
+extern  int  TTF_SizeUTF8(TTF_Font *font, const char *text, int *w, int *h);
+extern  int  TTF_SizeUNICODE(TTF_Font *font, const Uint16 *text, int *w, int *h);
+extern  SDL_Surface *  TTF_RenderText_Solid(TTF_Font *font,
+                const char *text, SDL_Color fg);
+extern  SDL_Surface *  TTF_RenderUTF8_Solid(TTF_Font *font,
+                const char *text, SDL_Color fg);
+extern  SDL_Surface *  TTF_RenderUNICODE_Solid(TTF_Font *font,
+                const Uint16 *text, SDL_Color fg);
+extern  SDL_Surface *  TTF_RenderGlyph_Solid(TTF_Font *font,
+                    Uint16 ch, SDL_Color fg);
+extern  SDL_Surface *  TTF_RenderText_Shaded(TTF_Font *font,
+                const char *text, SDL_Color fg, SDL_Color bg);
+extern  SDL_Surface *  TTF_RenderUTF8_Shaded(TTF_Font *font,
+                const char *text, SDL_Color fg, SDL_Color bg);
+extern  SDL_Surface *  TTF_RenderUNICODE_Shaded(TTF_Font *font,
+                const Uint16 *text, SDL_Color fg, SDL_Color bg);
+extern  SDL_Surface *  TTF_RenderGlyph_Shaded(TTF_Font *font,
+                Uint16 ch, SDL_Color fg, SDL_Color bg);
+extern  SDL_Surface *  TTF_RenderText_Blended(TTF_Font *font,
+                const char *text, SDL_Color fg);
+extern  SDL_Surface *  TTF_RenderUTF8_Blended(TTF_Font *font,
+                const char *text, SDL_Color fg);
+extern  SDL_Surface *  TTF_RenderUNICODE_Blended(TTF_Font *font,
+                const Uint16 *text, SDL_Color fg);
+extern  SDL_Surface *  TTF_RenderText_Blended_Wrapped(TTF_Font *font,
+                const char *text, SDL_Color fg, Uint32 wrapLength);
+extern  SDL_Surface *  TTF_RenderUTF8_Blended_Wrapped(TTF_Font *font,
+                const char *text, SDL_Color fg, Uint32 wrapLength);
+extern  SDL_Surface *  TTF_RenderUNICODE_Blended_Wrapped(TTF_Font *font,
+                const Uint16 *text, SDL_Color fg, Uint32 wrapLength);
+extern  SDL_Surface *  TTF_RenderGlyph_Blended(TTF_Font *font,
+                        Uint16 ch, SDL_Color fg);
+extern  void  TTF_CloseFont(TTF_Font *font);
+extern  void  TTF_Quit(void);
+extern  int  TTF_WasInit(void);
+extern  int TTF_GetFontKerningSize(TTF_Font *font, int prev_index, int index);
+""")
+# dlopen the SDL library.
+
+from .cdefs import ffi
+
+# strategy from cairocffi
+def dlopen(ffi, *names):
+    """Try various names for the same library, for different platforms."""
+    for name in names:
+        try:
+            return ffi.dlopen(name)
+        except OSError:
+            pass
+    # Re-raise the exception.
+    return ffi.dlopen(names[0]) # pragma: no cover
+
+_LIB = dlopen(ffi,
+              'SDL2_ttf',
+              'libSDL2_ttf.so',
+              'libSDL2_ttf-2.0.so.0')
+# Names to expose to the outside
+
+from .autohelpers import *

_sdl_ttf/renamed.py

+# "pretty" names without the NAMESPACE_ prefixes...
+from __future__ import absolute_import
+
+from _sdl_ttf import lib
+
+__all__ = []
+
+def _init():
+    here = globals()
+    import re
+    constant = re.compile("TTF_[A-Z][A-Z]+")
+    for name in dir(lib):
+        if not name.startswith("TTF_"):
+            continue
+        elif constant.match(name):
+            pretty_name = name[4:]
+        else:
+            pretty_name = name[4].lower() + name[5:]
+        here[pretty_name] = getattr(lib, name)
+        __all__.append(pretty_name)
+        __all__.sort()
+
+_init()

_sdl_ttf/structs.py

+# Base class for struct helpers.
+
+import _sdl.structs
+from .dso import ffi
+
+class Struct(_sdl.structs.Struct):
+    """
+    Wrap a cffi structure in a Python class, hiding allocation and
+    dereferencing.
+    """
+    def __init__(self, cdata=ffi.NULL, ffi=ffi):
+        _sdl.structs.Struct(cdata, ffi)
+
+def unbox(data, c_type=None, ffi=ffi):
+    """
+    Try to return something to pass to low-level ffi calls.
+    For a cffi type, return data.
+    For a Struct, return the wrapper's cdata.
+    Else try to use data as a ffi initializer for c_type.
+    """
+    if not isinstance(data, ffi.CData):
+        try:
+            return data.cdata
+        except AttributeError:
+            if c_type:
+                return ffi.new(c_type, data)
+    return data
 #!/bin/sh
 # Generate automatic wrapper helpers.
-python -m _sdl.builder
-python -m _sdl_image.builder
-python -m _sdl_mixer.builder
+python -m builder.build_sdl
+python -m builder.build_ttf
+python -m builder.build_mixer
+python -m builder.build_image

builder/__init__.py

Empty file added.

builder/build_image.py

+# Generate SDL_image wrappers.
+# Only used at build time.
+
+import os
+import re
+
+from .builder import Builder
+
+header = """# Automatically generated wrappers.
+# Override by adding wrappers to helpers.py.
+from .dso import ffi, _LIB
+from .structs import unbox
+
+"""
+
+def go():
+    from _sdl_image import cdefs
+    builder = Builder()
+    output_filename = os.path.join(os.path.dirname(__file__),
+                                   "..",
+                                   "_sdl_image",
+                                   "autohelpers.py")
+    with open(output_filename, "w+") as output:
+        output.write(header)
+        builder.generate(output,
+                         cdefs=cdefs,
+                         helpers=cdefs,
+                         filter=re.compile("^.* IMG_.*$"))
+
+if __name__ == "__main__":
+    go()

builder/build_mixer.py

+# Generate SDL_image wrappers.
+# Only used at build time.
+
+import os
+import re
+from .builder import Builder
+
+header = """# Automatically generated wrappers.
+# Override by adding wrappers to helpers.py.
+from .dso import ffi, _LIB
+from .structs import unbox, Struct
+
+"""
+
+def go():
+    from _sdl_mixer import cdefs
+    builder = Builder()
+    output_filename = os.path.join(os.path.dirname(__file__),
+                                   "..",
+                                   "_sdl_mixer",
+                                   "autohelpers.py")
+    with open(output_filename, "w+") as output:
+        output.write(header)
+        builder.generate(output,
+                         cdefs=cdefs,
+                         helpers=cdefs,
+                         filter=re.compile("^.* (Mix_|MIX_).*$"))
+
+if __name__ == "__main__":
+    go()

builder/build_sdl.py

+# Generate libSDL2 wrappers.
+
+import json
+import os.path
+import pprint
+
+from .builder import Builder
+
+header = """# Automatically generated wrappers.
+# Override by adding wrappers to helpers.py.
+from .dso import ffi, _LIB
+from .structs import Struct, unbox
+
+"""
+
+api = ["""# API
+import apipkg
+
+exports = """, """
+
+ns_dict = dict((s, '_sdl.renamed:%s' % s)
+               for s in exports if not s.startswith('_'))
+ns_dict['image'] = '_sdl_image.renamed'
+ns_dict['mixer'] = '_sdl_mixer.renamed'
+ns_dict['ttf'] = '_sdl_ttf.renamed'
+
+apipkg.initpkg(__name__, ns_dict)
+"""]
+
+
+def go():
+    from _sdl import cdefs, helpers
+
+    try:
+        with open(os.path.join(os.path.dirname(__file__), 'dox.json'), 'r') as funcdocs:
+            all_funcdocs = json.load(funcdocs)
+    except IOError:
+        all_funcdocs = {}
+
+    builder = Builder(all_funcdocs)
+
+    output_filename = os.path.join(os.path.dirname(__file__),
+                                   "..",
+                                   "_sdl",
+                                   "autohelpers.py")
+    with open(output_filename, "w+") as output:
+        output.write(header)
+        builder.generate(output, cdefs=cdefs, helpers=helpers)
+
+    import _sdl.renamed
+
+    exports = pprint.pformat(sorted(name for name in dir(_sdl.renamed)
+                                    if not name.startswith('_')))
+    api_filename = os.path.join(os.path.dirname(__file__), "..", "sdl", "__init__.py")
+    with open(api_filename, "w+") as output:
+        output.write(exports.join(api))
+
+if __name__ == "__main__":
+    go()

builder/build_ttf.py

+# Generate SDL_image wrappers.
+# Only used at build time.
+
+import os
+import re
+
+from .builder import Builder
+
+header = """# Automatically generated wrappers.
+# Override by adding wrappers to helpers.py.
+from .dso import ffi, _LIB
+from .structs import unbox, Struct
+
+"""
+
+def go():
+    from _sdl_ttf import cdefs
+    builder = Builder()
+    output_filename = os.path.join(os.path.dirname(__file__),
+                                   "..",
+                                   "_sdl_ttf",
+                                   "autohelpers.py")
+    with open(output_filename, "w+") as output:
+        output.write(header)
+        builder.generate(output,
+                         cdefs=cdefs,
+                         helpers=cdefs,
+                         filter=re.compile("^.* TTF_.*$"))
+
+if __name__ == "__main__":
+    go()

builder/builder.py

+# Quick, dirty way to generate wrapper functions by iterating over cffi's
+# parsed declarations.
+
+import cffi.model
+import collections
+import pycparser.c_ast
+
+def is_primitive(arg):
+    """Return True if arg is primitive"""
+    primitive = False
+    if hasattr(arg, 'ALL_PRIMITIVE_TYPES') and arg.get_c_name() in arg.ALL_PRIMITIVE_TYPES:
+        primitive = True
+    return primitive
+
+def is_direct(arg):
+    """Return True if arg can be handled directly by cffi."""
+    return (is_primitive(arg) or
+            (arg.get_c_name() in ('char *', 'char const *')) or
+            (hasattr(arg, 'kind') and arg.kind == 'enum'))
+
+def is_primitive_or_primitive_p(arg):
+    """Return True if arg is primitive or primitive*"""
+    primitive = False
+    if hasattr(arg, 'totype'):
+        arg = arg.totype  # a pointer
+    primitive = is_primitive(arg)
+    return primitive
+
+def is_primitive_p(arg):
+    """Return True if arg is primitive*"""
+    return is_primitive_or_primitive_p(arg) and hasattr(arg, 'totype')
+
+class IndentedWriter(object):
+    def __init__(self, writer):
+        self.writer = writer
+        self.level = 0
+        self.indentation = "    "
+
+    def writeln(self, msg):
+        self.writer.write(self.indentation * self.level)
+        self.writer.write(msg)
+        self.writer.write("\n")
+
+    def indent(self):
+        self.level += 1
+
+    def dedent(self):
+        self.level -= 1
+
+def iter_declarations(ffi):
+    """Yield all declarations from an ffi object."""
+    # Sometimes the source is a square bracket... related to ffi.include?
+    for source in ffi._cdefsources:
+        if source in '[]': continue
+        ast, macros, source = ffi._parser._parse(source)
+        for name, node in ast.children():
+            if not isinstance(node, pycparser.c_ast.Decl):
+                continue
+            yield node
+
+def get_declarations(ffi):
+    return ffi._parser._declarations
+
+def get_outargs(declaration):
+    """
+    Guess which arguments are output parameters by finding all primitive
+    arguments at the end of a function's argument list.
+    """
+    outargs = {}
+    for i in range(len(declaration.args) - 1, -1, -1):
+        arg = declaration.args[i]
+        if not is_primitive_p(arg):
+            break
+        if arg.get_c_name() in STRING_TYPES:
+            break
+        outargs[i] = arg
+    return outargs
+
+def funcnames_argnames(declarations):
+    """
+    Yield (function name, function argument names) for all functions in
+    declarations.
+
+    Some functions have parameters named None. This is either the void
+    paramete