3 #include <msp/fs/dir.h>
4 #include <msp/graphics/display_private.h>
5 #include <msp/graphics/window_private.h>
6 #include "xineengine.h"
7 #include "xinestream.h"
12 XineEngine::XineEngine(Graphics::Window &w, Mutex *m):
21 FS::Path config_fn = FS::get_home_dir()/".xine"/"config";
22 xine_config_load(engine, config_fn.c_str());
26 audio_driver = xine_open_audio_driver(engine, "auto", 0);
28 throw runtime_error("Could not open audio driver");
30 visual.display = window.get_display().get_private().display;
32 visual.d = window.get_private().window;
33 visual.user_data = this;
34 visual.dest_size_cb = &dest_size_cb;
35 visual.frame_output_cb = &frame_output_cb;
38 visual.lock_display = &lock_cb;
39 visual.unlock_display = &unlock_cb;
43 visual.lock_display = 0;
44 visual.unlock_display = 0;
47 video_driver = xine_open_video_driver(engine, "auto", XINE_VISUAL_TYPE_X11_2, &visual);
49 throw runtime_error("Could not open video driver");
51 window.signal_expose.connect(sigc::mem_fun(this, &XineEngine::window_exposed));
54 XineEngine::~XineEngine()
56 xine_close_video_driver(engine, video_driver);
57 xine_close_audio_driver(engine, audio_driver);
61 void XineEngine::add_stream(XineStream &stream)
63 streams.push_back(&stream);
66 void XineEngine::remove_stream(XineStream &stream)
68 list<XineStream *>::iterator i = find(streams.begin(), streams.end(), &stream);
73 void XineEngine::tick()
77 xine_port_send_gui_data(video_driver, XINE_GUI_SEND_EXPOSE_EVENT, &pending_expose->xevent);
78 delete pending_expose;
82 for(list<XineStream *>::const_iterator i=streams.begin(); i!=streams.end(); ++i)
86 void XineEngine::window_exposed(unsigned, unsigned, unsigned, unsigned, const Graphics::Window::Event &event)
88 delete pending_expose;
89 pending_expose = new Graphics::Window::Event(event);
92 void XineEngine::dest_size_cb(void *user_data, int, int, double, int *dest_width, int *dest_height, double *dest_pixel_aspect)
94 XineEngine &engine = *reinterpret_cast<XineEngine *>(user_data);
95 *dest_width = engine.window.get_width();
96 *dest_height = engine.window.get_height();
97 *dest_pixel_aspect = 1.0;
100 void XineEngine::frame_output_cb(void *user_data, int, int, double, int *dest_x, int *dest_y, int *dest_width, int *dest_height, double *dest_pixel_aspect, int *win_x, int *win_y)
102 XineEngine &engine = *reinterpret_cast<XineEngine *>(user_data);
105 *dest_width = engine.window.get_width();
106 *dest_height = engine.window.get_height();
107 *dest_pixel_aspect = 1.0;
112 void XineEngine::lock_cb(void *user_data)
114 XineEngine &engine = *reinterpret_cast<XineEngine *>(user_data);
115 pthread_t tid = pthread_self();
116 if(tid==engine.locked_thread)
120 engine.display_mutex->lock();
121 engine.locked_thread = tid;
122 engine.lock_count = 1;
126 void XineEngine::unlock_cb(void *user_data)
128 XineEngine &engine = *reinterpret_cast<XineEngine *>(user_data);
129 pthread_t tid = pthread_self();
130 if(tid!=engine.locked_thread)
131 throw logic_error("Unlock from non-locked thread");
132 if(!--engine.lock_count)
134 engine.locked_thread = 0;
135 engine.display_mutex->unlock();