Commits

Daniel Holth committed 616ea63

enhance SDL_image and add SDL_mixer bindings

  • Participants
  • Parent commits 29890b4

Comments (0)

Files changed (22)

 *.*-info
 build
 dist
+autohelpers.py

File _sdl/builder.py

 
 import os.path
 import cffi.model
-
-from . import cdefs, helpers
+import collections
 
 def is_primitive(arg):
     """Return true if arg is primitive or primitive*"""
         self.level = 0
         self.indentation = "    "
 
-    def write(self, msg):
+    def writeln(self, msg):
         self.writer.write(self.indentation * self.level)
         self.writer.write(msg)
         self.writer.write("\n")
         # it might be an anonymous struct
         return
     for name in declaration.enumerators:
-        output.write("%s = _LIB.%s" % (name, name))
-    output.write("")
+        output.writeln("%s = _LIB.%s" % (name, name))
+    output.writeln("")
+
+declarations_by_type = collections.defaultdict(list)
 
 def handle_struct(output, declaration_name, declaration):
-    output.write("class %s(Struct): pass" % declaration.name)
+    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.write("def %s(%s):" % (fname, arg_vars))
+    output.writeln("def %s(%s):" % (fname, arg_vars))
     output.indent()
-    output.write('"""' + declaration.get_c_name().replace("(*)", " " + fname) + '"""')
-    output.write("rc = _LIB.%s(%s)" % (fname,
-                                       ', '.join(["unbox(%s)" % name
-                                                  for name in arg_names])))
-    if declaration.result.get_c_name() in STRING_TYPES:
-        output.write("return ffi.string(rc)")
+    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.write("return rc")
+        output.writeln("return rc")
     output.dedent()
-    output.write("")
+    output.writeln("")
+
     return
 
     returning = []
     for i, (action, arg, returns) in enumerate(treatment(fname, declaration)):
         if action in ("pass", "self"):
-            output.write("c_args[%d] = args[%d]" % (i, i))
+            output.writeln("c_args[%d] = args[%d]" % (i, i))
         elif action == "new":
-            output.write("c_args[%d] = ffi.new(%s)" % (i, repr(arg.get_c_name())))
+            output.writeln("c_args[%d] = ffi.new(%s)" % (i, repr(arg.get_c_name())))
 
             if returns:
                 if isinstance(arg.totype, cffi.model.StructType):
                     returning.append("c_args[%d][0]" % (i,))
 
         else:
-            output.write("c_args[%d] = None" % (i, ))
+            output.writeln("c_args[%d] = None" % (i, ))
 
-    output.write("rc = _LIB.%s(*c_args)" % (fname,))
+    output.writeln("rc = _LIB.%s(*c_args)" % (fname,))
 
     if not returning:
         if declaration.result.get_c_name() == "char *":
-            output.write("return ffi.string(rc)")
+            output.writeln("return ffi.string(rc)")
         else:
-            output.write("return rc")
+            output.writeln("return rc")
     else:
         if len(returning) == 1:
-            output.write("return %s" % returning[0])
+            output.writeln("return %s" % returning[0])
         else:
-            output.write("return (" + ", ".join(returning) + ")")
+            output.writeln("return (" + ", ".join(returning) + ")")
 
     output.dedent()
-    output.write("")
+    output.writeln("")
 
-def generate(output):
+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.
     """
-    declarations = cdefs.ffi._parser._declarations
+    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):
+    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 = declarations[declaration_name]
 
         if declaration.args:
-            output.write("def %s(*args):" % fname)
+            output.writeln("def %s(*args):" % fname)
         else:
-            output.write("def %s():" % fname)
+            output.writeln("def %s():" % fname)
 
         output.indent()
-        output.write('"""' + declaration.get_c_name().replace("(*)", " " + fname) + '"""')
-        output.write("c_args = %s" % (repr([None]*len(declaration.args))))
+        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.write("c_args[%d] = args[%d]" % (i, i))
+                output.writeln("c_args[%d] = args[%d]" % (i, i))
             elif action == "new":
-                output.write("c_args[%d] = ffi.new(%s)" % (i, repr(arg.get_c_name())))
+                output.writeln("c_args[%d] = ffi.new(%s)" % (i, repr(arg.get_c_name())))
 
                 if returns:
                     if isinstance(arg.totype, cffi.model.StructType):
                         returning.append("c_args[%d][0]" % (i,))
 
             else:
-                output.write("c_args[%d] = None" % (i, ))
+                output.writeln("c_args[%d] = None" % (i, ))
 
-        output.write("rc = _LIB.%s(*c_args)" % (fname,))
+        output.writeln("rc = _LIB.%s(*c_args)" % (fname,))
 
         if not returning:
             if declaration.result.get_c_name() == "char *":
-                output.write("return ffi.string(rc)")
+                output.writeln("return ffi.string(rc)")
             else:
-                output.write("return rc")
+                output.writeln("return rc")
         else:
             if len(returning) == 1:
-                output.write("return %s" % returning[0])
+                output.writeln("return %s" % returning[0])
             else:
-                output.write("return (" + ", ".join(returning) + ")")
+                output.writeln("return (" + ", ".join(returning) + ")")
 
         output.dedent()
-        output.write("")
+        output.writeln("")
 
 header = """# Automatically generated wrappers.
 # Override by adding wrappers to helpers.py.
 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
 
-def go():
     output_filename = os.path.join(os.path.dirname(__file__), "autohelpers.py")
     with open(output_filename, "w+") as output:
         output.write(header)
-        generate(output)
+        generate(output, cdefs=cdefs, helpers=helpers)
 
     import pprint
     import _sdl.renamed

File _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()

File _sdl_image/cdefs.py

+# SDL2's SDL_image bindings for pysdl2-cffi.
+
+import cffi
+
+import _sdl.cdefs
+import _sdl.lib
+
+ffi = cffi.FFI()
+ffi.include(_sdl.cdefs.ffi)
+
+# SDL_image uses SDL_SetError / SDL_GetError for error reporting.
+
+ffi.cdef("""
+
+extern const SDL_version * IMG_Linked_Version(void);
+
+typedef enum
+{
+    IMG_INIT_JPG = 0x00000001,
+    IMG_INIT_PNG = 0x00000002,
+    IMG_INIT_TIF = 0x00000004,
+    IMG_INIT_WEBP = 0x00000008
+} IMG_InitFlags;
+
+extern int IMG_Init(int flags);
+
+extern void IMG_Quit(void);
+
+extern SDL_Surface * IMG_LoadTyped_RW(SDL_RWops *src, int freesrc, const char *type);
+
+extern SDL_Surface * IMG_Load(const char *file);
+extern SDL_Surface * IMG_Load_RW(SDL_RWops *src, int freesrc);
+
+extern SDL_Texture * IMG_LoadTexture(SDL_Renderer *renderer, const char *file);
+extern SDL_Texture * IMG_LoadTexture_RW(SDL_Renderer *renderer, SDL_RWops *src, int freesrc);
+extern SDL_Texture * IMG_LoadTextureTyped_RW(SDL_Renderer *renderer, SDL_RWops *src, int freesrc, const char *type);
+
+extern int IMG_isICO(SDL_RWops *src);
+extern int IMG_isCUR(SDL_RWops *src);
+extern int IMG_isBMP(SDL_RWops *src);
+extern int IMG_isGIF(SDL_RWops *src);
+extern int IMG_isJPG(SDL_RWops *src);
+extern int IMG_isLBM(SDL_RWops *src);
+extern int IMG_isPCX(SDL_RWops *src);
+extern int IMG_isPNG(SDL_RWops *src);
+extern int IMG_isPNM(SDL_RWops *src);
+extern int IMG_isTIF(SDL_RWops *src);
+extern int IMG_isXCF(SDL_RWops *src);
+extern int IMG_isXPM(SDL_RWops *src);
+extern int IMG_isXV(SDL_RWops *src);
+extern int IMG_isWEBP(SDL_RWops *src);
+
+extern SDL_Surface * IMG_LoadICO_RW(SDL_RWops *src);
+extern SDL_Surface * IMG_LoadCUR_RW(SDL_RWops *src);
+extern SDL_Surface * IMG_LoadBMP_RW(SDL_RWops *src);
+extern SDL_Surface * IMG_LoadGIF_RW(SDL_RWops *src);
+extern SDL_Surface * IMG_LoadJPG_RW(SDL_RWops *src);
+extern SDL_Surface * IMG_LoadLBM_RW(SDL_RWops *src);
+extern SDL_Surface * IMG_LoadPCX_RW(SDL_RWops *src);
+extern SDL_Surface * IMG_LoadPNG_RW(SDL_RWops *src);
+extern SDL_Surface * IMG_LoadPNM_RW(SDL_RWops *src);
+extern SDL_Surface * IMG_LoadTGA_RW(SDL_RWops *src);
+extern SDL_Surface * IMG_LoadTIF_RW(SDL_RWops *src);
+extern SDL_Surface * IMG_LoadXCF_RW(SDL_RWops *src);
+extern SDL_Surface * IMG_LoadXPM_RW(SDL_RWops *src);
+extern SDL_Surface * IMG_LoadXV_RW(SDL_RWops *src);
+extern SDL_Surface * IMG_LoadWEBP_RW(SDL_RWops *src);
+
+extern SDL_Surface * IMG_ReadXPMFromArray(char **xpm);
+
+extern int IMG_SavePNG(SDL_Surface *surface, const char *file);
+extern int IMG_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst);
+""")
+
+IMG_GetError = _sdl.lib.SDL_GetError
+IMG_SetError = _sdl.lib.SDL_SetError

File _sdl_image/dso.py

+# 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,
+              'libSDL2_image.so',
+              'libSDL2_image-2.0.so.0',
+              'SDL2_image')

File _sdl_image/image.py

-# SDL2's SDL_image bindings for pysdl2-cffi.
-
-import cffi
-
-import _sdl.cdefs
-from _sdl.internal import guard
-import _sdl.lib
-import _sdl.dso
-
-__missing_functions = []
-
-def lookup(name):
-    if hasattr(_LIB, name):
-        return getattr(_LIB, name)
-    __missing_functions.append(name)
-    return None
-
-ffi = cffi.FFI()
-ffi.include(_sdl.cdefs.ffi)
-
-# SDL_image uses SDL_SetError / SDL_GetError for error reporting.
-
-ffi.cdef("""
-
-extern const SDL_version * IMG_Linked_Version(void);
-
-typedef enum
-{
-    IMG_INIT_JPG = 0x00000001,
-    IMG_INIT_PNG = 0x00000002,
-    IMG_INIT_TIF = 0x00000004,
-    IMG_INIT_WEBP = 0x00000008
-} IMG_InitFlags;
-
-extern int IMG_Init(int flags);
-
-extern void IMG_Quit(void);
-
-extern SDL_Surface * IMG_LoadTyped_RW(SDL_RWops *src, int freesrc, const char *type);
-
-extern SDL_Surface * IMG_Load(const char *file);
-extern SDL_Surface * IMG_Load_RW(SDL_RWops *src, int freesrc);
-
-extern SDL_Texture * IMG_LoadTexture(SDL_Renderer *renderer, const char *file);
-extern SDL_Texture * IMG_LoadTexture_RW(SDL_Renderer *renderer, SDL_RWops *src, int freesrc);
-extern SDL_Texture * IMG_LoadTextureTyped_RW(SDL_Renderer *renderer, SDL_RWops *src, int freesrc, const char *type);
-
-extern int IMG_isICO(SDL_RWops *src);
-extern int IMG_isCUR(SDL_RWops *src);
-extern int IMG_isBMP(SDL_RWops *src);
-extern int IMG_isGIF(SDL_RWops *src);
-extern int IMG_isJPG(SDL_RWops *src);
-extern int IMG_isLBM(SDL_RWops *src);
-extern int IMG_isPCX(SDL_RWops *src);
-extern int IMG_isPNG(SDL_RWops *src);
-extern int IMG_isPNM(SDL_RWops *src);
-extern int IMG_isTIF(SDL_RWops *src);
-extern int IMG_isXCF(SDL_RWops *src);
-extern int IMG_isXPM(SDL_RWops *src);
-extern int IMG_isXV(SDL_RWops *src);
-extern int IMG_isWEBP(SDL_RWops *src);
-
-extern SDL_Surface * IMG_LoadICO_RW(SDL_RWops *src);
-extern SDL_Surface * IMG_LoadCUR_RW(SDL_RWops *src);
-extern SDL_Surface * IMG_LoadBMP_RW(SDL_RWops *src);
-extern SDL_Surface * IMG_LoadGIF_RW(SDL_RWops *src);
-extern SDL_Surface * IMG_LoadJPG_RW(SDL_RWops *src);
-extern SDL_Surface * IMG_LoadLBM_RW(SDL_RWops *src);
-extern SDL_Surface * IMG_LoadPCX_RW(SDL_RWops *src);
-extern SDL_Surface * IMG_LoadPNG_RW(SDL_RWops *src);
-extern SDL_Surface * IMG_LoadPNM_RW(SDL_RWops *src);
-extern SDL_Surface * IMG_LoadTGA_RW(SDL_RWops *src);
-extern SDL_Surface * IMG_LoadTIF_RW(SDL_RWops *src);
-extern SDL_Surface * IMG_LoadXCF_RW(SDL_RWops *src);
-extern SDL_Surface * IMG_LoadXPM_RW(SDL_RWops *src);
-extern SDL_Surface * IMG_LoadXV_RW(SDL_RWops *src);
-extern SDL_Surface * IMG_LoadWEBP_RW(SDL_RWops *src);
-
-extern SDL_Surface * IMG_ReadXPMFromArray(char **xpm);
-
-extern int IMG_SavePNG(SDL_Surface *surface, const char *file);
-extern int IMG_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst);
-""")
-
-_LIB = _sdl.dso.dlopen(ffi,
-                       'libSDL2_image.so',
-                       'libSDL2_image-2.0.so.0',
-                       'SDL2_image')
-
-IMG_INIT_JPG = lookup('IMG_INIT_JPG')
-IMG_INIT_PNG = lookup('IMG_INIT_PNG')
-IMG_INIT_TIF = lookup('IMG_INIT_TIF')
-IMG_INIT_WEBP = lookup('IMG_INIT_WEBP')
-
-IMG_Init = guard(lookup("IMG_Init"))
-IMG_InitJPG = guard(lookup("IMG_InitJPG"))
-IMG_InitPNG = guard(lookup("IMG_InitPNG"))
-IMG_InitTIF = guard(lookup("IMG_InitTIF"))
-IMG_InitWEBP = guard(lookup("IMG_InitWEBP"))
-IMG_isBMP = guard(lookup("IMG_isBMP"))
-IMG_isCUR = guard(lookup("IMG_isCUR"))
-IMG_isGIF = guard(lookup("IMG_isGIF"))
-IMG_isICO = guard(lookup("IMG_isICO"))
-IMG_isJPG = guard(lookup("IMG_isJPG"))
-IMG_isLBM = guard(lookup("IMG_isLBM"))
-IMG_isPCX = guard(lookup("IMG_isPCX"))
-IMG_isPNG = guard(lookup("IMG_isPNG"))
-IMG_isPNM = guard(lookup("IMG_isPNM"))
-IMG_isTIF = guard(lookup("IMG_isTIF"))
-IMG_isWEBP = guard(lookup("IMG_isWEBP"))
-IMG_isXCF = guard(lookup("IMG_isXCF"))
-IMG_isXPM = guard(lookup("IMG_isXPM"))
-IMG_isXV = guard(lookup("IMG_isXV"))
-IMG_Linked_Version = guard(lookup("IMG_Linked_Version"))
-IMG_Load = guard(lookup("IMG_Load"))
-IMG_LoadBMP_RW = guard(lookup("IMG_LoadBMP_RW"))
-IMG_LoadCUR_RW = guard(lookup("IMG_LoadCUR_RW"))
-IMG_LoadGIF_RW = guard(lookup("IMG_LoadGIF_RW"))
-IMG_LoadICO_RW = guard(lookup("IMG_LoadICO_RW"))
-IMG_LoadJPG_RW = guard(lookup("IMG_LoadJPG_RW"))
-IMG_LoadLBM_RW = guard(lookup("IMG_LoadLBM_RW"))
-IMG_LoadPCX_RW = guard(lookup("IMG_LoadPCX_RW"))
-IMG_LoadPNG_RW = guard(lookup("IMG_LoadPNG_RW"))
-IMG_LoadPNM_RW = guard(lookup("IMG_LoadPNM_RW"))
-IMG_Load_RW = guard(lookup("IMG_Load_RW"))
-IMG_LoadTexture = guard(lookup("IMG_LoadTexture"))
-IMG_LoadTexture_RW = guard(lookup("IMG_LoadTexture_RW"))
-IMG_LoadTextureTyped_RW = guard(lookup("IMG_LoadTextureTyped_RW"))
-IMG_LoadTGA_RW = guard(lookup("IMG_LoadTGA_RW"))
-IMG_LoadTIF_RW = guard(lookup("IMG_LoadTIF_RW"))
-IMG_LoadTyped_RW = guard(lookup("IMG_LoadTyped_RW"))
-IMG_LoadWEBP_RW = guard(lookup("IMG_LoadWEBP_RW"))
-IMG_LoadXCF_RW = guard(lookup("IMG_LoadXCF_RW"))
-IMG_LoadXPM_RW = guard(lookup("IMG_LoadXPM_RW"))
-IMG_LoadXV_RW = guard(lookup("IMG_LoadXV_RW"))
-IMG_Quit = guard(lookup("IMG_Quit"))
-IMG_QuitJPG = guard(lookup("IMG_QuitJPG"))
-IMG_QuitPNG = guard(lookup("IMG_QuitPNG"))
-IMG_QuitTIF = guard(lookup("IMG_QuitTIF"))
-IMG_QuitWEBP = guard(lookup("IMG_QuitWEBP"))
-
-IMG_GetError = _sdl.lib.SDL_GetError
-IMG_SetError = _sdl.lib.SDL_SetError

File _sdl_image/lib.py

+# Names to expose to the outside
+
+from .autohelpers import *

File _sdl_image/renamed.py

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

File _sdl_mixer/__init__.py

Empty file added.

File _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()

File _sdl_mixer/cdefs.py

+# SDL_mixer wrapper.
+# Part of pysdl2-cffi.
+
+import cffi
+import _sdl.cdefs
+
+ffi = cffi.FFI()
+ffi.include(_sdl.cdefs.ffi)
+
+# TODO use defines
+#define SDL_MIXER_MAJOR_VERSION 2
+#define SDL_MIXER_MINOR_VERSION 0
+#define SDL_MIXER_PATCHLEVEL    0
+#define SDL_MIXER_VERSION(X)                        \
+#define MIX_MAJOR_VERSION   SDL_MIXER_MAJOR_VERSION
+#define MIX_MINOR_VERSION   SDL_MIXER_MINOR_VERSION
+#define MIX_PATCHLEVEL      SDL_MIXER_PATCHLEVEL
+#define MIX_VERSION(X)      SDL_MIXER_VERSION(X)
+
+#define Mix_LoadWAV(file)   Mix_LoadWAV_RW(SDL_RWFromFile(file, "rb"), 1)
+#define MIX_CHANNEL_POST  -2
+#define MIX_EFFECTSMAXSPEED  "MIX_EFFECTSMAXSPEED"
+#define Mix_PlayChannel(channel,chunk,loops) Mix_PlayChannelTimed(channel,chunk,loops,-1)
+#define Mix_FadeInChannel(channel,chunk,loops,ms) Mix_FadeInChannelTimed(channel,chunk,loops,ms,-1)
+#define Mix_SetError    SDL_SetError
+#define Mix_GetError    SDL_GetError
+
+ffi.cdef("""
+extern int SDL_GetRevisionNumber(void);
+extern const SDL_version * Mix_Linked_Version(void);
+typedef enum
+{
+    MIX_INIT_FLAC = 0x00000001,
+    MIX_INIT_MOD = 0x00000002,
+    MIX_INIT_MODPLUG = 0x00000004,
+    MIX_INIT_MP3 = 0x00000008,
+    MIX_INIT_OGG = 0x00000010,
+    MIX_INIT_FLUIDSYNTH = 0x00000020
+} MIX_InitFlags;
+extern int Mix_Init(int flags);
+extern void Mix_Quit(void);
+typedef struct Mix_Chunk {
+    int allocated;
+    Uint8 *abuf;
+    Uint32 alen;
+    Uint8 volume;
+} Mix_Chunk;
+typedef enum {
+    MIX_NO_FADING,
+    MIX_FADING_OUT,
+    MIX_FADING_IN
+} Mix_Fading;
+typedef enum {
+    MUS_NONE,
+    MUS_CMD,
+    MUS_WAV,
+    MUS_MOD,
+    MUS_MID,
+    MUS_OGG,
+    MUS_MP3,
+    MUS_MP3_MAD,
+    MUS_FLAC,
+    MUS_MODPLUG
+} Mix_MusicType;
+typedef struct _Mix_Music Mix_Music;
+extern int Mix_OpenAudio(int frequency, Uint16 format, int channels, int chunksize);
+extern int Mix_AllocateChannels(int numchans);
+extern int Mix_QuerySpec(int *frequency,Uint16 *format,int *channels);
+extern Mix_Chunk * Mix_LoadWAV_RW(SDL_RWops *src, int freesrc);
+extern Mix_Music * Mix_LoadMUS(const char *file);
+extern Mix_Music * Mix_LoadMUS_RW(SDL_RWops *src, int freesrc);
+extern Mix_Music * Mix_LoadMUSType_RW(SDL_RWops *src, Mix_MusicType type, int freesrc);
+extern Mix_Chunk * Mix_QuickLoad_WAV(Uint8 *mem);
+extern Mix_Chunk * Mix_QuickLoad_RAW(Uint8 *mem, Uint32 len);
+extern void Mix_FreeChunk(Mix_Chunk *chunk);
+extern void Mix_FreeMusic(Mix_Music *music);
+extern int Mix_GetNumChunkDecoders(void);
+extern const char * Mix_GetChunkDecoder(int index);
+extern int Mix_GetNumMusicDecoders(void);
+extern const char * Mix_GetMusicDecoder(int index);
+extern Mix_MusicType Mix_GetMusicType(const Mix_Music *music);
+extern void Mix_SetPostMix(void (*mix_func)(void *udata, Uint8 *stream, int len), void *arg);
+extern void Mix_HookMusic(void (*mix_func)(void *udata, Uint8 *stream, int len), void *arg);
+extern void Mix_HookMusicFinished(void (*music_finished)(void));
+extern void * Mix_GetMusicHookData(void);
+extern void Mix_ChannelFinished(void (*channel_finished)(int channel));
+typedef void (*Mix_EffectFunc_t)(int chan, void *stream, int len, void *udata);
+typedef void (*Mix_EffectDone_t)(int chan, void *udata);
+extern int Mix_RegisterEffect(int chan, Mix_EffectFunc_t f, Mix_EffectDone_t d, void *arg);
+extern int Mix_UnregisterEffect(int channel, Mix_EffectFunc_t f);
+extern int Mix_UnregisterAllEffects(int channel);
+extern int Mix_SetPanning(int channel, Uint8 left, Uint8 right);
+extern int Mix_SetPosition(int channel, Sint16 angle, Uint8 distance);
+extern int Mix_SetDistance(int channel, Uint8 distance);
+extern int Mix_SetReverseStereo(int channel, int flip);
+extern int Mix_ReserveChannels(int num);
+extern int Mix_GroupChannel(int which, int tag);
+extern int Mix_GroupChannels(int from, int to, int tag);
+extern int Mix_GroupAvailable(int tag);
+extern int Mix_GroupCount(int tag);
+extern int Mix_GroupOldest(int tag);
+extern int Mix_GroupNewer(int tag);
+extern int Mix_PlayChannelTimed(int channel, Mix_Chunk *chunk, int loops, int ticks);
+extern int Mix_PlayMusic(Mix_Music *music, int loops);
+extern int Mix_FadeInMusic(Mix_Music *music, int loops, int ms);
+extern int Mix_FadeInMusicPos(Mix_Music *music, int loops, int ms, double position);
+extern int Mix_FadeInChannelTimed(int channel, Mix_Chunk *chunk, int loops, int ms, int ticks);
+extern int Mix_Volume(int channel, int volume);
+extern int Mix_VolumeChunk(Mix_Chunk *chunk, int volume);
+extern int Mix_VolumeMusic(int volume);
+extern int Mix_HaltChannel(int channel);
+extern int Mix_HaltGroup(int tag);
+extern int Mix_HaltMusic(void);
+extern int Mix_ExpireChannel(int channel, int ticks);
+extern int Mix_FadeOutChannel(int which, int ms);
+extern int Mix_FadeOutGroup(int tag, int ms);
+extern int Mix_FadeOutMusic(int ms);
+extern Mix_Fading Mix_FadingMusic(void);
+extern Mix_Fading Mix_FadingChannel(int which);
+extern void Mix_Pause(int channel);
+extern void Mix_Resume(int channel);
+extern int Mix_Paused(int channel);
+extern void Mix_PauseMusic(void);
+extern void Mix_ResumeMusic(void);
+extern void Mix_RewindMusic(void);
+extern int Mix_PausedMusic(void);
+extern int Mix_SetMusicPosition(double position);
+extern int Mix_Playing(int channel);
+extern int Mix_PlayingMusic(void);
+extern int Mix_SetMusicCMD(const char *command);
+extern int Mix_SetSynchroValue(int value);
+extern int Mix_GetSynchroValue(void);
+extern int Mix_SetSoundFonts(const char *paths);
+extern const char* Mix_GetSoundFonts(void);
+extern int Mix_EachSoundFont(int (*function)(const char*, void*), void *data);
+extern Mix_Chunk * Mix_GetChunk(int channel);
+extern void Mix_CloseAudio(void);
+""")
+
+

File _sdl_mixer/constants.py

+# Constants and macros for SDL_mixer
+
+AUDIO_S16LSB = 0x8010
+AUDIO_S16MSB = 0x9010
+AUDIO_S16 = AUDIO_S16LSB
+AUDIO_S16SYS = AUDIO_S16LSB
+MIX_DEFAULT_FORMAT = AUDIO_S16LSB
+MIX_CHANNELS = 8
+MIX_DEFAULT_FREQUENCY = 22050
+MIX_DEFAULT_CHANNELS = 2
+MIX_MAX_VOLUME = 128

File _sdl_mixer/dso.py

+# 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,
+              'libSDL2_mixer-2.0.so',
+              'libSDL2_mixer-2.0.so.0',
+              'SDL2_mixer')

File _sdl_mixer/lib.py

+# Names to expose to the outside
+
+from .constants import *
+from .autohelpers import *

File _sdl_mixer/renamed.py

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

File build.py

-#!/usr/bin/env python
-# Run the bindings generator.
-import _sdl.builder ; _sdl.builder.go()
+#!/bin/sh
+# Generate automatic wrapper helpers.
+python -m _sdl.builder
+python -m _sdl_image.builder
+python -m _sdl_mixer.builder

File sdl/__init__.py

 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)

File tests/loopwave.py

 
     # Clean up on signal
     SDL_CloseAudio()
-    SDL_FreeWAV(wave.sound)
+    SDL_FreeWAV(wave.sound_p[0])
     SDL_Quit()
     return 0
 

File tests/playmus.py

+# PLAYMUS:  A test application for the SDL mixer 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.
+
+import os
+import sys
+
+from _sdl.lib import SDL_Init, SDL_Delay, SDL_Quit, SDL_INIT_AUDIO
+from _sdl_mixer.lib import *
+
+audio_open = 0
+music = ffi.NULL
+next_track = 0
+
+def CleanUp(exitcode):
+    if Mix_PlayingMusic():
+        Mix_FadeOutMusic(1500)
+        SDL_Delay(1500)
+    if music:
+        Mix_FreeMusic(music)
+        music = NULL
+    if audio_open:
+        Mix_CloseAudio()
+        audio_open = 0
+    SDL_Quit()
+    sys.exit(exitcode)
+
+def Usage(argv0):
+    sys.stderr.write("Usage: %s [-i] [-l] [-8] [-r rate] [-c channels] [-b buffers] [-v N] [-rwops] <musicfile>\n" % (argv0))
+
+def Menu():
+    sys.stdout.write("Available commands: (p)ause (r)esume (h)alt volume(v#) > ")
+    sys.stdin.flush()
+
+#     if (scanf("%s" % (buf)) == 1)
+#         switch buf[0]:
+#         case 'p': case 'P':
+#             Mix_PauseMusic()
+#             break
+#         case 'r': case 'R':
+#             Mix_ResumeMusic()
+#             break
+#         case 'h': case 'H':
+#             Mix_HaltMusic()
+#             break
+#         case 'v': case 'V':
+#             Mix_VolumeMusic(int(buf+1))
+#             break
+#
+#     printf("Music playing: %s Paused: %s\n" % (Mix_PlayingMusic() ? "yes" : "no",
+#            Mix_PausedMusic() ? "yes" : "no")
+
+def main():
+    audio_format = None
+    audio_volume = MIX_MAX_VOLUME
+    looping = 0
+    interactive = 0
+    rwops = 0
+
+    # Initialize variables
+    audio_rate = 22050
+    audio_format = AUDIO_S16
+    audio_channels = 2
+    audio_buffers = 4096
+
+    # Initialize the SDL library
+    if SDL_Init(SDL_INIT_AUDIO) < 0 :
+        sys.stderr.write("Couldn't initialize SDL: %s\n" % (SDL_GetError()))
+        return 255
+
+    # Open the audio device
+    if Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers) < 0:
+        sys.stderr.write("Couldn't open audio: %s\n" % (SDL_GetError()))
+        return(2)
+    else:
+        audio_rate = ffi.new("int *")
+        audio_format = ffi.new("uint16_t *")
+        audio_channels = ffi.new("int *")
+        Mix_QuerySpec(audio_rate, audio_format, audio_channels)
+        sys.stdout.write("Opened audio at %d Hz %d bit %s (%s), %d bytes audio buffer\n" % (audio_rate[0],
+            (audio_format[0] & 0xFF),
+            "surround" if (audio_channels[0] > 2)  else "stereo" if (audio_channels[0] > 1) else "mono",
+            "BE" if (audio_format[0] & 0x1000) else "LE",
+            audio_buffers))
+    audio_open = 1
+
+    # Set the music volume
+    Mix_VolumeMusic(audio_volume)
+
+    # Set the external music player, if any
+    if os.getenv("MUSIC_CMD"):
+        Mix_SetMusicCMD(os.getenv("MUSIC_CMD"))
+
+    next_track = 0
+
+    i = 1
+
+    # Load the requested music file
+    if rwops:
+        music = Mix_LoadMUS_RW(SDL_RWFromFile(argv[i], "rb"), SDL_TRUE)
+    else:
+        music = Mix_LoadMUS(sys.argv[i])
+    if  music == ffi.NULL :
+        sys.stderr.write("Couldn't load %s: %s\n" % (sys.argv[i], SDL_GetError()))
+        CleanUp(2)
+
+    # Play and then exit
+    sys.stdout.write("Playing %s\n" % (sys.argv[i]))
+    Mix_FadeInMusic(music, looping, 2000)
+    while not next_track and (Mix_PlayingMusic() or Mix_PausedMusic()):
+        if interactive:
+            Menu()
+        else:
+            SDL_Delay(100)
+    Mix_FreeMusic(music)
+    music = ffi.NULL
+
+    # If the user presses Ctrl-C more than once, exit.
+    SDL_Delay(500)
+    if next_track > 1: return
+
+    i += 1
+
+    CleanUp(0)
+
+    # Not reached, but fixes compiler warnings
+    return 0
+
+if __name__ == "__main__":
+    sys.exit(main())

File tests/testhotplug.py

                     instance = SDL_JoystickInstanceID(joystick)
                     SDL_Log("Joy Added  : %d : %s\n" % (event.jdevice.which, SDL_JoystickName(joystick)))
                     if enable_haptic:
+                        import pdb; pdb.set_trace()
                         if SDL_JoystickIsHaptic(joystick):
                             haptic = SDL_HapticOpenFromJoystick(joystick)
                             if haptic:

File tests/testviewport.py

     while not done:
         # Check for events
         frames += 1
-        while SDL_PollEvent():
+        while SDL_PollEvent(event):
             pass # should check for escape...
             # SDLTest_CommonEvent(state, &event, &done)