mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-25 09:21:53 +00:00
370 lines
6.6 KiB
Objective-C
370 lines
6.6 KiB
Objective-C
/** <title>NSMovie</title>
|
|
|
|
<abstract>Encapsulate a Quicktime movie</abstract>
|
|
|
|
Copyright <copy>(C) 2003 Free Software Foundation, Inc.</copy>
|
|
|
|
Author: Fred Kiefer <FredKiefer@gmx.de>
|
|
Date: March 2003
|
|
|
|
This file is part of the GNUstep GUI Library.
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; see the file COPYING.LIB.
|
|
If not, see <http://www.gnu.org/licenses/> or write to the
|
|
Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#import <Foundation/NSArray.h>
|
|
#import <Foundation/NSData.h>
|
|
#import <Foundation/NSLock.h>
|
|
#import <Foundation/NSURL.h>
|
|
|
|
#import "AppKit/NSMovie.h"
|
|
#import "AppKit/NSMovieView.h"
|
|
#import "AppKit/NSPasteboard.h"
|
|
|
|
enum
|
|
{
|
|
MOVIE_SHOULD_PLAY = 1,
|
|
MOVIE_SHOULD_PAUSE
|
|
};
|
|
|
|
#define BUFFER_SIZE 4096
|
|
|
|
@interface NSMovie (NSMovieViewPrivate)
|
|
- (id<GSVideoSource>) _source;
|
|
- (id<GSVideoSink>) _sink;
|
|
@end
|
|
|
|
@implementation NSMovie (NSMovieViewPrivate)
|
|
- (id< GSVideoSource >) _source
|
|
{
|
|
return _source;
|
|
}
|
|
|
|
- (id< GSVideoSink >) _sink
|
|
{
|
|
return _sink;
|
|
}
|
|
@end
|
|
|
|
@interface NSMovieView (PrivateMethods)
|
|
- (void) _stream;
|
|
- (void) _finished: (NSNumber *)finishedPlaying;
|
|
@end
|
|
|
|
@implementation NSMovieView (PrivateMethods)
|
|
- (void) _stream
|
|
{
|
|
NSUInteger bytesRead;
|
|
BOOL success = NO;
|
|
void *buffer;
|
|
id <GSVideoSink> sink = [[self movie] _sink];
|
|
id <GSVideoSource> source = [[self movie] _source];
|
|
|
|
// Exit with success = NO if device could not be open.
|
|
if ([sink open])
|
|
{
|
|
// Allocate space for buffer and start writing.
|
|
buffer = NSZoneMalloc(NSDefaultMallocZone(), BUFFER_SIZE);
|
|
do
|
|
{
|
|
do
|
|
{
|
|
// If not MOVIE_SHOULD_PLAY block thread
|
|
[_readLock lockWhenCondition: MOVIE_SHOULD_PLAY];
|
|
if (_shouldStop)
|
|
{
|
|
[_readLock unlock];
|
|
break;
|
|
}
|
|
bytesRead = [source readBytes: buffer
|
|
length: BUFFER_SIZE];
|
|
[_readLock unlock];
|
|
[_playbackLock lock];
|
|
success = [sink playBytes: buffer length: bytesRead];
|
|
[_playbackLock unlock];
|
|
} while ((!_shouldStop) && (bytesRead > 0) && success);
|
|
|
|
[source setCurrentTime: 0.0];
|
|
} while (_shouldLoop == YES && _shouldStop == NO);
|
|
|
|
[sink close];
|
|
NSZoneFree (NSDefaultMallocZone(), buffer);
|
|
}
|
|
|
|
RETAIN(self);
|
|
[self performSelectorOnMainThread: @selector(_finished:)
|
|
withObject: [NSNumber numberWithBool: success]
|
|
waitUntilDone: YES];
|
|
RELEASE(self);
|
|
}
|
|
|
|
- (void) _finished: (NSNumber *)finishedPlaying
|
|
{
|
|
DESTROY(_readLock);
|
|
DESTROY(_playbackLock);
|
|
}
|
|
@end
|
|
|
|
@implementation NSMovieView
|
|
|
|
- (instancetype) init
|
|
{
|
|
self = [super init];
|
|
if (self != nil)
|
|
{
|
|
_movie = nil;
|
|
_rate = 1.0;
|
|
_volume = 1.0;
|
|
|
|
_flags.muted = NO;
|
|
_flags.loopMode = NSQTMovieNormalPlayback;
|
|
_flags.plays_selection_only = NO;
|
|
_flags.plays_every_frame = YES;
|
|
_flags.is_controller_visible = NO;
|
|
_flags.editable = NO;
|
|
_flags.reserved = 0;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void) setMovie: (NSMovie *)movie
|
|
{
|
|
ASSIGN(_movie, movie);
|
|
|
|
if (_movie != nil)
|
|
{
|
|
[[movie _sink] setMovieView: self];
|
|
}
|
|
}
|
|
|
|
- (NSMovie*) movie
|
|
{
|
|
return _movie;
|
|
}
|
|
|
|
- (void) start: (id)sender
|
|
{
|
|
// If the locks exists this instance is already playing
|
|
if (_readLock != nil && _playbackLock != nil)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_readLock = [[NSConditionLock alloc] initWithCondition: MOVIE_SHOULD_PAUSE];
|
|
_playbackLock = [[NSLock alloc] init];
|
|
|
|
if ([_readLock tryLock] != YES)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_shouldStop = NO;
|
|
[NSThread detachNewThreadSelector: @selector(_stream)
|
|
toTarget: self
|
|
withObject: nil];
|
|
|
|
[_readLock unlockWithCondition: MOVIE_SHOULD_PLAY];
|
|
}
|
|
|
|
- (void) stop: (id)sender
|
|
{
|
|
if (_readLock == nil)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ([_readLock tryLock] != YES)
|
|
{
|
|
return;
|
|
}
|
|
_shouldStop = YES;
|
|
|
|
// Set to MOVIE_SHOULD_PLAY so that thread isn't blocked.
|
|
[_readLock unlockWithCondition: MOVIE_SHOULD_PLAY];
|
|
}
|
|
|
|
- (BOOL) isPlaying
|
|
{
|
|
if (_readLock == nil)
|
|
{
|
|
return NO;
|
|
}
|
|
if ([_readLock condition] == MOVIE_SHOULD_PLAY)
|
|
{
|
|
return YES;
|
|
}
|
|
return NO;
|
|
}
|
|
|
|
- (void) gotoPosterFrame: (id)sender;
|
|
{
|
|
//FIXME
|
|
}
|
|
|
|
- (void) gotoBeginning: (id)sender;
|
|
{
|
|
//FIXME
|
|
}
|
|
|
|
- (void) gotoEnd: (id)sender;
|
|
{
|
|
//FIXME
|
|
}
|
|
|
|
- (void) stepForward: (id)sender;
|
|
{
|
|
//FIXME
|
|
}
|
|
|
|
- (void) stepBack: (id)sender;
|
|
{
|
|
//FIXME
|
|
}
|
|
|
|
- (void) setRate: (float)rate;
|
|
{
|
|
_rate = rate;
|
|
}
|
|
|
|
- (float) rate
|
|
{
|
|
return _rate;
|
|
}
|
|
|
|
- (void) setVolume: (float)volume
|
|
{
|
|
_volume = volume;
|
|
}
|
|
|
|
- (float) volume
|
|
{
|
|
return _volume;
|
|
}
|
|
|
|
- (void) setMuted: (BOOL)mute
|
|
{
|
|
_flags.muted = mute;
|
|
}
|
|
|
|
- (BOOL) isMuted
|
|
{
|
|
return _flags.muted;
|
|
}
|
|
|
|
- (void) setLoopMode: (NSQTMovieLoopMode)mode
|
|
{
|
|
_flags.loopMode = mode;
|
|
}
|
|
|
|
- (NSQTMovieLoopMode) loopMode
|
|
{
|
|
return _flags.loopMode;
|
|
}
|
|
|
|
- (void) setPlaysSelectionOnly: (BOOL)flag
|
|
{
|
|
_flags.plays_selection_only = flag;
|
|
}
|
|
|
|
- (BOOL) playsSelectionOnly
|
|
{
|
|
return _flags.plays_selection_only;
|
|
}
|
|
|
|
- (void) setPlaysEveryFrame: (BOOL)flag
|
|
{
|
|
_flags.plays_every_frame = flag;
|
|
}
|
|
|
|
- (BOOL) playsEveryFrame
|
|
{
|
|
return _flags.plays_every_frame;
|
|
}
|
|
|
|
- (void) showController: (BOOL)show adjustingSize: (BOOL)adjustSize
|
|
{
|
|
//FIXME
|
|
_flags.is_controller_visible = show;
|
|
}
|
|
|
|
- (void*) movieController
|
|
{
|
|
//FIXME
|
|
return NULL;
|
|
}
|
|
|
|
- (BOOL) isControllerVisible
|
|
{
|
|
return _flags.is_controller_visible;
|
|
}
|
|
|
|
- (NSRect) movieRect
|
|
{
|
|
return [self bounds];
|
|
}
|
|
|
|
- (void) resizeWithMagnification: (float)magnification;
|
|
{
|
|
//FIXME
|
|
}
|
|
- (NSSize) sizeForMagnification: (float)magnification;
|
|
{
|
|
//FIXME
|
|
return NSMakeSize(0, 0);
|
|
}
|
|
|
|
- (void) setEditable: (BOOL)editable;
|
|
{
|
|
_flags.editable = editable;
|
|
}
|
|
|
|
- (BOOL) isEditable
|
|
{
|
|
return _flags.editable;
|
|
}
|
|
|
|
- (void) cut: (id)sender
|
|
{
|
|
//FIXME
|
|
}
|
|
|
|
- (void) copy: (id)sender
|
|
{
|
|
//FIXME
|
|
}
|
|
|
|
- (void) paste: (id)sender
|
|
{
|
|
//FIXME
|
|
}
|
|
|
|
- (void) clear: (id)sender
|
|
{
|
|
//FIXME
|
|
}
|
|
|
|
- (void) undo: (id)sender
|
|
{
|
|
//FIXME
|
|
}
|
|
|
|
- (void) selectAll: (id)sender
|
|
{
|
|
//FIXME
|
|
}
|
|
|
|
@end
|