Commit a3bcbaaf authored by Olivier Aubert's avatar Olivier Aubert

python-ctypes: implement support for callbacks

parent 54d73b7c
...@@ -2,7 +2,7 @@ MODULE_NAME=vlc.py ...@@ -2,7 +2,7 @@ MODULE_NAME=vlc.py
all: $(MODULE_NAME) all: $(MODULE_NAME)
$(MODULE_NAME): generate.py header.py override.py ../../include/vlc/*.h $(MODULE_NAME): generate.py header.py footer.py override.py ../../include/vlc/*.h
./generate.py ../../include/vlc/*.h > $@ ./generate.py ../../include/vlc/*.h > $@
doc: $(MODULE_NAME) doc: $(MODULE_NAME)
......
* Investigate memory management * Investigate memory management
* Implement event callbacks
* Write a test suite * Write a test suite
* Support multiple VLC versions: define a front-end module which will * Support multiple VLC versions: define a front-end module which will
......
# Footer code.
class MediaEvent(ctypes.Structure):
_fields_ = [
('media_name', ctypes.c_char_p),
('instance_name', ctypes.c_char_p),
]
class EventUnion(ctypes.Union):
_fields_ = [
('meta_type', ctypes.c_uint),
('new_child', ctypes.c_uint),
('new_duration', ctypes.c_longlong),
('new_status', ctypes.c_int),
('media', ctypes.c_void_p),
('new_state', ctypes.c_uint),
# Media instance
('new_position', ctypes.c_float),
('new_time', ctypes.c_longlong),
('new_title', ctypes.c_int),
('new_seekable', ctypes.c_longlong),
('new_pausable', ctypes.c_longlong),
# FIXME: Skipped MediaList and MediaListView...
('filename', ctypes.c_char_p),
('new_length', ctypes.c_longlong),
('media_event', MediaEvent),
]
class Event(ctypes.Structure):
_fields_ = [
('type', EventTypeT),
('object', ctypes.c_void_p),
('u', EventUnion),
]
# Decorator for callback methods
callbackmethod=ctypes.CFUNCTYPE(None, Event, ctypes.c_void_p)
# Example callback method
@callbackmethod
def debug_callback(event, data):
print "Debug callback method"
print "Event:", event
print "Data", data
if __name__ == '__main__':
import sys
if sys.argv[1:]:
i=vlc.Instance()
m=i.media_new(sys.argv[1])
p=MediaPlayer()
p.set_media(m)
p.play()
...@@ -59,13 +59,13 @@ blacklist=[ ...@@ -59,13 +59,13 @@ blacklist=[
"libvlc_exception_get_message", "libvlc_exception_get_message",
"libvlc_get_vlc_instance", "libvlc_get_vlc_instance",
"libvlc_media_add_option_flag",
"libvlc_media_list_view_index_of_item", "libvlc_media_list_view_index_of_item",
"libvlc_media_list_view_insert_at_index", "libvlc_media_list_view_insert_at_index",
"libvlc_media_list_view_remove_at_index", "libvlc_media_list_view_remove_at_index",
"libvlc_media_list_view_add_item", "libvlc_media_list_view_add_item",
# In svn but not in current 1.0.0 # In svn but not in current 1.0.0
"libvlc_media_add_option_flag",
'libvlc_video_set_deinterlace', 'libvlc_video_set_deinterlace',
'libvlc_video_get_marquee_option_as_int', 'libvlc_video_get_marquee_option_as_int',
'libvlc_video_get_marquee_option_as_string', 'libvlc_video_get_marquee_option_as_string',
...@@ -74,10 +74,6 @@ blacklist=[ ...@@ -74,10 +74,6 @@ blacklist=[
'libvlc_vlm_get_event_manager', 'libvlc_vlm_get_event_manager',
'mediacontrol_PlaylistSeq__free', 'mediacontrol_PlaylistSeq__free',
# TODO
"libvlc_event_detach",
"libvlc_event_attach",
] ]
# Precompiled regexps # Precompiled regexps
...@@ -106,7 +102,7 @@ typ2class={ ...@@ -106,7 +102,7 @@ typ2class={
'libvlc_log_t*': 'Log', 'libvlc_log_t*': 'Log',
'libvlc_log_iterator_t*': 'LogIterator', 'libvlc_log_iterator_t*': 'LogIterator',
'libvlc_log_message_t*': 'LogMessage', 'libvlc_log_message_t*': 'LogMessage',
'libvlc_event_type_t': 'EventType', 'libvlc_event_type_t': 'ctypes.c_uint',
'libvlc_event_manager_t*': 'EventManager', 'libvlc_event_manager_t*': 'EventManager',
'libvlc_media_discoverer_t*': 'MediaDiscoverer', 'libvlc_media_discoverer_t*': 'MediaDiscoverer',
'libvlc_media_library_t*': 'MediaLibrary', 'libvlc_media_library_t*': 'MediaLibrary',
...@@ -134,7 +130,7 @@ typ2class={ ...@@ -134,7 +130,7 @@ typ2class={
'unsigned': 'ctypes.c_uint', 'unsigned': 'ctypes.c_uint',
'int': 'ctypes.c_int', 'int': 'ctypes.c_int',
'...': 'FIXMEva_list', '...': 'FIXMEva_list',
'libvlc_callback_t': 'FIXMEcallback', 'libvlc_callback_t': 'ctypes.c_void_p',
'libvlc_time_t': 'ctypes.c_longlong', 'libvlc_time_t': 'ctypes.c_longlong',
} }
...@@ -147,7 +143,6 @@ defined_classes=( ...@@ -147,7 +143,6 @@ defined_classes=(
'Log', 'Log',
'LogIterator', 'LogIterator',
#'LogMessage', #'LogMessage',
'EventType',
'EventManager', 'EventManager',
'MediaDiscoverer', 'MediaDiscoverer',
'MediaLibrary', 'MediaLibrary',
...@@ -157,9 +152,6 @@ defined_classes=( ...@@ -157,9 +152,6 @@ defined_classes=(
'TrackDescription', 'TrackDescription',
'AudioOutput', 'AudioOutput',
'MediaControl', 'MediaControl',
#'RGBPicture',
#'MediaControlPosition',
#'MediaControlStreamInformation',
) )
# Definition of prefixes that we can strip from method names when # Definition of prefixes that we can strip from method names when
...@@ -195,10 +187,10 @@ def parse_param(s): ...@@ -195,10 +187,10 @@ def parse_param(s):
# K&R definition: only type # K&R definition: only type
return s.replace(' ', ''), '' return s.replace(' ', ''), ''
def generate_header(classes=None): def insert_code(filename):
"""Generate header code. """Generate header/footer code.
""" """
f=open('header.py', 'r') f=open(filename, 'r')
for l in f: for l in f:
if 'build_date' in l: if 'build_date' in l:
print 'build_date="%s"' % time.ctime() print 'build_date="%s"' % time.ctime()
...@@ -603,11 +595,12 @@ if __name__ == '__main__': ...@@ -603,11 +595,12 @@ if __name__ == '__main__':
if debug: if debug:
sys.exit(0) sys.exit(0)
generate_header() insert_code('header.py')
generate_enums(enums) generate_enums(enums)
wrapped=generate_wrappers(methods) wrapped=generate_wrappers(methods)
for l in methods: for l in methods:
output_ctypes(*l) output_ctypes(*l)
insert_code('footer.py')
all=set( t[1] for t in methods ) all=set( t[1] for t in methods )
not_wrapped=all.difference(wrapped) not_wrapped=all.difference(wrapped)
......
...@@ -86,6 +86,9 @@ class LogMessage(ctypes.Structure): ...@@ -86,6 +86,9 @@ class LogMessage(ctypes.Structure):
('message', ctypes.c_char_p), ('message', ctypes.c_char_p),
] ]
def __str__(self):
print "vlc.LogMessage(%d:%s): %s" % (self.severity, self.type, self.message)
class MediaControlPosition(ctypes.Structure): class MediaControlPosition(ctypes.Structure):
_fields_= [ _fields_= [
('origin', ctypes.c_ushort), ('origin', ctypes.c_ushort),
...@@ -142,9 +145,6 @@ class RGBPicture(ctypes.Structure): ...@@ -142,9 +145,6 @@ class RGBPicture(ctypes.Structure):
def free(self): def free(self):
mediacontrol_RGBPicture__free(self) mediacontrol_RGBPicture__free(self)
# Decorator for callback methods
callbackmethod=ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_void_p)
def check_vlc_exception(result, func, args): def check_vlc_exception(result, func, args):
"""Error checking method for functions using an exception in/out parameter. """Error checking method for functions using an exception in/out parameter.
""" """
......
...@@ -101,7 +101,7 @@ class MediaPlayer: ...@@ -101,7 +101,7 @@ class MediaPlayer:
if p: if p:
o.set_media(i.media_new(p[0])) o.set_media(i.media_new(p[0]))
return o return o
def get_instance(self): def get_instance(self):
"""Return the associated vlc.Instance. """Return the associated vlc.Instance.
""" """
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment