9 changed files with 209 additions and 55 deletions
@ -0,0 +1,31 @@ |
|||
using System; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using System.Collections.Generic; |
|||
using System.Collections.ObjectModel; |
|||
using Avalonia.Controls.Platform; |
|||
using System.Reactive.Disposables; |
|||
using System.Reactive.Linq; |
|||
using System.Text.RegularExpressions; |
|||
using System.Runtime.InteropServices; |
|||
using System.Text; |
|||
|
|||
namespace Avalonia.FreeDesktop |
|||
{ |
|||
internal static class NativeMethods |
|||
{ |
|||
[DllImport("libc", SetLastError = true)] |
|||
private static extern long readlink([MarshalAs(UnmanagedType.LPArray)] byte[] filename, |
|||
[MarshalAs(UnmanagedType.LPArray)] byte[] buffer, |
|||
long len); |
|||
|
|||
public static string ReadLink(string path) |
|||
{ |
|||
var symlink = Encoding.UTF8.GetBytes(path); |
|||
var result = new byte[4095]; |
|||
readlink(symlink, result, result.Length); |
|||
var rawstr = Encoding.UTF8.GetString(result); |
|||
return rawstr.Substring(0, rawstr.IndexOf('\0')); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,78 @@ |
|||
using System; |
|||
using System.Collections.ObjectModel; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using System.Reactive.Disposables; |
|||
using System.Reactive.Linq; |
|||
using Avalonia.Controls.Platform; |
|||
|
|||
namespace Avalonia.Native |
|||
{ |
|||
internal class WindowsMountedVolumeInfoListener : IDisposable |
|||
{ |
|||
private readonly CompositeDisposable _disposables; |
|||
private readonly ObservableCollection<MountedVolumeInfo> _targetObs; |
|||
private bool _beenDisposed = false; |
|||
private ObservableCollection<MountedVolumeInfo> mountedDrives; |
|||
|
|||
public WindowsMountedVolumeInfoListener(ObservableCollection<MountedVolumeInfo> mountedDrives) |
|||
{ |
|||
this.mountedDrives = mountedDrives; |
|||
_disposables = new CompositeDisposable(); |
|||
|
|||
var pollTimer = Observable.Interval(TimeSpan.FromSeconds(1)) |
|||
.Subscribe(Poll); |
|||
|
|||
_disposables.Add(pollTimer); |
|||
|
|||
Poll(0); |
|||
} |
|||
|
|||
private void Poll(long _) |
|||
{ |
|||
var mountVolInfos = Directory.GetDirectories("/Volumes") |
|||
.Select(p => new MountedVolumeInfo() |
|||
{ |
|||
VolumeLabel = Path.GetFileName(p), |
|||
VolumePath = p, |
|||
VolumeSizeBytes = 0 |
|||
}) |
|||
.ToArray(); |
|||
|
|||
if (_targetObs.SequenceEqual(mountVolInfos)) |
|||
return; |
|||
else |
|||
{ |
|||
_targetObs.Clear(); |
|||
|
|||
foreach (var i in mountVolInfos) |
|||
_targetObs.Add(i); |
|||
} |
|||
} |
|||
|
|||
protected virtual void Dispose(bool disposing) |
|||
{ |
|||
if (!_beenDisposed) |
|||
{ |
|||
if (disposing) |
|||
{ |
|||
|
|||
} |
|||
_beenDisposed = true; |
|||
} |
|||
} |
|||
public void Dispose() |
|||
{ |
|||
Dispose(true); |
|||
} |
|||
} |
|||
|
|||
public class MacOSMountedVolumeInfoProvider : IMountedVolumeInfoProvider |
|||
{ |
|||
public IDisposable Listen(ObservableCollection<MountedVolumeInfo> mountedDrives) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(mountedDrives != null); |
|||
return new WindowsMountedVolumeInfoListener(mountedDrives); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,71 @@ |
|||
using System; |
|||
using System.Collections.ObjectModel; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using System.Reactive.Disposables; |
|||
using System.Reactive.Linq; |
|||
using Avalonia.Controls.Platform; |
|||
|
|||
namespace Avalonia.Win32 |
|||
{ |
|||
internal class WindowsMountedVolumeInfoListener : IDisposable |
|||
{ |
|||
private readonly CompositeDisposable _disposables; |
|||
private readonly ObservableCollection<MountedVolumeInfo> _targetObs; |
|||
private bool _beenDisposed = false; |
|||
private ObservableCollection<MountedVolumeInfo> mountedDrives; |
|||
|
|||
public WindowsMountedVolumeInfoListener(ObservableCollection<MountedVolumeInfo> mountedDrives) |
|||
{ |
|||
this.mountedDrives = mountedDrives; |
|||
_disposables = new CompositeDisposable(); |
|||
|
|||
var pollTimer = Observable.Interval(TimeSpan.FromSeconds(1)) |
|||
.Subscribe(Poll); |
|||
|
|||
_disposables.Add(pollTimer); |
|||
|
|||
Poll(0); |
|||
} |
|||
|
|||
private void Poll(long _) |
|||
{ |
|||
var allDrives = DriveInfo.GetDrives(); |
|||
|
|||
var mountVolInfos = allDrives |
|||
.Select(p => new MountedVolumeInfo() |
|||
{ |
|||
VolumeLabel = p.VolumeLabel, |
|||
VolumePath = p.RootDirectory.FullName, |
|||
VolumeSizeBytes = (ulong)p.TotalSize |
|||
}) |
|||
.ToArray(); |
|||
|
|||
if (_targetObs.SequenceEqual(mountVolInfos)) |
|||
return; |
|||
else |
|||
{ |
|||
_targetObs.Clear(); |
|||
|
|||
foreach (var i in mountVolInfos) |
|||
_targetObs.Add(i); |
|||
} |
|||
} |
|||
|
|||
protected virtual void Dispose(bool disposing) |
|||
{ |
|||
if (!_beenDisposed) |
|||
{ |
|||
if (disposing) |
|||
{ |
|||
|
|||
} |
|||
_beenDisposed = true; |
|||
} |
|||
} |
|||
public void Dispose() |
|||
{ |
|||
Dispose(true); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using System; |
|||
using System.Collections.ObjectModel; |
|||
using Avalonia.Controls.Platform; |
|||
|
|||
namespace Avalonia.Win32 |
|||
{ |
|||
public class WindowsMountedVolumeInfoProvider : IMountedVolumeInfoProvider |
|||
{ |
|||
public IDisposable Listen(ObservableCollection<MountedVolumeInfo> mountedDrives) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(mountedDrives != null); |
|||
return new WindowsMountedVolumeInfoListener(mountedDrives); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue