~ubuntu-branches/ubuntu/hoary/kdemultimedia/hoary

« back to all changes in this revision

Viewing changes to aktion/kxanim.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Martin Schulze
  • Date: 2003-01-22 15:00:51 UTC
  • Revision ID: james.westby@ubuntu.com-20030122150051-uihwkdoxf15mi1tn
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <qdir.h>
 
2
#include <qfile.h>
 
3
#include <qsize.h>
 
4
#include <qsizepolicy.h>
 
5
#include "kxanim.h"
 
6
 
 
7
#include <kapp.h>
 
8
#include <klocale.h>
 
9
 
 
10
#include <unistd.h>
 
11
#include <string.h>
 
12
 
 
13
#include <iostream.h>
 
14
 
 
15
/* some #defines */
 
16
#define KA_ERROR_NONE        0
 
17
#define KA_ERROR_FILENAME    1
 
18
#define KA_ERROR_INFO        2
 
19
#define KA_ERROR_UNSUPPORTED 3
 
20
#define KA_ERROR_ACTIVE      4
 
21
#define KA_ERROR_EXECUTABLE  5
 
22
 
 
23
KXAnim::KXAnim(QWidget *parent, const char *name) : QWidget( parent, name)
 
24
{
 
25
    /* default autoresize */
 
26
    autoResize = true;
 
27
 
 
28
    /* default loop state */
 
29
    loop = true;
 
30
 
 
31
    /* Get the base window ID */
 
32
    window = this->winId();
 
33
 
 
34
    /* Get the X11 display */
 
35
    dpy = this->x11Display();
 
36
    window_atom = XInternAtom(dpy, "XANIM_PROPERTY", 0);
 
37
 
 
38
    /*** connections ***/
 
39
    /* KProcess output */
 
40
    connect(&proc, SIGNAL( receivedStdout(KProcess *, char *, int)),
 
41
            this, SLOT( getOutput( KProcess *, char *, int)) );
 
42
    /* KProcess output */
 
43
    connect(&proc, SIGNAL( receivedStderr(KProcess *, char *, int)),
 
44
            this, SLOT( getOutput( KProcess *, char *, int)) );
 
45
    /* KProcess terminated */
 
46
    connect(&proc, SIGNAL( processExited(KProcess *)),
 
47
            this, SLOT( emitStopped( KProcess *)) );
 
48
    setDefaults();
 
49
    resetXAnimDefaults();
 
50
}
 
51
 
 
52
void KXAnim::resetXAnimDefaults()
 
53
{
 
54
        /* =========== SOUND ============ */
 
55
        audio=true;
 
56
        audioSync=true;
 
57
        audioInitialVolume=40;
 
58
        /* =========== COLOR ============ */
 
59
        colorMapping=none;
 
60
        colorAhead=5;
 
61
        /* =========== GAMMA ============ */
 
62
        gammaDisplay=1.0;
 
63
        /* =========== SCALING ============ */
 
64
        resizing=true;
 
65
 
 
66
        scaleFactor=1.0;
 
67
        scaleHFactor=1.0;
 
68
        scaleVFactor=1.0;
 
69
        scaleWidth=0;
 
70
        scaleHeight=0;
 
71
        scaleToBuffer=false;
 
72
 
 
73
        scaleFactorB=1.0;
 
74
        scaleHFactorB=1.0;
 
75
        scaleVFactorB=1.0;
 
76
        scaleWidthB=0;
 
77
        scaleHeightB=0;
 
78
        scaleToDisplay=false;
 
79
        /* =========== OTHERS ============ */
 
80
        loading=2;
 
81
        //preload=false;
 
82
        x11Shared=false;
 
83
        multiBuffer=true;
 
84
        usePixmap=false;
 
85
        x11VisualClass="default";
 
86
        pauseAt=-1;
 
87
        extras="";
 
88
        executable="xanim";
 
89
}
 
90
 
 
91
void KXAnim::setDefaults()
 
92
{
 
93
    /* we aren't playing anything! */
 
94
    playing = false;
 
95
    /* we don't have a file yet! */
 
96
    fileName = "";
 
97
    /* x-anim is not active */
 
98
    active = false;
 
99
    /* set the default sizes */
 
100
    videoHeight=1;
 
101
    videoWidth=1;
 
102
    /* set the default framerate */
 
103
    videoSpeed=0.0;
 
104
    /* we have no frames! */
 
105
    videoFrames=0;
 
106
    /* empty the outpu buffer */
 
107
    outBuff = "";
 
108
    /* we have no video, so: */
 
109
    videoCodec="";
 
110
    /* no errors */
 
111
    errorCode=KA_ERROR_NONE;
 
112
    errorString="";
 
113
}
 
114
 
 
115
void KXAnim::changeProperty( const char *c )
 
116
{
 
117
    /* send the char(s)... */
 
118
    if (active)
 
119
          XChangeProperty(dpy, window, window_atom, XA_STRING, 8, PropModeReplace, (unsigned char *)c, strlen(c));
 
120
}
 
121
 
 
122
void KXAnim::updateSize()
 
123
{
 
124
   int x,y;
 
125
 
 
126
   x=int(videoWidth * scaleFactor);
 
127
   y=int(videoHeight * scaleFactor);
 
128
   if (scaleHFactor!=1.0)
 
129
      x=int(videoWidth * scaleHFactor);
 
130
   else
 
131
      if (scaleWidth!=0)
 
132
         x=scaleWidth;
 
133
   if (scaleVFactor!=1.0)
 
134
      y=int(videoWidth * scaleVFactor);
 
135
   else
 
136
      if (scaleHeight!=0)
 
137
         y=scaleHeight;
 
138
   resize(x,y);
 
139
 
 
140
//   reinterpret_cast<QWidget *>(parent())->updateGeometry();
 
141
//   if (x!=width() || y!=height()) setFixedSize(x,y);
 
142
}
 
143
 
 
144
void KXAnim::play()
 
145
{
 
146
    QString s;
 
147
 
 
148
    if (!fileName.isEmpty())
 
149
    {
 
150
        if (active == false)
 
151
        /* Activate x-anim */
 
152
        {
 
153
            outBuff="";
 
154
            proc.clearArguments();
 
155
            proc << executable;
 
156
            proc << "-Zr";
 
157
            s.sprintf("+W%d",winId());
 
158
            proc << s;
 
159
            parseParameters();
 
160
            if (autoResize)
 
161
               /* resize the widget properly */
 
162
               updateSize();
 
163
            proc << fileName;
 
164
 
 
165
            proc.start(KProcess::NotifyOnExit,KProcess::Stdout);
 
166
            active = true;
 
167
        }
 
168
        playing = !playing;
 
169
        changeProperty(" ");
 
170
    }
 
171
}
 
172
 
 
173
void KXAnim::pause()
 
174
{
 
175
    if (playing==true)
 
176
    {
 
177
        playing = false;
 
178
        play();
 
179
    }
 
180
}
 
181
 
 
182
void KXAnim::stop()
 
183
{
 
184
    changeProperty("q");
 
185
}
 
186
 
 
187
void KXAnim::stepForward()
 
188
{
 
189
    playing = false;
 
190
    changeProperty(".");
 
191
}
 
192
 
 
193
void KXAnim::stepBack()
 
194
{
 
195
    playing = false;
 
196
    changeProperty(",");
 
197
}
 
198
 
 
199
void KXAnim::stepForwardWA()
 
200
{
 
201
    playing = false;
 
202
    changeProperty("/");
 
203
}
 
204
 
 
205
void KXAnim::stepBackWA()
 
206
{
 
207
    playing = false;
 
208
    changeProperty("m");
 
209
}
 
210
 
 
211
void KXAnim::toggleSound()
 
212
{
 
213
    changeProperty("s");
 
214
}
 
215
 
 
216
void KXAnim::volumeIncrement()
 
217
{
 
218
   changeProperty("3");
 
219
}
 
220
 
 
221
void KXAnim::volumeDecrement()
 
222
{
 
223
   changeProperty("2");
 
224
}
 
225
 
 
226
void KXAnim::setVolume(int v)
 
227
{
 
228
    QCString s;
 
229
 
 
230
    s.sprintf("v%d",v);
 
231
    changeProperty(s);
 
232
}
 
233
 
 
234
void KXAnim::faster()
 
235
{
 
236
    changeProperty("-");
 
237
}
 
238
 
 
239
void KXAnim::slower()
 
240
{
 
241
    changeProperty("=");
 
242
}
 
243
 
 
244
void KXAnim::resetSpeed()
 
245
{
 
246
    changeProperty("0");
 
247
}
 
248
 
 
249
void KXAnim::setFile(QString file)
 
250
{
 
251
    errorCode=KA_ERROR_NONE;
 
252
 
 
253
    if (!file.isEmpty() && QFile::exists(file) && !QDir(file).exists())
 
254
    {
 
255
        if (active == false)
 
256
        /* Activate x-anim */
 
257
        {
 
258
            fileName = file;
 
259
            outBuff="";
 
260
            proc.clearArguments();
 
261
            proc << executable;
 
262
            proc << "+Zv" << "+v" << "+f" << "-Ae";
 
263
            proc << fileName;
 
264
            /* just to get the file information */
 
265
            disconnect(&proc, SIGNAL( processExited(KProcess *)),
 
266
                       this, SLOT( emitStopped( KProcess *)) );
 
267
            connect(&proc, SIGNAL( processExited(KProcess *)),
 
268
                    this, SLOT( checkOutput( KProcess *)) );
 
269
            if (proc.start(KProcess::NotifyOnExit,KProcess::AllOutput)==false)
 
270
            {
 
271
                /* can't finde the xanim executable! */
 
272
                errorCode = KA_ERROR_EXECUTABLE;
 
273
                setErrorString( errorCode, fileName );
 
274
                emit stopped();
 
275
            }
 
276
        }
 
277
        else
 
278
        {
 
279
            errorCode = KA_ERROR_ACTIVE;
 
280
            setErrorString( errorCode, file );
 
281
            emit stopped();
 
282
        }
 
283
    }
 
284
    else
 
285
    {
 
286
       errorCode = KA_ERROR_FILENAME;
 
287
       setErrorString( errorCode, file );
 
288
       emit stopped();
 
289
    }
 
290
}
 
291
 
 
292
void KXAnim::checkOutput( KProcess *)
 
293
{
 
294
/*
 
295
  the xanim has stopped. Check the output and emit the stopped signal
 
296
*/
 
297
    disconnect(&proc, SIGNAL( processExited(KProcess *)),
 
298
               this, SLOT( checkOutput( KProcess *)) );
 
299
    connect(&proc, SIGNAL( processExited(KProcess *)),
 
300
            this, SLOT( emitStopped( KProcess *)) );
 
301
 
 
302
    playing = false;
 
303
    active = false;
 
304
    errorCode=getVideoInfo();
 
305
    if (errorCode==0)
 
306
       if (autoResize)
 
307
          /* resize the widget properly */
 
308
          updateSize();
 
309
    setErrorString( errorCode, fileName );
 
310
    emit stopped();
 
311
}
 
312
 
 
313
int KXAnim::getVideoInfo()
 
314
{
 
315
    int pos, pos2, pos3;
 
316
    QString s;
 
317
 
 
318
    /*** check the output of xanim to see if the executable is valid ***/
 
319
    if ( (pos=outBuff.find("XAnim Rev",0,false)) == -1)
 
320
        return KA_ERROR_EXECUTABLE;
 
321
 
 
322
    /*** check the output of xanim to get the file info ***/
 
323
    if ( (pos=outBuff.find("Video Codec:",0,false)) != -1)
 
324
    {
 
325
        /* check the video codec */
 
326
        if ( (pos2=outBuff.find("unsupported by this executable",pos+12,false)) == -1)
 
327
        {
 
328
            if ( (pos3=outBuff.find("depth=",pos+13,false)) != -1)
 
329
            {
 
330
                videoCodec=outBuff.mid(pos+13,pos3-(pos+13));
 
331
            }
 
332
            else return KA_ERROR_INFO;
 
333
        }
 
334
        else return KA_ERROR_UNSUPPORTED;
 
335
    } else videoCodec="";
 
336
 
 
337
//    if ( (pos=outBuff.find("Frame Stats:",0,false)) != -1)
 
338
//    {
 
339
        /* check the size */
 
340
        pos2=outBuff.find("Size",0,false);
 
341
        if (pos2==-1)
 
342
        {
 
343
            pos2=outBuff.findRev("MPG",-1,false);
 
344
            if (pos2!=-1) pos2--;
 
345
        }
 
346
        if (pos2!=-1)
 
347
        {
 
348
            if ( (pos3=outBuff.find("x",pos2+5,false)) != -1)
 
349
            {
 
350
                s=outBuff.mid(pos2+5,pos3-(pos2+5));
 
351
                videoWidth=s.toInt();
 
352
                if ( (pos2=outBuff.find(" ",pos3,false)) != -1)
 
353
                {
 
354
                    s=outBuff.mid(pos3+1,pos2-(pos3+1));
 
355
                    videoHeight=s.toInt();
 
356
                }
 
357
                else return KA_ERROR_INFO;
 
358
            }
 
359
            else return KA_ERROR_INFO;
 
360
        }
 
361
        else return KA_ERROR_INFO;
 
362
 
 
363
        /* check the number of frames */
 
364
        if ( (pos2=outBuff.find("frames",0,false)) != -1)
 
365
        {
 
366
            if ( (pos3=outBuff.find(" ",pos2+8,false)) != -1)
 
367
            {
 
368
                s=outBuff.mid(pos2+7,pos3-(pos2+7));
 
369
                videoFrames=s.toInt();
 
370
            }
 
371
            else return KA_ERROR_INFO;
 
372
        }
 
373
        else videoFrames=0;
 
374
 
 
375
        /* check the video speed */
 
376
        if ( (pos2=outBuff.find("fps=",0,false)) != -1)
 
377
        {
 
378
            if ( (pos3=outBuff.find("\n",pos2+4,false)) != -1)
 
379
            {
 
380
                s=outBuff.mid(pos2+4,pos3-(pos2+4));
 
381
                videoSpeed=s.toFloat();
 
382
            }
 
383
            else return KA_ERROR_INFO;
 
384
        }
 
385
        else videoSpeed=0;
 
386
//    }
 
387
//    else return KA_ERROR_INFO;
 
388
 
 
389
    /* no errors! */
 
390
    return KA_ERROR_NONE;
 
391
}
 
392
 
 
393
void KXAnim::getOutput( KProcess *, char *text, int len)
 
394
{
 
395
    temp.fill(' ',len+1);
 
396
    temp.replace(0,len,text);
 
397
    temp[len]='\0';
 
398
    outBuff.append(temp);
 
399
}
 
400
 
 
401
void KXAnim::emitStopped( KProcess *)
 
402
{
 
403
/*
 
404
  the xanim has stopped the playing of a video
 
405
  emit the stopped signal
 
406
*/
 
407
    playing = false;
 
408
    active = false;
 
409
    emit stopped();
 
410
}
 
411
 
 
412
void KXAnim::setErrorString( int n, QString file )
 
413
{
 
414
   /* no errors */
 
415
   errorString=QString::null;
 
416
   switch (n)
 
417
   {
 
418
       case KA_ERROR_FILENAME   : errorString=i18n("%1: wrong file name.").arg(file); break;
 
419
       case KA_ERROR_INFO       : errorString=i18n("Error reading file info."); break;
 
420
       case KA_ERROR_UNSUPPORTED: errorString=i18n("Unsupported video codec."); break;
 
421
       case KA_ERROR_ACTIVE     : errorString=i18n("The video is active!"); break;
 
422
       case KA_ERROR_EXECUTABLE : errorString=i18n("Can't find the xanim executable:\n%1").arg(executable); break;
 
423
   }
 
424
}
 
425
 
 
426
void KXAnim::closeEvent( QCloseEvent *e)
 
427
{
 
428
    if (active)
 
429
        stop();
 
430
    while (active);
 
431
    e->accept();
 
432
}
 
433
 
 
434
KXAnim::~KXAnim()
 
435
{
 
436
}
 
437
 
 
438
void KXAnim::parseParameters()
 
439
{
 
440
    QString s;
 
441
    int pos,pos2;
 
442
 
 
443
    if (!loop)
 
444
        proc<<"+Ze";
 
445
 
 
446
    /* =========== SOUND ============ */
 
447
    if (audio==false) proc<<"-Ae";
 
448
    if (audioSync==false) proc<<"-Ak";
 
449
    if (audioInitialVolume!=40)
 
450
    {
 
451
       s.sprintf("+Av%d",audioInitialVolume);
 
452
       proc<<s;
 
453
    }
 
454
    /* =========== COLOR ============ */
 
455
    switch (colorMapping)
 
456
    {
 
457
       case none:        break;
 
458
       case static332:   proc<<"+C3"; break;
 
459
       case lookupTable: proc<<"+CF4"; break;
 
460
       case grayScale:   proc<<"+Cg"; break;
 
461
    }
 
462
    if (colorMapping==lookupTable && colorAhead!=5)
 
463
    {
 
464
       s.sprintf("+Cs%d",colorAhead);
 
465
       proc<<s;
 
466
    }
 
467
 
 
468
    /* =========== GAMMA ============ */
 
469
    if (gammaDisplay!=1.0)
 
470
    {
 
471
        s.sprintf("+Gd%1.5f",gammaDisplay);
 
472
        proc<<s;
 
473
    }
 
474
 
 
475
    /* =========== SCALING ============ */
 
476
    if (resizing==true) proc<<"+Sr";
 
477
 
 
478
    if (!autoResize)
 
479
    {
 
480
        s.sprintf("+Sx%d", width());
 
481
        proc << s;
 
482
        s.sprintf("+Sy%d", height());
 
483
        proc << s;
 
484
    }
 
485
    else
 
486
    {
 
487
        if (scaleFactor != 1.0)
 
488
        {
 
489
            s.sprintf("+Ss%2.5f",scaleFactor);
 
490
            proc<<s;
 
491
        }
 
492
        else
 
493
        {
 
494
            if (scaleHFactor != 1.0)
 
495
            {
 
496
               s.sprintf("+Sh%10.8f",scaleHFactor);
 
497
               proc<<s;
 
498
            }
 
499
            if (scaleVFactor != 1.0)
 
500
            {
 
501
               s.sprintf("+Sv%10.8f",scaleVFactor);
 
502
               proc<<s;
 
503
            }
 
504
        }
 
505
        if (scaleWidth!=0)
 
506
        {
 
507
            s.sprintf("+Sx%d",scaleWidth);
 
508
            proc<<s;
 
509
        }
 
510
        if (scaleHeight!=0)
 
511
        {
 
512
            s.sprintf("+Sy%d",scaleHeight);
 
513
            proc<<s;
 
514
        }
 
515
        if (scaleToBuffer==true) proc<<"+Sc";
 
516
    }
 
517
 
 
518
    if (scaleFactorB != 1.0)
 
519
    {
 
520
        s.sprintf("+SS%10.8f",scaleFactorB);
 
521
        proc<<s;
 
522
    }
 
523
    else
 
524
    {
 
525
        if (scaleHFactorB != 1.0)
 
526
        {
 
527
           s.sprintf("+SH%10.8f",scaleHFactorB);
 
528
           proc<<s;
 
529
        }
 
530
        if (scaleVFactorB != 1.0)
 
531
        {
 
532
           s.sprintf("+SV%10.8f",scaleVFactorB);
 
533
           proc<<s;
 
534
        }
 
535
    }
 
536
    if (scaleWidthB!=0)
 
537
    {
 
538
        s.sprintf("+SX%d",scaleWidthB);
 
539
        proc<<s;
 
540
    }
 
541
    if (scaleHeightB!=0)
 
542
    {
 
543
        s.sprintf("+SY%d",scaleHeightB);
 
544
        proc<<s;
 
545
    }
 
546
    if (scaleToDisplay==true) proc<<"+SC";
 
547
 
 
548
    /* =========== OTHERS ============ */
 
549
    switch (loading)
 
550
    {
 
551
       case 0: break;
 
552
       case 1: proc<<"+b"; break;
 
553
       case 2: proc<<"+f"; break;
 
554
    }
 
555
    if (x11Shared==true && loading!=1) proc<<"+B";
 
556
    if (multiBuffer==false) proc<<"-D";
 
557
    if (usePixmap==true) proc<<"+p";
 
558
    if (x11VisualClass.contains("default",false)==0)
 
559
    {
 
560
       s="+V";
 
561
       s+=x11VisualClass;
 
562
       proc<<s;
 
563
    }
 
564
    if (pauseAt!=-1)
 
565
    {
 
566
        s.sprintf("+Zp%d",pauseAt);
 
567
        proc<<s;
 
568
    }
 
569
    extras.simplifyWhiteSpace();
 
570
    if (!extras.isEmpty())
 
571
    {
 
572
       pos=-1;
 
573
       do
 
574
       {
 
575
          pos2=extras.find(' ',pos+1);
 
576
          if (pos2!=-1)
 
577
             s=extras.mid(pos+1,pos2-(pos+1));
 
578
          else
 
579
             s=extras.mid(pos+1,extras.length()-(pos+1));
 
580
          proc<<s;
 
581
          pos=pos2;
 
582
       } while (pos2!=-1);       
 
583
    }
 
584
}
 
585
 
 
586
void KXAnim::mousePressEvent( QMouseEvent *mouse)
 
587
{
 
588
   emit mouseClick(mouse);
 
589
}
 
590
 
 
591
QSize KXAnim::sizeHint() const
 
592
{
 
593
  int x,y;
 
594
 
 
595
  x=int(videoWidth * scaleFactor);
 
596
  y=int(videoHeight * scaleFactor);
 
597
  if (scaleHFactor!=1.0)
 
598
    x=int(videoWidth * scaleHFactor);
 
599
  else
 
600
    if (scaleWidth!=0)
 
601
      x=scaleWidth;
 
602
 
 
603
  if (scaleVFactor!=1.0)
 
604
    y=int(videoWidth * scaleVFactor);
 
605
  else
 
606
    if (scaleHeight!=0)
 
607
      y=scaleHeight;
 
608
 
 
609
  return QSize(x,y);
 
610
}
 
611
 
 
612
QSize KXAnim::minimumSizeHint() const
 
613
{
 
614
  return QSize(16,16);
 
615
}
 
616
 
 
617
QSizePolicy KXAnim::sizePolicy() const
 
618
{
 
619
  return QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
 
620
}
 
621
 
 
622
 
 
623
#include "kxanim.moc"