]> git.saurik.com Git - wxWidgets.git/blob - utils/wxMMedia2/lib/vidxanm.cpp
a4ca4ef074a9426ecbcf22e84de26b109e548911
[wxWidgets.git] / utils / wxMMedia2 / lib / vidxanm.cpp
1 // -------------------------------------------------------------------------
2 // Name: vidxanm.cpp
3 // Purpose: wxMMedia
4 // Author: Guilhem Lavaux
5 // Created: 1997
6 // Updated: 1998
7 // Copyright: (C) 1997, 1998, 1999 Guilhem Lavaux
8 // License: wxWindows license
9 // -------------------------------------------------------------------------
10
11 #ifdef __GNUG__
12 #pragma implementation "vidxanm.h"
13 #endif
14
15 #include <wx/wxprec.h>
16
17 #ifndef WX_PRECOMP
18 #include <wx/wx.h>
19 #endif
20
21 // Pizza !
22 #include <wx/gtk/win_gtk.h>
23
24 #include <X11/Xlib.h>
25 #include <X11/Intrinsic.h>
26 #ifdef __WXGTK__
27 #include <gtk/gtkwidget.h>
28 #include <gtk/gtkwindow.h>
29 #include <gdk/gdk.h>
30 #include <gdk/gdkprivate.h>
31 #endif
32
33 #include <wx/filefn.h>
34 #include <wx/wfstream.h>
35
36 #define WXMMEDIA_INTERNAL
37 #include "vidbase.h"
38 #include "vidxanm.h"
39
40 IMPLEMENT_DYNAMIC_CLASS(wxVideoXANIM, wxVideoBaseDriver)
41
42 // -------------------------------------------------------------------------
43 // End process detector
44
45 class wxVideoXANIMProcess: public wxProcess {
46 public:
47 wxVideoXANIMProcess(wxVideoXANIM *xanim);
48
49 void OnTerminate(int pid, int status);
50
51 protected:
52 wxVideoXANIM *m_vid_xanim;
53 };
54
55 // -------------------------------------------------------------------------
56 // XAnim video driver (implementation)
57
58 wxVideoXANIMProcess::wxVideoXANIMProcess(wxVideoXANIM *xanim)
59 {
60 m_vid_xanim = xanim;
61 }
62
63 void wxVideoXANIMProcess::OnTerminate(int WXUNUSED(pid), int WXUNUSED(status))
64 {
65 m_vid_xanim->m_xanim_started = FALSE;
66 m_vid_xanim->OnFinished();
67 }
68
69 wxVideoXANIM::wxVideoXANIM()
70 : wxVideoBaseDriver()
71 {
72 m_internal = new wxXANIMinternal;
73 m_xanim_detector = new wxVideoXANIMProcess(this);
74 m_xanim_started = FALSE;
75 m_paused = FALSE;
76 m_filename = "";
77 m_remove_file = FALSE;
78 }
79
80 wxVideoXANIM::wxVideoXANIM(wxInputStream& str)
81 : wxVideoBaseDriver(str)
82 {
83 m_internal = new wxXANIMinternal;
84 m_xanim_detector = new wxVideoXANIMProcess(this);
85 m_xanim_started = FALSE;
86 m_paused = FALSE;
87
88 m_filename = wxGetTempFileName("vidxa");
89 m_remove_file = TRUE;
90 wxFileOutputStream fout(m_filename);
91
92 fout << str;
93 }
94
95 wxVideoXANIM::wxVideoXANIM(const wxString& filename)
96 {
97 m_internal = new wxXANIMinternal;
98 m_xanim_detector = new wxVideoXANIMProcess(this);
99 m_xanim_started = FALSE;
100 m_paused = FALSE;
101
102 m_filename = filename;
103 m_remove_file = FALSE;
104 }
105
106 wxVideoXANIM::~wxVideoXANIM()
107 {
108 if (m_xanim_started)
109 Stop();
110 delete m_internal;
111 delete m_xanim_detector;
112
113 if (m_remove_file)
114 wxRemoveFile(m_filename);
115 }
116
117 bool wxVideoXANIM::Play()
118 {
119 if (!m_paused && m_xanim_started)
120 return TRUE;
121 if (!m_video_output) {
122 wxVideoCreateFrame(this);
123 return TRUE;
124 }
125
126 // The movie starts with xanim
127 if (RestartXANIM()) {
128 m_paused = FALSE;
129 return TRUE;
130 }
131 return FALSE;
132 }
133
134 bool wxVideoXANIM::Pause()
135 {
136 if (!m_paused && SendCommand(" ")) {
137 m_paused = TRUE;
138 return TRUE;
139 }
140 return FALSE;
141 }
142
143 bool wxVideoXANIM::Resume()
144 {
145 if (m_paused && SendCommand(" ")) {
146 m_paused = FALSE;
147 return TRUE;
148 }
149 return FALSE;
150 }
151
152 bool wxVideoXANIM::Stop()
153 {
154 if (!m_xanim_started)
155 return FALSE;
156
157 SendCommand("q");
158
159 // We are waiting for the termination of the subprocess.
160 while (m_xanim_started) {
161 wxYield();
162 }
163
164 m_paused = FALSE;
165
166 return TRUE;
167 }
168
169 bool wxVideoXANIM::Resize(wxUint16 w, wxUint16 h)
170 {
171 if (!m_video_output)
172 return FALSE;
173
174 m_video_output->SetSize(w, h);
175 return FALSE;
176 }
177
178 bool wxVideoXANIM::GetSize(wxSize& size) const
179 {
180 return FALSE;
181 }
182
183 bool wxVideoXANIM::IsCapable(wxVideoType v_type)
184 {
185 if (v_type == wxVIDEO_MSAVI || v_type == wxVIDEO_MPEG ||
186 v_type == wxVIDEO_QT || v_type == wxVIDEO_GIF || v_type == wxVIDEO_JMOV ||
187 v_type == wxVIDEO_FLI || v_type == wxVIDEO_IFF || v_type == wxVIDEO_SGI)
188 return TRUE;
189 else
190 return FALSE;
191 }
192
193 bool wxVideoXANIM::IsPaused()
194 {
195 return m_paused;
196 }
197
198 bool wxVideoXANIM::IsStopped()
199 {
200 return !m_xanim_started;
201 }
202
203 bool wxVideoXANIM::AttachOutput(wxWindow& out)
204 {
205 if (!wxVideoBaseDriver::AttachOutput(out))
206 return FALSE;
207
208 return TRUE;
209 }
210
211 void wxVideoXANIM::DetachOutput()
212 {
213 SendCommand("q");
214 m_xanim_started = FALSE;
215 m_paused = FALSE;
216
217 wxVideoBaseDriver::DetachOutput();
218 }
219
220 bool wxVideoXANIM::SendCommand(const char *command, char **ret,
221 wxUint32 *size)
222 {
223 if (!m_xanim_started)
224 if (!RestartXANIM())
225 return FALSE;
226
227 // Send a command to XAnim through X11 Property
228 XChangeProperty(m_internal->xanim_dpy, m_internal->xanim_window,
229 m_internal->xanim_atom,
230 XA_STRING, 8, PropModeReplace, (unsigned char *)command,
231 strlen(command));
232 XFlush(m_internal->xanim_dpy);
233 if (ret) {
234 int prop_format;
235 Atom prop_type;
236 unsigned long extra;
237
238 XGetWindowProperty(m_internal->xanim_dpy, m_internal->xanim_window,
239 m_internal->xanim_ret, 0, 16, True, AnyPropertyType,
240 &prop_type, &prop_format, (unsigned long *)size,
241 &extra, (unsigned char **)ret);
242 }
243 return TRUE;
244 }
245
246 bool wxVideoXANIM::RestartXANIM()
247 {
248 wxString xanim_command;
249 int ret;
250 Atom prop_type;
251 int prop_format;
252 unsigned long nitems;
253 unsigned long extra;
254 char prop[4];
255 bool xanim_chg_size;
256
257 if (!m_video_output || m_xanim_started)
258 return FALSE;
259
260 // Check if we can change the size of the window dynamicly
261 xanim_chg_size = TRUE;
262 // Get current display
263 #ifdef __WXGTK__
264 m_internal->xanim_dpy = gdk_display;
265 GtkPizza *pizza = GTK_PIZZA( m_video_output->m_wxwindow );
266 GdkWindow *window = pizza->bin_window;
267
268 m_internal->xanim_window =
269 ((GdkWindowPrivate *)window)->xwindow;
270 #endif
271 // Get the XANIM atom
272 m_internal->xanim_atom = XInternAtom(m_internal->xanim_dpy,
273 "XANIM_PROPERTY", False);
274
275 // Build the command
276 xanim_command.Printf(wxT("xanim -Zr +Ze +Sr +f +W%d +f +q "
277 "+Av70 %s %s"), m_internal->xanim_window,
278 (xanim_chg_size) ? _T("") : _T(""),
279 WXSTRINGCAST m_filename);
280
281 // Execute it
282 if (!wxExecute(xanim_command, FALSE, m_xanim_detector))
283 return FALSE;
284
285 // Wait for XAnim to be ready
286 nitems = 0;
287 m_xanim_started = TRUE;
288 while (nitems == 0 && m_xanim_started) {
289 ret = XGetWindowProperty(m_internal->xanim_dpy, m_internal->xanim_window,
290 m_internal->xanim_atom,
291 0, 4, False, AnyPropertyType, &prop_type,
292 &prop_format, &nitems, &extra,
293 (unsigned char **)&prop);
294 wxYield();
295 }
296
297 m_video_output->SetSize(m_video_output->GetSize());
298 // Very useful ! Actually it sends a SETSIZE event to XAnim
299
300 m_paused = FALSE;
301
302 return TRUE;
303 }