瀏覽代碼

manager: load/save screenshot

osy 5 年之前
父節點
當前提交
ee97b8a8a1

+ 1 - 1
CocoaSpice/CSDisplayMetal.m

@@ -234,7 +234,7 @@ static void cs_channel_destroy(SpiceSession *s, SpiceChannel *channel, gpointer
     dispatch_semaphore_wait(_drawLock, DISPATCH_TIME_FOREVER); // TODO: separate read lock so we don't block texture copy
     dispatch_semaphore_wait(_drawLock, DISPATCH_TIME_FOREVER); // TODO: separate read lock so we don't block texture copy
     if (_canvasData) { // may be destroyed at this point
     if (_canvasData) { // may be destroyed at this point
         CGDataProviderRef dataProviderRef = CGDataProviderCreateWithData(NULL, _canvasData, _canvasStride * _canvasArea.size.height, nil);
         CGDataProviderRef dataProviderRef = CGDataProviderCreateWithData(NULL, _canvasData, _canvasStride * _canvasArea.size.height, nil);
-        img = CGImageCreate(_canvasArea.size.width, _canvasArea.size.height, 8, 32, _canvasStride, colorSpaceRef, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst, dataProviderRef, NULL, NO, kCGRenderingIntentDefault);
+        img = CGImageCreate(_canvasArea.size.width, _canvasArea.size.height, 8, 32, _canvasStride, colorSpaceRef, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst, dataProviderRef, NULL, NO, kCGRenderingIntentDefault);
         CGDataProviderRelease(dataProviderRef);
         CGDataProviderRelease(dataProviderRef);
     } else {
     } else {
         img = NULL;
         img = NULL;

+ 1 - 0
Managers/UTMVirtualMachine.h

@@ -37,6 +37,7 @@ NS_ASSUME_NONNULL_BEGIN
 @property (nonatomic, assign, readonly) UTMVMState state;
 @property (nonatomic, assign, readonly) UTMVMState state;
 @property (nonatomic, readonly, nullable) UTMQemuManager *qemu;
 @property (nonatomic, readonly, nullable) UTMQemuManager *qemu;
 @property (nonatomic, readonly) BOOL busy;
 @property (nonatomic, readonly) BOOL busy;
+@property (nonatomic, readonly) UIImage *screenshot;
 
 
 + (BOOL)URLisVirtualMachine:(NSURL *)url;
 + (BOOL)URLisVirtualMachine:(NSURL *)url;
 + (NSString *)virtualMachineName:(NSURL *)url;
 + (NSString *)virtualMachineName:(NSURL *)url;

+ 26 - 1
Managers/UTMVirtualMachine.m

@@ -30,6 +30,7 @@ NSString *const kUTMErrorDomain = @"com.osy86.utm";
 NSString *const kUTMBundleConfigFilename = @"config.plist";
 NSString *const kUTMBundleConfigFilename = @"config.plist";
 NSString *const kUTMBundleExtension = @"utm";
 NSString *const kUTMBundleExtension = @"utm";
 NSString *const kUTMBundleViewFilename = @"view.plist";
 NSString *const kUTMBundleViewFilename = @"view.plist";
+NSString *const kUTMBundleScreenshotFilename = @"screenshot.png";
 NSString *const kSuspendSnapshotName = @"suspend";
 NSString *const kSuspendSnapshotName = @"suspend";
 
 
 @interface UTMVirtualMachine ()
 @interface UTMVirtualMachine ()
@@ -48,6 +49,7 @@ NSString *const kSuspendSnapshotName = @"suspend";
     dispatch_semaphore_t _will_quit_sema;
     dispatch_semaphore_t _will_quit_sema;
     dispatch_semaphore_t _qemu_exit_sema;
     dispatch_semaphore_t _qemu_exit_sema;
     BOOL _is_busy;
     BOOL _is_busy;
+    UIImage *_screenshot;
 }
 }
 
 
 @synthesize busy = _is_busy;
 @synthesize busy = _is_busy;
@@ -94,6 +96,7 @@ NSString *const kSuspendSnapshotName = @"suspend";
         }
         }
         _configuration = [[UTMConfiguration alloc] initWithDictionary:plist name:name path:url];
         _configuration = [[UTMConfiguration alloc] initWithDictionary:plist name:name path:url];
         [self loadViewState:url];
         [self loadViewState:url];
+        [self loadScreenshot];
     }
     }
     return self;
     return self;
 }
 }
@@ -199,7 +202,6 @@ NSString *const kSuspendSnapshotName = @"suspend";
     }
     }
     _spice_connection.glibMainContext = _spice.glibMainContext;
     _spice_connection.glibMainContext = _spice.glibMainContext;
     self.delegate.vmMessage = nil;
     self.delegate.vmMessage = nil;
-    self.delegate.vmScreenshot = nil;
     self.delegate.vmDisplay = nil;
     self.delegate.vmDisplay = nil;
     self.delegate.vmInput = nil;
     self.delegate.vmInput = nil;
     _primaryDisplay = nil;
     _primaryDisplay = nil;
@@ -285,6 +287,7 @@ NSString *const kSuspendSnapshotName = @"suspend";
     }
     }
     [self syncViewState];
     [self syncViewState];
     [self changeState:kVMPausing];
     [self changeState:kVMPausing];
+    [self saveScreenshot];
     __block BOOL success = YES;
     __block BOOL success = YES;
     dispatch_semaphore_t suspend_sema = dispatch_semaphore_create(0);
     dispatch_semaphore_t suspend_sema = dispatch_semaphore_create(0);
     [_qemu vmStopWithCompletion:^(NSError * err) {
     [_qemu vmStopWithCompletion:^(NSError * err) {
@@ -490,4 +493,26 @@ NSString *const kSuspendSnapshotName = @"suspend";
           withError:nil];
           withError:nil];
 }
 }
 
 
+#pragma mark - Screenshot
+
+@synthesize screenshot = _screenshot;
+
+- (void)loadScreenshot {
+    NSURL *url = [[self packageURLForName:self.configuration.name] URLByAppendingPathComponent:kUTMBundleScreenshotFilename];
+    _screenshot = [UIImage imageWithContentsOfFile:url.path];
+}
+
+- (void)saveScreenshot {
+    _screenshot = self.primaryDisplay.screenshot;
+    NSURL *url = [[self packageURLForName:self.configuration.name] URLByAppendingPathComponent:kUTMBundleScreenshotFilename];
+    if (_screenshot) {
+        [UIImagePNGRepresentation(_screenshot) writeToURL:url atomically:NO];
+    }
+}
+
+- (void)deleteScreenshot {
+    NSURL *url = [[self packageURLForName:self.configuration.name] URLByAppendingPathComponent:kUTMBundleScreenshotFilename];
+    [[NSFileManager defaultManager] removeItemAtURL:url error:nil];
+}
+
 @end
 @end

+ 0 - 1
Managers/UTMVirtualMachineDelegate.h

@@ -38,7 +38,6 @@ typedef NS_ENUM(NSUInteger, UTMVMState) {
 
 
 @protocol UTMVirtualMachineDelegate <NSObject>
 @protocol UTMVirtualMachineDelegate <NSObject>
 
 
-@property (nonatomic, nullable, strong) UIImage *vmScreenshot;
 @property (nonatomic, nullable, copy) NSString *vmMessage;
 @property (nonatomic, nullable, copy) NSString *vmMessage;
 @property (nonatomic, weak) CSDisplayMetal *vmDisplay;
 @property (nonatomic, weak) CSDisplayMetal *vmDisplay;
 @property (nonatomic, weak) CSInput *vmInput;
 @property (nonatomic, weak) CSInput *vmInput;

+ 0 - 1
Views/VMDisplayMetalViewController.m

@@ -64,7 +64,6 @@
     BOOL _isRunning;
     BOOL _isRunning;
 }
 }
 
 
-@synthesize vmScreenshot;
 @synthesize vmMessage;
 @synthesize vmMessage;
 @synthesize vmDisplay;
 @synthesize vmDisplay;
 @synthesize vmInput;
 @synthesize vmInput;

+ 1 - 2
Views/VMListViewController.m

@@ -42,7 +42,6 @@
 @implementation VMListViewController
 @implementation VMListViewController
 
 
 @synthesize vmMessage;
 @synthesize vmMessage;
-@synthesize vmScreenshot;
 @synthesize vmDisplay;
 @synthesize vmDisplay;
 @synthesize vmInput;
 @synthesize vmInput;
 @synthesize vmConfiguration;
 @synthesize vmConfiguration;
@@ -307,7 +306,7 @@
 
 
 - (void)virtualMachine:(UTMVirtualMachine *)vm transitionToState:(UTMVMState)state {
 - (void)virtualMachine:(UTMVirtualMachine *)vm transitionToState:(UTMVMState)state {
     dispatch_async(dispatch_get_main_queue(), ^{
     dispatch_async(dispatch_get_main_queue(), ^{
-        [self.activeCell changeState:state image:self.vmScreenshot];
+        [self.activeCell changeState:state image:vm.screenshot];
         switch (state) {
         switch (state) {
             case kVMError: {
             case kVMError: {
                 NSString *msg = self.vmMessage ? self.vmMessage : NSLocalizedString(@"An internal error has occured.", @"Alert message");
                 NSString *msg = self.vmMessage ? self.vmMessage : NSLocalizedString(@"An internal error has occured.", @"Alert message");