]> git.tdb.fi Git - xinema.git/blob - source/xineengine.cpp
656990e012ecbfafa7da5c0873ac9d350e35ecdb
[xinema.git] / source / xineengine.cpp
1 #include <stdexcept>
2 #include <msp/fs/dir.h>
3 #include <msp/graphics/display_private.h>
4 #include <msp/graphics/window_private.h>
5 #include "xineengine.h"
6
7 using namespace std;
8 using namespace Msp;
9
10 XineEngine::XineEngine(Graphics::Window &w, Mutex *m):
11         window(w),
12         display_mutex(m),
13         locked_thread(0),
14         lock_count(0),
15         pending_expose(0)
16 {
17         engine = xine_new();
18
19         FS::Path config_fn = FS::get_home_dir()/".xine"/"config";
20         xine_config_load(engine, config_fn.c_str());
21
22         xine_init(engine);
23
24         audio_driver = xine_open_audio_driver(engine, "auto", 0);
25         if(!audio_driver)
26                 throw runtime_error("Could not open audio driver");
27
28         visual.display = window.get_display().get_private().display;
29         visual.screen = 0;
30         visual.d = window.get_private().window;
31         visual.user_data = this;
32         visual.dest_size_cb = &dest_size_cb;
33         visual.frame_output_cb = &frame_output_cb;
34         if(display_mutex)
35         {
36                 visual.lock_display = &lock_cb;
37                 visual.unlock_display = &unlock_cb;
38         }
39         else
40         {
41                 visual.lock_display = 0;
42                 visual.unlock_display = 0;
43         }
44
45         video_driver = xine_open_video_driver(engine, "auto", XINE_VISUAL_TYPE_X11_2, &visual);
46         if(!video_driver)
47                 throw runtime_error("Could not open video driver");
48
49         window.signal_expose.connect(sigc::mem_fun(this, &XineEngine::window_exposed));
50 }
51
52 XineEngine::~XineEngine()
53 {
54         xine_close_video_driver(engine, video_driver);
55         xine_close_audio_driver(engine, audio_driver);
56         xine_exit(engine);
57 }
58
59 void XineEngine::tick()
60 {
61         if(pending_expose)
62         {
63                 xine_port_send_gui_data(video_driver, XINE_GUI_SEND_EXPOSE_EVENT, &pending_expose->xevent);
64                 delete pending_expose;
65                 pending_expose = 0;
66         }
67 }
68
69 void XineEngine::window_exposed(unsigned, unsigned, unsigned, unsigned, const Graphics::Window::Event &event)
70 {
71         delete pending_expose;
72         pending_expose = new Graphics::Window::Event(event);
73 }
74
75 void XineEngine::dest_size_cb(void *user_data, int, int, double, int *dest_width, int *dest_height, double *dest_pixel_aspect)
76 {
77         XineEngine &engine = *reinterpret_cast<XineEngine *>(user_data);
78         *dest_width = engine.window.get_width();
79         *dest_height = engine.window.get_height();
80         *dest_pixel_aspect = 1.0;
81 }
82
83 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)
84 {
85         XineEngine &engine = *reinterpret_cast<XineEngine *>(user_data);
86         *dest_x = 0;
87         *dest_y = 0;
88         *dest_width = engine.window.get_width();
89         *dest_height = engine.window.get_height();
90         *dest_pixel_aspect = 1.0;
91         *win_x = 0;
92         *win_y = 0;
93 }
94
95 void XineEngine::lock_cb(void *user_data)
96 {
97         XineEngine &engine = *reinterpret_cast<XineEngine *>(user_data);
98         pthread_t tid = pthread_self();
99         if(tid==engine.locked_thread)
100                 ++engine.lock_count;
101         else
102         {
103                 engine.display_mutex->lock();
104                 engine.locked_thread = tid;
105                 engine.lock_count = 1;
106         }
107 }
108
109 void XineEngine::unlock_cb(void *user_data)
110 {
111         XineEngine &engine = *reinterpret_cast<XineEngine *>(user_data);
112         pthread_t tid = pthread_self();
113         if(tid!=engine.locked_thread)
114                 throw logic_error("Unlock from non-locked thread");
115         if(!--engine.lock_count)
116         {
117                 engine.locked_thread = 0;
118                 engine.display_mutex->unlock();
119         }
120 }