]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/mmedia/vidxanm.cpp
suppress unused parameter warning
[wxWidgets.git] / contrib / src / mmedia / vidxanm.cpp
CommitLineData
e8482f24
GL
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
92a19c2e 11#include "wx/wxprec.h"
e8482f24
GL
12
13#ifndef WX_PRECOMP
c3be59bc 14#include "wx/wx.h"
e8482f24
GL
15#endif
16
c9ce02ac 17#ifdef __WXGTK__
e8482f24 18// Pizza !
c3be59bc 19#include "wx/gtk/win_gtk.h"
c9ce02ac 20#endif
e8482f24
GL
21
22#include <X11/Xlib.h>
23#include <X11/Intrinsic.h>
24#ifdef __WXGTK__
25#include <gtk/gtkwidget.h>
26#include <gtk/gtkwindow.h>
27#include <gdk/gdk.h>
836724c3 28#include <gdk/gdkx.h>
e8482f24
GL
29#include <gdk/gdkprivate.h>
30#endif
31
c3be59bc
WS
32#include "wx/filefn.h"
33#include "wx/wfstream.h"
34#include "wx/datstrm.h"
35#include "wx/tokenzr.h"
e8482f24
GL
36
37#define WXMMEDIA_INTERNAL
38#include "wx/mmedia/vidbase.h"
39#include "wx/mmedia/vidxanm.h"
40
41IMPLEMENT_DYNAMIC_CLASS(wxVideoXANIM, wxVideoBaseDriver)
42
43// -------------------------------------------------------------------------
44// End process detector
45
46class wxVideoXANIMProcess: public wxProcess {
47public:
48 wxVideoXANIMProcess(wxVideoXANIM *xanim);
49
50 void OnTerminate(int pid, int status);
51
52protected:
53 wxVideoXANIM *m_vid_xanim;
54};
55
56class wxVideoXANIMOutput: public wxProcess {
57public:
58 wxVideoXANIMOutput();
59
60 void OnTerminate(int pid, int status);
61
62 bool IsTerminated() const;
63protected:
64 bool m_terminated;
65};
66
67// -------------------------------------------------------------------------
68// XAnim video driver (process handling implementation)
69
70wxVideoXANIMProcess::wxVideoXANIMProcess(wxVideoXANIM *xanim)
71{
72 m_vid_xanim = xanim;
73}
74
75void wxVideoXANIMProcess::OnTerminate(int WXUNUSED(pid), int WXUNUSED(status))
76{
dea7e44a 77 m_vid_xanim->m_xanim_started = false;
e8482f24
GL
78 m_vid_xanim->OnFinished();
79}
80
81wxVideoXANIMOutput::wxVideoXANIMOutput()
dea7e44a 82 : wxProcess(NULL, wxID_ANY)
e8482f24 83{
dea7e44a 84 m_terminated = false;
e8482f24
GL
85 Redirect();
86}
87
88bool wxVideoXANIMOutput::IsTerminated() const
89{
90 return m_terminated;
91}
92
93void wxVideoXANIMOutput::OnTerminate(int pid, int status)
94{
dea7e44a 95 m_terminated = true;
e8482f24
GL
96}
97
98// -------------------------------------------------------------------------
99// XAnim video driver (implementation)
100
101wxVideoXANIM::wxVideoXANIM()
102 : wxVideoBaseDriver()
103{
104 m_internal = new wxXANIMinternal;
105 m_xanim_detector = new wxVideoXANIMProcess(this);
dea7e44a
WS
106 m_xanim_started = false;
107 m_paused = false;
6f568182 108 m_filename = wxEmptyString;
dea7e44a 109 m_remove_file = false;
e8482f24
GL
110}
111
112wxVideoXANIM::wxVideoXANIM(wxInputStream& str)
113 : wxVideoBaseDriver(str)
114{
115 m_internal = new wxXANIMinternal;
116 m_xanim_detector = new wxVideoXANIMProcess(this);
dea7e44a
WS
117 m_xanim_started = false;
118 m_paused = false;
e8482f24
GL
119 m_size[0] = 0;
120 m_size[1] = 0;
121
6f568182 122 m_filename = wxGetTempFileName(_T("vidxa"));
dea7e44a 123 m_remove_file = true;
e8482f24
GL
124 wxFileOutputStream fout(m_filename);
125
126 fout << str;
127
128 CollectInfo();
129}
130
131wxVideoXANIM::wxVideoXANIM(const wxString& filename)
132{
133 m_internal = new wxXANIMinternal;
134 m_xanim_detector = new wxVideoXANIMProcess(this);
dea7e44a
WS
135 m_xanim_started = false;
136 m_paused = false;
e8482f24
GL
137
138 m_filename = filename;
dea7e44a 139 m_remove_file = false;
e8482f24
GL
140 m_size[0] = 0;
141 m_size[1] = 0;
142
143 CollectInfo();
144}
145
146wxVideoXANIM::~wxVideoXANIM()
147{
148 if (m_xanim_started)
149 Stop();
150 delete m_internal;
151 delete m_xanim_detector;
152
153 if (m_remove_file)
154 wxRemoveFile(m_filename);
155}
156
157// -------------------------------------------------------------------------
158// Movie controller
159
160bool wxVideoXANIM::Play()
161{
162 if (!m_paused && m_xanim_started)
dea7e44a 163 return true;
e8482f24
GL
164 if (!m_video_output) {
165 wxVideoCreateFrame(this);
dea7e44a 166 return true;
e8482f24
GL
167 }
168
169 // The movie starts with xanim
170 if (RestartXANIM()) {
dea7e44a
WS
171 m_paused = false;
172 return true;
e8482f24 173 }
dea7e44a 174 return false;
e8482f24
GL
175}
176
177bool wxVideoXANIM::Pause()
178{
179 if (!m_paused && SendCommand(" ")) {
dea7e44a
WS
180 m_paused = true;
181 return true;
e8482f24 182 }
dea7e44a 183 return false;
e8482f24
GL
184}
185
186bool wxVideoXANIM::Resume()
187{
188 if (m_paused && SendCommand(" ")) {
dea7e44a
WS
189 m_paused = false;
190 return true;
e8482f24 191 }
dea7e44a 192 return false;
e8482f24
GL
193}
194
195bool wxVideoXANIM::Stop()
196{
197 if (!m_xanim_started)
dea7e44a 198 return false;
e8482f24
GL
199
200 SendCommand("q");
201
202 // We are waiting for the termination of the subprocess.
203 while (m_xanim_started) {
204 wxYield();
205 }
206
dea7e44a 207 m_paused = false;
e8482f24 208
dea7e44a 209 return true;
e8482f24
GL
210}
211
212// -------------------------------------------------------------------------
213// Movie size controller
214
215bool wxVideoXANIM::SetSize(wxSize size)
216{
217 if (!m_video_output)
dea7e44a 218 return false;
e8482f24
GL
219
220 m_video_output->SetSize(size.GetWidth(), size.GetHeight());
dea7e44a 221 return false;
e8482f24
GL
222}
223
224bool wxVideoXANIM::GetSize(wxSize& size) const
225{
226 if (m_size[0] == 0)
dea7e44a 227 return false;
e8482f24 228 size.Set(m_size[0], m_size[1]);
dea7e44a 229 return true;
e8482f24
GL
230}
231
232// -------------------------------------------------------------------------
233// Capabilities of XAnim
234
235bool wxVideoXANIM::IsCapable(wxVideoType v_type) const
236{
237 if (v_type == wxVIDEO_MSAVI || v_type == wxVIDEO_MPEG ||
dea7e44a
WS
238 v_type == wxVIDEO_QT || v_type == wxVIDEO_GIF || v_type == wxVIDEO_JMOV ||
239 v_type == wxVIDEO_FLI || v_type == wxVIDEO_IFF || v_type == wxVIDEO_SGI)
240 return true;
e8482f24 241 else
dea7e44a 242 return false;
e8482f24
GL
243}
244
245// -------------------------------------------------------------------------
246// Movie state
247
248wxString wxVideoXANIM::GetMovieCodec() const
249{
250 if (m_size[0] == 0)
251 return wxT("");
252 return m_movieCodec;
253}
254
255wxString wxVideoXANIM::GetAudioCodec() const
256{
257 if (m_size[0] == 0)
258 return wxT("");
259 return m_audioCodec;
260}
261
262wxUint32 wxVideoXANIM::GetSampleRate() const
263{
264 if (m_size[0] == 0)
265 return 0;
266 return m_sampleRate;
267}
268
269wxUint8 wxVideoXANIM::GetChannels() const
270{
271 if (m_size[0] == 0)
272 return 0;
273 return m_channels;
274}
275
276wxUint8 wxVideoXANIM::GetBPS() const
277{
278 if (m_size[0] == 0)
279 return 0;
280 return m_bps;
281}
282
283double wxVideoXANIM::GetFrameRate() const
284{
285 if (m_size[0] == 0)
286 return 0.0;
287 return m_frameRate;
288}
289
290wxUint32 wxVideoXANIM::GetNbFrames() const
291{
292 if (m_size[0] == 0)
293 return 0;
294 return m_frames;
295}
296
297
298bool wxVideoXANIM::IsPaused() const
299{
300 return m_paused;
301}
302
303bool wxVideoXANIM::IsStopped() const
304{
305 return !m_xanim_started;
306}
307
308// -------------------------------------------------------------------------
309// Output management
310
311bool wxVideoXANIM::AttachOutput(wxWindow& out)
312{
313 if (!wxVideoBaseDriver::AttachOutput(out))
dea7e44a 314 return false;
e8482f24 315
dea7e44a 316 return true;
e8482f24
GL
317}
318
319void wxVideoXANIM::DetachOutput()
320{
321 SendCommand("q");
dea7e44a
WS
322 m_xanim_started = false;
323 m_paused = false;
e8482f24
GL
324
325 wxVideoBaseDriver::DetachOutput();
326}
327
328// -------------------------------------------------------------------------
329// Lowlevel XAnim controller
330
331bool wxVideoXANIM::SendCommand(const char *command, char **ret,
dea7e44a 332 wxUint32 *size)
e8482f24
GL
333{
334 if (!m_xanim_started)
335 if (!RestartXANIM())
dea7e44a 336 return false;
e8482f24
GL
337
338 // Send a command to XAnim through X11 Property
339 XChangeProperty(m_internal->xanim_dpy, m_internal->xanim_window,
dea7e44a
WS
340 m_internal->xanim_atom,
341 XA_STRING, 8, PropModeReplace, (unsigned char *)command,
342 strlen(command));
e8482f24
GL
343 XFlush(m_internal->xanim_dpy);
344 if (ret) {
345 int prop_format;
dea7e44a
WS
346 Atom prop_type;
347 unsigned long extra;
348
349 XGetWindowProperty(m_internal->xanim_dpy, m_internal->xanim_window,
350 m_internal->xanim_ret, 0, 16, True, AnyPropertyType,
351 &prop_type, &prop_format, (unsigned long *)size,
352 &extra, (unsigned char **)ret);
e8482f24 353 }
dea7e44a 354 return true;
e8482f24
GL
355}
356
357bool wxVideoXANIM::CollectInfo()
358{
359 wxVideoXANIMOutput *xanimProcess;
360 wxString xanim_command;
361 wxStringTokenizer tokenizer;
362
363 xanimProcess = new wxVideoXANIMOutput;
364 xanim_command = wxT("xanim +v +Zv -Ae ");
365 xanim_command += m_filename;
dea7e44a
WS
366 if (!wxExecute(xanim_command, false, xanimProcess))
367 return false;
e8482f24
GL
368
369 wxInputStream *infoStream = xanimProcess->GetInputStream();
370 wxString totalOutput;
371
15e8daec 372 while (infoStream->GetLastError() == wxSTREAM_NO_ERROR) {
e8482f24
GL
373 char line[100];
374
375 infoStream->Read(line, sizeof(line)-1);
376 if (infoStream->LastRead() == 0)
377 break;
378
379 line[infoStream->LastRead()] = 0;
380
6f568182 381 totalOutput += wxString::FromAscii(line);
e8482f24
GL
382 }
383
384 // This is good for everything ... :-)
385 int position = totalOutput.Find(wxT("Video Codec:"));
386
387 totalOutput.Remove(0, position+13);
388
389 position = totalOutput.Find(wxT("depth="));
390 m_movieCodec = totalOutput(0, position);
391
392 totalOutput.Remove(0, position);
6f568182 393 tokenizer.SetString(totalOutput, wxT("\n\r"));
e8482f24
GL
394
395 // the rest of the line
396 wxString token = tokenizer.GetNextToken();
397 unsigned long my_long;
398
399#define GETINT(i) \
400totalOutput.ToULong(&my_long); \
401i = my_long;
402
403 // 'Audio Codec:'
404 totalOutput = tokenizer.GetString();
405 totalOutput.Remove(0, totalOutput.Find(wxT(":"))+2);
406
407 position = totalOutput.Find(wxT("Rate"));
408 m_audioCodec = totalOutput(0, position-1);
409
410 // 'Rate='
411 totalOutput.Remove(0, totalOutput.Find(wxT("="))+1);
412 GETINT(m_sampleRate);
413 // 'Chans='
414 totalOutput.Remove(0, totalOutput.Find(wxT("="))+1);
415 GETINT(m_channels);
416 // 'Bps='
417 totalOutput.Remove(0, totalOutput.Find(wxT("="))+1);
418 GETINT(m_bps);
419 // 'Frame Stats:'
420 tokenizer.Reinit(totalOutput);
421 tokenizer.GetNextToken();
422 totalOutput = tokenizer.GetString();
423 totalOutput.Remove(0, totalOutput.Find(wxT(":"))+2);
424 // 'Size='
425 totalOutput.Remove(0, totalOutput.Find(wxT("="))+1);
426 GETINT(m_size[0]);
427 // 'x'
428 totalOutput.Remove(0,1);
429 GETINT(m_size[1]);
430 // 'Frames='
431 totalOutput.Remove(0, totalOutput.Find(wxT("="))+1);
432 GETINT(m_frames);
433 // 'avfps='
434 totalOutput.Remove(0, totalOutput.Find(wxT("="))+1);
435 totalOutput.ToDouble(&m_frameRate);
436
437 // We wait for the conclusion
438 while (!xanimProcess->IsTerminated())
439 wxYield();
440
441 delete xanimProcess;
442
dea7e44a 443 return true;
e8482f24
GL
444}
445
446bool wxVideoXANIM::RestartXANIM()
447{
448 wxString xanim_command;
449 int ret;
450 Atom prop_type;
451 int prop_format;
452 unsigned long nitems;
453 unsigned long extra;
454 char prop[4];
455 bool xanim_chg_size;
456
457 if (!m_video_output || m_xanim_started)
dea7e44a 458 return false;
e8482f24
GL
459
460 // Check if we can change the size of the window dynamicly
dea7e44a 461 xanim_chg_size = true;
e8482f24
GL
462 // Get current display
463#ifdef __WXGTK__
464 m_internal->xanim_dpy = gdk_display;
465 GtkPizza *pizza = GTK_PIZZA( m_video_output->m_wxwindow );
466 GdkWindow *window = pizza->bin_window;
467
15e8daec 468 m_internal->xanim_window = GDK_WINDOW_XWINDOW(window);
e8482f24
GL
469#endif
470 // Get the XANIM atom
471 m_internal->xanim_atom = XInternAtom(m_internal->xanim_dpy,
dea7e44a 472 "XANIM_PROPERTY", False);
e8482f24
GL
473
474 // Build the command
7c8b87a7
WS
475 xanim_command.Printf(
476 wxT("xanim -Zr +Ze +Sr +f +W%d +f +q +Av70 %s %s"),
477 (int)m_internal->xanim_window,
478 (xanim_chg_size) ? _T("") : _T(""), // ??? why ???
479 WXSTRINGCAST m_filename);
e8482f24
GL
480
481 // Execute it
dea7e44a
WS
482 if (!wxExecute(xanim_command, false, m_xanim_detector))
483 return false;
e8482f24
GL
484
485 // Wait for XAnim to be ready
486 nitems = 0;
dea7e44a 487 m_xanim_started = true;
e8482f24
GL
488 while (nitems == 0 && m_xanim_started) {
489 ret = XGetWindowProperty(m_internal->xanim_dpy, m_internal->xanim_window,
dea7e44a
WS
490 m_internal->xanim_atom,
491 0, 4, False, AnyPropertyType, &prop_type,
492 &prop_format, &nitems, &extra,
493 (unsigned char **)&prop);
e8482f24
GL
494 wxYield();
495 }
496
497 wxSize vibrato_size;
498
499 vibrato_size = m_video_output->GetSize();
500
501 vibrato_size.SetWidth(vibrato_size.GetWidth()+1);
502 m_video_output->SetSize(vibrato_size);
503 vibrato_size.SetWidth(vibrato_size.GetWidth()-1);
504 m_video_output->SetSize(vibrato_size);
c42b1de6
GL
505 // Very useful ! Actually it "should" sends a SETSIZE event to XAnim
506 // FIXME: This event is not sent !!
e8482f24 507
dea7e44a 508 m_paused = false;
e8482f24 509
dea7e44a 510 return true;
e8482f24 511}