20 changed files with 130 additions and 4066 deletions
@ -1,173 +0,0 @@ |
|||||
using System; |
|
||||
using System.Threading.Tasks; |
|
||||
using Tmds.DBus.Protocol; |
|
||||
|
|
||||
namespace Avalonia.FreeDesktop |
|
||||
{ |
|
||||
internal class Registrar : AppMenuRegistrarObject |
|
||||
{ |
|
||||
private const string Interface = "com.canonical.AppMenu.Registrar"; |
|
||||
|
|
||||
public Registrar(RegistrarService service, ObjectPath path) : base(service, path) { } |
|
||||
|
|
||||
public Task RegisterWindowAsync(uint windowId, ObjectPath menuObjectPath) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "uo", |
|
||||
member: "RegisterWindow", |
|
||||
flags: MessageFlags.NoReplyExpected); |
|
||||
writer.WriteUInt32(windowId); |
|
||||
writer.WriteObjectPath(menuObjectPath); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task UnregisterWindowAsync(uint windowId) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "u", |
|
||||
member: "UnregisterWindow"); |
|
||||
writer.WriteUInt32(windowId); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<(string Service, ObjectPath MenuObjectPath)> GetMenuForWindowAsync(uint windowId) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_so(m, (AppMenuRegistrarObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "u", |
|
||||
member: "GetMenuForWindow"); |
|
||||
writer.WriteUInt32(windowId); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
internal class RegistrarService |
|
||||
{ |
|
||||
public RegistrarService(Connection connection, string destination) |
|
||||
=> (Connection, Destination) = (connection, destination); |
|
||||
|
|
||||
public Connection Connection { get; } |
|
||||
public string Destination { get; } |
|
||||
public Registrar CreateRegistrar(string path) => new(this, path); |
|
||||
} |
|
||||
|
|
||||
internal class AppMenuRegistrarObject |
|
||||
{ |
|
||||
protected AppMenuRegistrarObject(RegistrarService service, ObjectPath path) |
|
||||
=> (Service, Path) = (service, path); |
|
||||
|
|
||||
protected RegistrarService Service { get; } |
|
||||
protected ObjectPath Path { get; } |
|
||||
protected Connection Connection => Service.Connection; |
|
||||
|
|
||||
protected MessageBuffer CreateGetPropertyMessage(string @interface, string property) |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "ss", |
|
||||
member: "Get"); |
|
||||
writer.WriteString(@interface); |
|
||||
writer.WriteString(property); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
|
|
||||
protected MessageBuffer CreateGetAllPropertiesMessage(string @interface) |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "s", |
|
||||
member: "GetAll"); |
|
||||
writer.WriteString(@interface); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
|
|
||||
protected ValueTask<IDisposable> WatchPropertiesChangedAsync<TProperties>(string @interface, |
|
||||
MessageValueReader<PropertyChanges<TProperties>> reader, Action<Exception?, PropertyChanges<TProperties>> handler, |
|
||||
bool emitOnCapturedContext) |
|
||||
{ |
|
||||
var rule = new MatchRule |
|
||||
{ |
|
||||
Type = MessageType.Signal, |
|
||||
Sender = Service.Destination, |
|
||||
Path = Path, |
|
||||
Interface = "org.freedesktop.DBus.Properties", |
|
||||
Member = "PropertiesChanged", |
|
||||
Arg0 = @interface |
|
||||
}; |
|
||||
return Connection.AddMatchAsync(rule, reader, static (ex, changes, _, hs) |
|
||||
=> ((Action<Exception?, PropertyChanges<TProperties>>)hs!).Invoke(ex, changes), |
|
||||
this, handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchSignalAsync<TArg>(string sender, string @interface, ObjectPath path, string signal, |
|
||||
MessageValueReader<TArg> reader, Action<Exception?, TArg> handler, bool emitOnCapturedContext) |
|
||||
{ |
|
||||
var rule = new MatchRule |
|
||||
{ |
|
||||
Type = MessageType.Signal, |
|
||||
Sender = sender, |
|
||||
Path = path, |
|
||||
Member = signal, |
|
||||
Interface = @interface |
|
||||
}; |
|
||||
return Connection.AddMatchAsync(rule, reader, static (ex, arg, _, hs) => |
|
||||
((Action<Exception?, TArg>)hs!).Invoke(ex, arg), this, handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchSignalAsync(string sender, string @interface, ObjectPath path, string signal, Action<Exception?> handler, |
|
||||
bool emitOnCapturedContext) |
|
||||
{ |
|
||||
var rule = new MatchRule |
|
||||
{ |
|
||||
Type = MessageType.Signal, |
|
||||
Sender = sender, |
|
||||
Path = path, |
|
||||
Member = signal, |
|
||||
Interface = @interface |
|
||||
}; |
|
||||
return Connection.AddMatchAsync<object>(rule, static (_, _) |
|
||||
=> null!, static (ex, _, _, hs) |
|
||||
=> ((Action<Exception?>)hs!).Invoke(ex), this, handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
protected static (string, ObjectPath) ReadMessage_so(Message message, AppMenuRegistrarObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
var arg0 = reader.ReadString(); |
|
||||
var arg1 = reader.ReadObjectPath(); |
|
||||
return (arg0, arg1); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,641 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Threading.Tasks; |
|
||||
using Tmds.DBus.Protocol; |
|
||||
|
|
||||
namespace Avalonia.FreeDesktop |
|
||||
{ |
|
||||
internal record DBusProperties |
|
||||
{ |
|
||||
public string[] Features { get; set; } = default!; |
|
||||
public string[] Interfaces { get; set; } = default!; |
|
||||
} |
|
||||
|
|
||||
internal class DBus : DBusObject |
|
||||
{ |
|
||||
private const string Interface = "org.freedesktop.DBus"; |
|
||||
|
|
||||
public DBus(DBusService service, ObjectPath path) : base(service, path) { } |
|
||||
|
|
||||
public Task<string> HelloAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_s(m, (DBusObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
"Hello"); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<uint> RequestNameAsync(string a0, uint a1) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_u(m, (DBusObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "su", |
|
||||
member: "RequestName"); |
|
||||
writer.WriteString(a0); |
|
||||
writer.WriteUInt32(a1); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<uint> ReleaseNameAsync(string a0) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_u(m, (DBusObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "s", |
|
||||
member: "ReleaseName"); |
|
||||
writer.WriteString(a0); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<uint> StartServiceByNameAsync(string a0, uint a1) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_u(m, (DBusObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "su", |
|
||||
member: "StartServiceByName"); |
|
||||
writer.WriteString(a0); |
|
||||
writer.WriteUInt32(a1); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task UpdateActivationEnvironmentAsync(Dictionary<string, string> a0) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "a{ss}", |
|
||||
member: "UpdateActivationEnvironment"); |
|
||||
writer.WriteDictionary(a0); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<bool> NameHasOwnerAsync(string a0) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_b(m, (DBusObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "s", |
|
||||
member: "NameHasOwner"); |
|
||||
writer.WriteString(a0); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<string[]> ListNamesAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_as(m, (DBusObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
"ListNames"); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<string[]> ListActivatableNamesAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_as(m, (DBusObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
"ListActivatableNames"); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task AddMatchAsync(string a0) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "s", |
|
||||
member: "AddMatch"); |
|
||||
writer.WriteString(a0); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task RemoveMatchAsync(string a0) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "s", |
|
||||
member: "RemoveMatch"); |
|
||||
writer.WriteString(a0); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<string> GetNameOwnerAsync(string a0) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_s(m, (DBusObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "s", |
|
||||
member: "GetNameOwner"); |
|
||||
writer.WriteString(a0); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<string[]> ListQueuedOwnersAsync(string a0) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_as(m, (DBusObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "s", |
|
||||
member: "ListQueuedOwners"); |
|
||||
writer.WriteString(a0); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<uint> GetConnectionUnixUserAsync(string a0) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_u(m, (DBusObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "s", |
|
||||
member: "GetConnectionUnixUser"); |
|
||||
writer.WriteString(a0); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<uint> GetConnectionUnixProcessIDAsync(string a0) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_u(m, (DBusObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "s", |
|
||||
member: "GetConnectionUnixProcessID"); |
|
||||
writer.WriteString(a0); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<byte[]> GetAdtAuditSessionDataAsync(string a0) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_ay(m, (DBusObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "s", |
|
||||
member: "GetAdtAuditSessionData"); |
|
||||
writer.WriteString(a0); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<byte[]> GetConnectionSELinuxSecurityContextAsync(string a0) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_ay(m, (DBusObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "s", |
|
||||
member: "GetConnectionSELinuxSecurityContext"); |
|
||||
writer.WriteString(a0); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task ReloadConfigAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
"ReloadConfig"); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<string> GetIdAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_s(m, (DBusObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
"GetId"); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<Dictionary<string, object>> GetConnectionCredentialsAsync(string a0) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_aesv(m, (DBusObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "s", |
|
||||
member: "GetConnectionCredentials"); |
|
||||
writer.WriteString(a0); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchNameOwnerChangedAsync(Action<Exception?, (string A0, string A1, string A2)> handler, bool emitOnCapturedContext = true) => |
|
||||
WatchSignalAsync(Service.Destination, Interface, Path, "NameOwnerChanged", static (m, s) => |
|
||||
ReadMessage_sss(m, (DBusObject)s!), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchNameLostAsync(Action<Exception?, string> handler, bool emitOnCapturedContext = true) => |
|
||||
WatchSignalAsync(Service.Destination, Interface, Path, "NameLost", static (m, s) => |
|
||||
ReadMessage_s(m, (DBusObject)s!), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchNameAcquiredAsync(Action<Exception?, string> handler, bool emitOnCapturedContext = true) => |
|
||||
WatchSignalAsync(Service.Destination, Interface, Path, "NameAcquired", static (m, s) => |
|
||||
ReadMessage_s(m, (DBusObject)s!), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public Task SetFeaturesAsync(string[] value) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "ssv", |
|
||||
member: "Set"); |
|
||||
writer.WriteString(Interface); |
|
||||
writer.WriteString("Features"); |
|
||||
writer.WriteSignature("as"); |
|
||||
writer.WriteArray(value); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetInterfacesAsync(string[] value) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "ssv", |
|
||||
member: "Set"); |
|
||||
writer.WriteString(Interface); |
|
||||
writer.WriteString("Interfaces"); |
|
||||
writer.WriteSignature("as"); |
|
||||
writer.WriteArray(value); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<string[]> GetFeaturesAsync() => |
|
||||
Connection.CallMethodAsync(CreateGetPropertyMessage(Interface, "Features"), static (m, s) => |
|
||||
ReadMessage_v_as(m, (DBusObject)s!), this); |
|
||||
|
|
||||
public Task<string[]> GetInterfacesAsync() => |
|
||||
Connection.CallMethodAsync(CreateGetPropertyMessage(Interface, "Interfaces"), static (m, s) => |
|
||||
ReadMessage_v_as(m, (DBusObject)s!), this); |
|
||||
|
|
||||
public Task<DBusProperties> GetPropertiesAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateGetAllPropertiesMessage(Interface), static (m, _) => |
|
||||
ReadMessage(m), this); |
|
||||
|
|
||||
static DBusProperties ReadMessage(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return ReadProperties(ref reader); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchPropertiesChangedAsync(Action<Exception?, PropertyChanges<DBusProperties>> handler, bool emitOnCapturedContext = true) |
|
||||
{ |
|
||||
return base.WatchPropertiesChangedAsync(Interface, static (m, _) => |
|
||||
ReadMessage(m), handler, emitOnCapturedContext); |
|
||||
|
|
||||
static PropertyChanges<DBusProperties> ReadMessage(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
reader.ReadString(); // interface
|
|
||||
List<string> changed = new(); |
|
||||
return new PropertyChanges<DBusProperties>(ReadProperties(ref reader, changed), changed.ToArray(), ReadInvalidated(ref reader)); |
|
||||
} |
|
||||
|
|
||||
static string[] ReadInvalidated(ref Reader reader) |
|
||||
{ |
|
||||
List<string>? invalidated = null; |
|
||||
var headersEnd = reader.ReadArrayStart(DBusType.String); |
|
||||
while (reader.HasNext(headersEnd)) |
|
||||
{ |
|
||||
invalidated ??= new List<string>(); |
|
||||
var property = reader.ReadString(); |
|
||||
switch (property) |
|
||||
{ |
|
||||
case "Features": |
|
||||
invalidated.Add("Features"); |
|
||||
break; |
|
||||
case "Interfaces": |
|
||||
invalidated.Add("Interfaces"); |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return invalidated?.ToArray() ?? Array.Empty<string>(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private static DBusProperties ReadProperties(ref Reader reader, List<string>? changedList = null) |
|
||||
{ |
|
||||
var props = new DBusProperties(); |
|
||||
var headersEnd = reader.ReadArrayStart(DBusType.Struct); |
|
||||
while (reader.HasNext(headersEnd)) |
|
||||
{ |
|
||||
var property = reader.ReadString(); |
|
||||
switch (property) |
|
||||
{ |
|
||||
case "Features": |
|
||||
reader.ReadSignature("as"); |
|
||||
props.Features = reader.ReadArray<string>(); |
|
||||
changedList?.Add("Features"); |
|
||||
break; |
|
||||
case "Interfaces": |
|
||||
reader.ReadSignature("as"); |
|
||||
props.Interfaces = reader.ReadArray<string>(); |
|
||||
changedList?.Add("Interfaces"); |
|
||||
break; |
|
||||
default: |
|
||||
reader.ReadVariant(); |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return props; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
internal class DBusService |
|
||||
{ |
|
||||
public DBusService(Connection connection, string destination) |
|
||||
=> (Connection, Destination) = (connection, destination); |
|
||||
|
|
||||
public Connection Connection { get; } |
|
||||
public string Destination { get; } |
|
||||
public DBus CreateDBus(string path) => new(this, path); |
|
||||
} |
|
||||
|
|
||||
internal class DBusObject |
|
||||
{ |
|
||||
protected DBusObject(DBusService service, ObjectPath path) |
|
||||
{ |
|
||||
Service = service; |
|
||||
Path = path; |
|
||||
} |
|
||||
|
|
||||
public DBusService Service { get; } |
|
||||
public ObjectPath Path { get; } |
|
||||
protected Connection Connection => Service.Connection; |
|
||||
|
|
||||
protected MessageBuffer CreateGetPropertyMessage(string @interface, string property) |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "ss", |
|
||||
member: "Get"); |
|
||||
writer.WriteString(@interface); |
|
||||
writer.WriteString(property); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
|
|
||||
protected MessageBuffer CreateGetAllPropertiesMessage(string @interface) |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "s", |
|
||||
member: "GetAll"); |
|
||||
writer.WriteString(@interface); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
|
|
||||
protected ValueTask<IDisposable> WatchPropertiesChangedAsync<TProperties>(string @interface, |
|
||||
MessageValueReader<PropertyChanges<TProperties>> reader, Action<Exception?, PropertyChanges<TProperties>> handler, |
|
||||
bool emitOnCapturedContext) |
|
||||
{ |
|
||||
var rule = new MatchRule |
|
||||
{ |
|
||||
Type = MessageType.Signal, |
|
||||
Sender = Service.Destination, |
|
||||
Path = Path, |
|
||||
Interface = "org.freedesktop.DBus.Properties", |
|
||||
Member = "PropertiesChanged", |
|
||||
Arg0 = @interface |
|
||||
}; |
|
||||
return Connection.AddMatchAsync(rule, reader, static (ex, changes, _, hs) => |
|
||||
((Action<Exception?, PropertyChanges<TProperties>>)hs!).Invoke(ex, changes), this, handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchSignalAsync<TArg>(string sender, string @interface, ObjectPath path, string signal, |
|
||||
MessageValueReader<TArg> reader, Action<Exception?, TArg> handler, bool emitOnCapturedContext) |
|
||||
{ |
|
||||
var rule = new MatchRule |
|
||||
{ |
|
||||
Type = MessageType.Signal, |
|
||||
Sender = sender, |
|
||||
Path = path, |
|
||||
Member = signal, |
|
||||
Interface = @interface |
|
||||
}; |
|
||||
return Connection.AddMatchAsync(rule, reader, static (ex, arg, _, hs) => |
|
||||
((Action<Exception?, TArg>)hs!).Invoke(ex, arg), this, handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchSignalAsync(string sender, string @interface, ObjectPath path, string signal, Action<Exception?> handler, |
|
||||
bool emitOnCapturedContext) |
|
||||
{ |
|
||||
var rule = new MatchRule |
|
||||
{ |
|
||||
Type = MessageType.Signal, |
|
||||
Sender = sender, |
|
||||
Path = path, |
|
||||
Member = signal, |
|
||||
Interface = @interface |
|
||||
}; |
|
||||
return Connection.AddMatchAsync<object>(rule, static (_, _) => null!, static (ex, _, _, hs) => |
|
||||
((Action<Exception?>)hs!).Invoke(ex), this, handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
protected static string ReadMessage_s(Message message, DBusObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return reader.ReadString(); |
|
||||
} |
|
||||
|
|
||||
protected static uint ReadMessage_u(Message message, DBusObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return reader.ReadUInt32(); |
|
||||
} |
|
||||
|
|
||||
protected static bool ReadMessage_b(Message message, DBusObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return reader.ReadBool(); |
|
||||
} |
|
||||
|
|
||||
protected static string[] ReadMessage_as(Message message, DBusObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return reader.ReadArray<string>(); |
|
||||
} |
|
||||
|
|
||||
protected static byte[] ReadMessage_ay(Message message, DBusObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return reader.ReadArray<byte>(); |
|
||||
} |
|
||||
|
|
||||
protected static Dictionary<string, object> ReadMessage_aesv(Message message, DBusObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return reader.ReadDictionary<string, object>(); |
|
||||
} |
|
||||
|
|
||||
protected static (string, string, string) ReadMessage_sss(Message message, DBusObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
var arg0 = reader.ReadString(); |
|
||||
var arg1 = reader.ReadString(); |
|
||||
var arg2 = reader.ReadString(); |
|
||||
return (arg0, arg1, arg2); |
|
||||
} |
|
||||
|
|
||||
protected static string[] ReadMessage_v_as(Message message, DBusObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
reader.ReadSignature("as"); |
|
||||
return reader.ReadArray<string>(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,627 +0,0 @@ |
|||||
using System; |
|
||||
using System.Threading.Tasks; |
|
||||
using Tmds.DBus.Protocol; |
|
||||
|
|
||||
namespace Avalonia.FreeDesktop.DBusIme.Fcitx |
|
||||
{ |
|
||||
internal class InputContext : FcitxObject |
|
||||
{ |
|
||||
private const string Interface = "org.fcitx.Fcitx.InputContext"; |
|
||||
|
|
||||
public InputContext(FcitxService service, ObjectPath path) : base(service, path) { } |
|
||||
|
|
||||
public Task FocusInAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
"FocusIn"); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task FocusOutAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
"FocusOut"); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task ResetAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
"Reset"); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetCursorRectAsync(int x, int y, int w, int h) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "iiii", |
|
||||
member: "SetCursorRect"); |
|
||||
writer.WriteInt32(x); |
|
||||
writer.WriteInt32(y); |
|
||||
writer.WriteInt32(w); |
|
||||
writer.WriteInt32(h); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetCapacityAsync(uint caps) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "u", |
|
||||
member: "SetCapacity"); |
|
||||
writer.WriteUInt32(caps); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetSurroundingTextAsync(string text, uint cursor, uint anchor) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "suu", |
|
||||
member: "SetSurroundingText"); |
|
||||
writer.WriteString(text); |
|
||||
writer.WriteUInt32(cursor); |
|
||||
writer.WriteUInt32(anchor); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetSurroundingTextPositionAsync(uint cursor, uint anchor) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "uu", |
|
||||
member: "SetSurroundingTextPosition"); |
|
||||
writer.WriteUInt32(cursor); |
|
||||
writer.WriteUInt32(anchor); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task DestroyICAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
"DestroyIC"); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<int> ProcessKeyEventAsync(uint keyval, uint keycode, uint state, int type, uint time) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_i(m, (FcitxObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "uuuiu", |
|
||||
member: "ProcessKeyEvent"); |
|
||||
writer.WriteUInt32(keyval); |
|
||||
writer.WriteUInt32(keycode); |
|
||||
writer.WriteUInt32(state); |
|
||||
writer.WriteInt32(type); |
|
||||
writer.WriteUInt32(time); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchCommitStringAsync(Action<Exception?, string> handler, bool emitOnCapturedContext = true) => |
|
||||
WatchSignalAsync(Service.Destination, Interface, Path, "CommitString", static (m, s) => |
|
||||
ReadMessage_s(m, (FcitxObject)s!), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchCurrentIMAsync(Action<Exception?, (string Name, string UniqueName, string LangCode)> handler, |
|
||||
bool emitOnCapturedContext = true) => |
|
||||
WatchSignalAsync(Service.Destination, Interface, Path, "CurrentIM", static (m, s) => |
|
||||
ReadMessage_sss(m, (FcitxObject)s!), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchUpdateFormattedPreeditAsync(Action<Exception?, ((string, int)[] Str, int Cursorpos)> handler, |
|
||||
bool emitOnCapturedContext = true) => |
|
||||
WatchSignalAsync(Service.Destination, Interface, Path, "UpdateFormattedPreedit", static (m, s) => |
|
||||
ReadMessage_arsizi(m, (FcitxObject)s!), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchForwardKeyAsync(Action<Exception?, (uint Keyval, uint State, int Type)> handler, |
|
||||
bool emitOnCapturedContext = true) => |
|
||||
WatchSignalAsync(Service.Destination, Interface, Path, "ForwardKey", static (m, s) => |
|
||||
ReadMessage_uui(m, (FcitxObject)s!), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchDeleteSurroundingTextAsync(Action<Exception?, (int Offset, uint Nchar)> handler, |
|
||||
bool emitOnCapturedContext = true) => |
|
||||
WatchSignalAsync(Service.Destination, Interface, Path, "DeleteSurroundingText", static (m, s) => |
|
||||
ReadMessage_iu(m, (FcitxObject)s!), handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
internal class InputMethod : FcitxObject |
|
||||
{ |
|
||||
private const string Interface = "org.fcitx.Fcitx.InputMethod"; |
|
||||
|
|
||||
public InputMethod(FcitxService service, ObjectPath path) : base(service, path) { } |
|
||||
|
|
||||
public Task<(int Icid, bool Enable, uint Keyval1, uint State1, uint Keyval2, uint State2)> CreateICv3Async(string appname, int pid) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_ibuuuu(m, (FcitxObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "si", |
|
||||
member: "CreateICv3"); |
|
||||
writer.WriteString(appname); |
|
||||
writer.WriteInt32(pid); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
internal class InputContext1 : FcitxObject |
|
||||
{ |
|
||||
private const string Interface = "org.fcitx.Fcitx.InputContext1"; |
|
||||
|
|
||||
public InputContext1(FcitxService service, ObjectPath path) : base(service, path) { } |
|
||||
|
|
||||
public Task FocusInAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
"FocusIn"); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task FocusOutAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
"FocusOut"); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task ResetAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
"Reset"); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetCursorRectAsync(int x, int y, int w, int h) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "iiii", |
|
||||
member: "SetCursorRect"); |
|
||||
writer.WriteInt32(x); |
|
||||
writer.WriteInt32(y); |
|
||||
writer.WriteInt32(w); |
|
||||
writer.WriteInt32(h); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetCapabilityAsync(ulong caps) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "t", |
|
||||
member: "SetCapability"); |
|
||||
writer.WriteUInt64(caps); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetSurroundingTextAsync(string text, uint cursor, uint anchor) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "suu", |
|
||||
member: "SetSurroundingText"); |
|
||||
writer.WriteString(text); |
|
||||
writer.WriteUInt32(cursor); |
|
||||
writer.WriteUInt32(anchor); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetSurroundingTextPositionAsync(uint cursor, uint anchor) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "uu", |
|
||||
member: "SetSurroundingTextPosition"); |
|
||||
writer.WriteUInt32(cursor); |
|
||||
writer.WriteUInt32(anchor); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task DestroyICAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
"DestroyIC"); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<bool> ProcessKeyEventAsync(uint keyval, uint keycode, uint state, bool type, uint time) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_b(m, (FcitxObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "uuubu", |
|
||||
member: "ProcessKeyEvent"); |
|
||||
writer.WriteUInt32(keyval); |
|
||||
writer.WriteUInt32(keycode); |
|
||||
writer.WriteUInt32(state); |
|
||||
writer.WriteBool(type); |
|
||||
writer.WriteUInt32(time); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchCommitStringAsync(Action<Exception?, string> handler, bool emitOnCapturedContext = true) |
|
||||
=> WatchSignalAsync(Service.Destination, Interface, Path, "CommitString", static (m, s) => |
|
||||
ReadMessage_s(m, (FcitxObject)s!), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchCurrentIMAsync(Action<Exception?, (string Name, string UniqueName, string LangCode)> handler, |
|
||||
bool emitOnCapturedContext = true) => |
|
||||
WatchSignalAsync(Service.Destination, Interface, Path, "CurrentIM", static (m, s) => |
|
||||
ReadMessage_sss(m, (FcitxObject)s!), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchUpdateFormattedPreeditAsync(Action<Exception?, ((string, int)[] Str, int Cursorpos)> handler, |
|
||||
bool emitOnCapturedContext = true) => |
|
||||
WatchSignalAsync(Service.Destination, Interface, Path, "UpdateFormattedPreedit", static (m, s) => |
|
||||
ReadMessage_arsizi(m, (FcitxObject)s!), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchForwardKeyAsync(Action<Exception?, (uint Keyval, uint State, bool Type)> handler, |
|
||||
bool emitOnCapturedContext = true) => |
|
||||
WatchSignalAsync(Service.Destination, Interface, Path, "ForwardKey", static (m, s) => |
|
||||
ReadMessage_uub(m, (FcitxObject)s!), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchDeleteSurroundingTextAsync(Action<Exception?, (int Offset, uint Nchar)> handler, |
|
||||
bool emitOnCapturedContext = true) => |
|
||||
WatchSignalAsync(Service.Destination, Interface, Path, "DeleteSurroundingText", static (m, s) => |
|
||||
ReadMessage_iu(m, (FcitxObject)s!), handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
internal class InputMethod1 : FcitxObject |
|
||||
{ |
|
||||
private const string Interface = "org.fcitx.Fcitx.InputMethod1"; |
|
||||
|
|
||||
public InputMethod1(FcitxService service, ObjectPath path) : base(service, path) { } |
|
||||
|
|
||||
public Task<(ObjectPath A0, byte[] A1)> CreateInputContextAsync((string, string)[] a0) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_oay(m, (FcitxObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "a(ss)", |
|
||||
member: "CreateInputContext"); |
|
||||
writer.WriteArray(a0); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
internal class FcitxService |
|
||||
{ |
|
||||
public FcitxService(Connection connection, string destination) |
|
||||
=> (Connection, Destination) = (connection, destination); |
|
||||
|
|
||||
public Connection Connection { get; } |
|
||||
public string Destination { get; } |
|
||||
public InputContext CreateInputContext(string path) => new(this, path); |
|
||||
public InputMethod CreateInputMethod(string path) => new(this, path); |
|
||||
public InputContext1 CreateInputContext1(string path) => new(this, path); |
|
||||
public InputMethod1 CreateInputMethod1(string path) => new(this, path); |
|
||||
} |
|
||||
|
|
||||
internal class FcitxObject |
|
||||
{ |
|
||||
protected FcitxObject(FcitxService service, ObjectPath path) |
|
||||
=> (Service, Path) = (service, path); |
|
||||
|
|
||||
public FcitxService Service { get; } |
|
||||
public ObjectPath Path { get; } |
|
||||
protected Connection Connection => Service.Connection; |
|
||||
|
|
||||
protected MessageBuffer CreateGetPropertyMessage(string @interface, string property) |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "ss", |
|
||||
member: "Get"); |
|
||||
writer.WriteString(@interface); |
|
||||
writer.WriteString(property); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
|
|
||||
protected MessageBuffer CreateGetAllPropertiesMessage(string @interface) |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "s", |
|
||||
member: "GetAll"); |
|
||||
writer.WriteString(@interface); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
|
|
||||
protected ValueTask<IDisposable> WatchPropertiesChangedAsync<TProperties>(string @interface, |
|
||||
MessageValueReader<PropertyChanges<TProperties>> reader, Action<Exception?, PropertyChanges<TProperties>> handler, |
|
||||
bool emitOnCapturedContext) |
|
||||
{ |
|
||||
var rule = new MatchRule |
|
||||
{ |
|
||||
Type = MessageType.Signal, |
|
||||
Sender = Service.Destination, |
|
||||
Path = Path, |
|
||||
Interface = "org.freedesktop.DBus.Properties", |
|
||||
Member = "PropertiesChanged", |
|
||||
Arg0 = @interface |
|
||||
}; |
|
||||
return Connection.AddMatchAsync(rule, reader, static (ex, changes, _, hs) => |
|
||||
((Action<Exception?, PropertyChanges<TProperties>>)hs!).Invoke(ex, changes), |
|
||||
this, handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchSignalAsync<TArg>(string sender, string @interface, ObjectPath path, string signal, |
|
||||
MessageValueReader<TArg> reader, Action<Exception?, TArg> handler, bool emitOnCapturedContext) |
|
||||
{ |
|
||||
var rule = new MatchRule |
|
||||
{ |
|
||||
Type = MessageType.Signal, |
|
||||
Sender = sender, |
|
||||
Path = path, |
|
||||
Member = signal, |
|
||||
Interface = @interface |
|
||||
}; |
|
||||
return Connection.AddMatchAsync(rule, reader, static (ex, arg, _, hs) => |
|
||||
((Action<Exception?, TArg>)hs!).Invoke(ex, arg), this, handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchSignalAsync(string sender, string @interface, ObjectPath path, string signal, Action<Exception?> handler, |
|
||||
bool emitOnCapturedContext) |
|
||||
{ |
|
||||
var rule = new MatchRule |
|
||||
{ |
|
||||
Type = MessageType.Signal, |
|
||||
Sender = sender, |
|
||||
Path = path, |
|
||||
Member = signal, |
|
||||
Interface = @interface |
|
||||
}; |
|
||||
return Connection.AddMatchAsync<object>(rule, static (_, _) => |
|
||||
null!, static (ex, _, _, hs) => |
|
||||
((Action<Exception?>)hs!).Invoke(ex), this, handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
protected static int ReadMessage_i(Message message, FcitxObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return reader.ReadInt32(); |
|
||||
} |
|
||||
|
|
||||
protected static string ReadMessage_s(Message message, FcitxObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return reader.ReadString(); |
|
||||
} |
|
||||
|
|
||||
protected static (string, string, string) ReadMessage_sss(Message message, FcitxObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
var arg0 = reader.ReadString(); |
|
||||
var arg1 = reader.ReadString(); |
|
||||
var arg2 = reader.ReadString(); |
|
||||
return (arg0, arg1, arg2); |
|
||||
} |
|
||||
|
|
||||
protected static ((string, int)[], int) ReadMessage_arsizi(Message message, FcitxObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
var arg0 = reader.ReadArray<(string, int)>(); |
|
||||
var arg1 = reader.ReadInt32(); |
|
||||
return (arg0, arg1); |
|
||||
} |
|
||||
|
|
||||
protected static (uint, uint, int) ReadMessage_uui(Message message, FcitxObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
var arg0 = reader.ReadUInt32(); |
|
||||
var arg1 = reader.ReadUInt32(); |
|
||||
var arg2 = reader.ReadInt32(); |
|
||||
return (arg0, arg1, arg2); |
|
||||
} |
|
||||
|
|
||||
protected static (int, uint) ReadMessage_iu(Message message, FcitxObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
var arg0 = reader.ReadInt32(); |
|
||||
var arg1 = reader.ReadUInt32(); |
|
||||
return (arg0, arg1); |
|
||||
} |
|
||||
|
|
||||
protected static (int, bool, uint, uint, uint, uint) ReadMessage_ibuuuu(Message message, FcitxObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
var arg0 = reader.ReadInt32(); |
|
||||
var arg1 = reader.ReadBool(); |
|
||||
var arg2 = reader.ReadUInt32(); |
|
||||
var arg3 = reader.ReadUInt32(); |
|
||||
var arg4 = reader.ReadUInt32(); |
|
||||
var arg5 = reader.ReadUInt32(); |
|
||||
return (arg0, arg1, arg2, arg3, arg4, arg5); |
|
||||
} |
|
||||
|
|
||||
protected static bool ReadMessage_b(Message message, FcitxObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return reader.ReadBool(); |
|
||||
} |
|
||||
|
|
||||
protected static (uint, uint, bool) ReadMessage_uub(Message message, FcitxObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
var arg0 = reader.ReadUInt32(); |
|
||||
var arg1 = reader.ReadUInt32(); |
|
||||
var arg2 = reader.ReadBool(); |
|
||||
return (arg0, arg1, arg2); |
|
||||
} |
|
||||
|
|
||||
protected static (ObjectPath, byte[]) ReadMessage_oay(Message message, FcitxObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
var arg0 = reader.ReadObjectPath(); |
|
||||
var arg1 = reader.ReadArray<byte>(); |
|
||||
return (arg0, arg1); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,513 +0,0 @@ |
|||||
using System; |
|
||||
using System.Threading.Tasks; |
|
||||
using Tmds.DBus.Protocol; |
|
||||
|
|
||||
namespace Avalonia.FreeDesktop.DBusIme.IBus |
|
||||
{ |
|
||||
internal class Portal : IBusObject |
|
||||
{ |
|
||||
private const string Interface = "org.freedesktop.IBus.Portal"; |
|
||||
|
|
||||
public Portal(IBusService service, ObjectPath path) : base(service, path) { } |
|
||||
|
|
||||
public Task<ObjectPath> CreateInputContextAsync(string clientName) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_o(m, (IBusObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "s", |
|
||||
member: "CreateInputContext"); |
|
||||
writer.WriteString(clientName); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
internal class InputContext : IBusObject |
|
||||
{ |
|
||||
private const string Interface = "org.freedesktop.IBus.InputContext"; |
|
||||
|
|
||||
public InputContext(IBusService service, ObjectPath path) : base(service, path) { } |
|
||||
|
|
||||
public Task<bool> ProcessKeyEventAsync(uint keyval, uint keycode, uint state) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_b(m, (IBusObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "uuu", |
|
||||
member: "ProcessKeyEvent"); |
|
||||
writer.WriteUInt32(keyval); |
|
||||
writer.WriteUInt32(keycode); |
|
||||
writer.WriteUInt32(state); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetCursorLocationAsync(int x, int y, int w, int h) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "iiii", |
|
||||
member: "SetCursorLocation"); |
|
||||
writer.WriteInt32(x); |
|
||||
writer.WriteInt32(y); |
|
||||
writer.WriteInt32(w); |
|
||||
writer.WriteInt32(h); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetCursorLocationRelativeAsync(int x, int y, int w, int h) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "iiii", |
|
||||
member: "SetCursorLocationRelative"); |
|
||||
writer.WriteInt32(x); |
|
||||
writer.WriteInt32(y); |
|
||||
writer.WriteInt32(w); |
|
||||
writer.WriteInt32(h); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task ProcessHandWritingEventAsync(double[] coordinates) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "ad", |
|
||||
member: "ProcessHandWritingEvent"); |
|
||||
writer.WriteArray(coordinates); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task CancelHandWritingAsync(uint nStrokes) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "u", |
|
||||
member: "CancelHandWriting"); |
|
||||
writer.WriteUInt32(nStrokes); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task FocusInAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
"FocusIn"); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task FocusOutAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
"FocusOut"); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task ResetAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
"Reset"); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetCapabilitiesAsync(uint caps) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "u", |
|
||||
member: "SetCapabilities"); |
|
||||
writer.WriteUInt32(caps); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task PropertyActivateAsync(string name, uint state) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "su", |
|
||||
member: "PropertyActivate"); |
|
||||
writer.WriteString(name); |
|
||||
writer.WriteUInt32(state); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetEngineAsync(string name) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "s", |
|
||||
member: "SetEngine"); |
|
||||
writer.WriteString(name); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<object> GetEngineAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_v(m, (IBusObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
"GetEngine"); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetSurroundingTextAsync(object text, uint cursorPos, uint anchorPos) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "vuu", |
|
||||
member: "SetSurroundingText"); |
|
||||
writer.WriteVariant(text); |
|
||||
writer.WriteUInt32(cursorPos); |
|
||||
writer.WriteUInt32(anchorPos); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchCommitTextAsync(Action<Exception?, object> handler, bool emitOnCapturedContext = true) => |
|
||||
WatchSignalAsync(Service.Destination, Interface, Path, "CommitText", static (m, s) => |
|
||||
ReadMessage_v(m, (IBusObject)s!), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchForwardKeyEventAsync(Action<Exception?, (uint Keyval, uint Keycode, uint State)> handler, |
|
||||
bool emitOnCapturedContext = true) => |
|
||||
WatchSignalAsync(Service.Destination, Interface, Path, "ForwardKeyEvent", static (m, s) => |
|
||||
ReadMessage_uuu(m, (IBusObject)s!), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchUpdatePreeditTextAsync(Action<Exception?, (object Text, uint CursorPos, bool Visible)> handler, |
|
||||
bool emitOnCapturedContext = true) => |
|
||||
WatchSignalAsync(Service.Destination, Interface, Path, "UpdatePreeditText", static (m, s) => |
|
||||
ReadMessage_vub(m, (IBusObject)s!), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchUpdatePreeditTextWithModeAsync( |
|
||||
Action<Exception?, (object Text, uint CursorPos, bool Visible, uint Mode)> handler, bool emitOnCapturedContext = true) => |
|
||||
WatchSignalAsync(Service.Destination, Interface, Path, "UpdatePreeditTextWithMode", static (m, s) => |
|
||||
ReadMessage_vubu(m, (IBusObject)s!), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchShowPreeditTextAsync(Action<Exception?> handler, bool emitOnCapturedContext = true) |
|
||||
=> WatchSignalAsync(Service.Destination, Interface, Path, "ShowPreeditText", handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchHidePreeditTextAsync(Action<Exception?> handler, bool emitOnCapturedContext = true) |
|
||||
=> WatchSignalAsync(Service.Destination, Interface, Path, "HidePreeditText", handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchUpdateAuxiliaryTextAsync(Action<Exception?, (object Text, bool Visible)> handler, |
|
||||
bool emitOnCapturedContext = true) => |
|
||||
WatchSignalAsync(Service.Destination, Interface, Path, "UpdateAuxiliaryText", static (m, s) => |
|
||||
ReadMessage_vb(m, (IBusObject)s!), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchShowAuxiliaryTextAsync(Action<Exception?> handler, bool emitOnCapturedContext = true) |
|
||||
=> WatchSignalAsync(Service.Destination, Interface, Path, "ShowAuxiliaryText", handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchHideAuxiliaryTextAsync(Action<Exception?> handler, bool emitOnCapturedContext = true) |
|
||||
=> WatchSignalAsync(Service.Destination, Interface, Path, "HideAuxiliaryText", handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchUpdateLookupTableAsync(Action<Exception?, (object Table, bool Visible)> handler, |
|
||||
bool emitOnCapturedContext = true) => |
|
||||
WatchSignalAsync(Service.Destination, Interface, Path, "UpdateLookupTable", static (m, s) => |
|
||||
ReadMessage_vb(m, (IBusObject)s!), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchShowLookupTableAsync(Action<Exception?> handler, bool emitOnCapturedContext = true) |
|
||||
=> WatchSignalAsync(Service.Destination, Interface, Path, "ShowLookupTable", handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchHideLookupTableAsync(Action<Exception?> handler, bool emitOnCapturedContext = true) |
|
||||
=> WatchSignalAsync(Service.Destination, Interface, Path, "HideLookupTable", handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchPageUpLookupTableAsync(Action<Exception?> handler, bool emitOnCapturedContext = true) |
|
||||
=> WatchSignalAsync(Service.Destination, Interface, Path, "PageUpLookupTable", handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchPageDownLookupTableAsync(Action<Exception?> handler, bool emitOnCapturedContext = true) |
|
||||
=> WatchSignalAsync(Service.Destination, Interface, Path, "PageDownLookupTable", handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchCursorUpLookupTableAsync(Action<Exception?> handler, bool emitOnCapturedContext = true) |
|
||||
=> WatchSignalAsync(Service.Destination, Interface, Path, "CursorUpLookupTable", handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchCursorDownLookupTableAsync(Action<Exception?> handler, bool emitOnCapturedContext = true) |
|
||||
=> WatchSignalAsync(Service.Destination, Interface, Path, "CursorDownLookupTable", handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchRegisterPropertiesAsync(Action<Exception?, object> handler, bool emitOnCapturedContext = true) |
|
||||
=> WatchSignalAsync(Service.Destination, Interface, Path, "RegisterProperties", static (m, s) => ReadMessage_v(m, (IBusObject)s!), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchUpdatePropertyAsync(Action<Exception?, object> handler, bool emitOnCapturedContext = true) |
|
||||
=> WatchSignalAsync(Service.Destination, Interface, Path, "UpdateProperty", static (m, s) => ReadMessage_v(m, (IBusObject)s!), handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
internal class Service : IBusObject |
|
||||
{ |
|
||||
private const string Interface = "org.freedesktop.IBus.Service"; |
|
||||
|
|
||||
public Service(IBusService service, ObjectPath path) : base(service, path) { } |
|
||||
|
|
||||
public Task DestroyAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
"Destroy"); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
internal class IBusService |
|
||||
{ |
|
||||
public IBusService(Connection connection, string destination) |
|
||||
=> (Connection, Destination) = (connection, destination); |
|
||||
|
|
||||
public Connection Connection { get; } |
|
||||
public string Destination { get; } |
|
||||
public Portal CreatePortal(string path) => new(this, path); |
|
||||
public InputContext CreateInputContext(string path) => new(this, path); |
|
||||
public Service CreateService(string path) => new(this, path); |
|
||||
} |
|
||||
|
|
||||
internal class IBusObject |
|
||||
{ |
|
||||
protected IBusObject(IBusService service, ObjectPath path) |
|
||||
=> (Service, Path) = (service, path); |
|
||||
|
|
||||
public IBusService Service { get; } |
|
||||
public ObjectPath Path { get; } |
|
||||
protected Connection Connection => Service.Connection; |
|
||||
|
|
||||
protected MessageBuffer CreateGetPropertyMessage(string @interface, string property) |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "ss", |
|
||||
member: "Get"); |
|
||||
writer.WriteString(@interface); |
|
||||
writer.WriteString(property); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
|
|
||||
protected MessageBuffer CreateGetAllPropertiesMessage(string @interface) |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "s", |
|
||||
member: "GetAll"); |
|
||||
writer.WriteString(@interface); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
|
|
||||
protected ValueTask<IDisposable> WatchPropertiesChangedAsync<TProperties>(string @interface, |
|
||||
MessageValueReader<PropertyChanges<TProperties>> reader, Action<Exception?, PropertyChanges<TProperties>> handler, |
|
||||
bool emitOnCapturedContext) |
|
||||
{ |
|
||||
var rule = new MatchRule |
|
||||
{ |
|
||||
Type = MessageType.Signal, |
|
||||
Sender = Service.Destination, |
|
||||
Path = Path, |
|
||||
Interface = "org.freedesktop.DBus.Properties", |
|
||||
Member = "PropertiesChanged", |
|
||||
Arg0 = @interface |
|
||||
}; |
|
||||
return Connection.AddMatchAsync(rule, reader, static (ex, changes, _, hs) => |
|
||||
((Action<Exception?, PropertyChanges<TProperties>>)hs!).Invoke(ex, changes), |
|
||||
this, handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchSignalAsync<TArg>(string sender, string @interface, ObjectPath path, string signal, |
|
||||
MessageValueReader<TArg> reader, Action<Exception?, TArg> handler, bool emitOnCapturedContext) |
|
||||
{ |
|
||||
var rule = new MatchRule |
|
||||
{ |
|
||||
Type = MessageType.Signal, |
|
||||
Sender = sender, |
|
||||
Path = path, |
|
||||
Member = signal, |
|
||||
Interface = @interface |
|
||||
}; |
|
||||
return Connection.AddMatchAsync(rule, reader, static (ex, arg, _, hs) => ((Action<Exception?, TArg>)hs!).Invoke(ex, arg), |
|
||||
this, handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchSignalAsync(string sender, string @interface, ObjectPath path, string signal, Action<Exception?> handler, |
|
||||
bool emitOnCapturedContext) |
|
||||
{ |
|
||||
var rule = new MatchRule |
|
||||
{ |
|
||||
Type = MessageType.Signal, |
|
||||
Sender = sender, |
|
||||
Path = path, |
|
||||
Member = signal, |
|
||||
Interface = @interface |
|
||||
}; |
|
||||
return Connection.AddMatchAsync<object>(rule, static (_, _) => null!, static (ex, _, _, hs) => ((Action<Exception?>)hs!).Invoke(ex), this, handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
protected static ObjectPath ReadMessage_o(Message message, IBusObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return reader.ReadObjectPath(); |
|
||||
} |
|
||||
|
|
||||
protected static bool ReadMessage_b(Message message, IBusObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return reader.ReadBool(); |
|
||||
} |
|
||||
|
|
||||
protected static object ReadMessage_v(Message message, IBusObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return reader.ReadVariant(); |
|
||||
} |
|
||||
|
|
||||
protected static (uint, uint, uint) ReadMessage_uuu(Message message, IBusObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
var arg0 = reader.ReadUInt32(); |
|
||||
var arg1 = reader.ReadUInt32(); |
|
||||
var arg2 = reader.ReadUInt32(); |
|
||||
return (arg0, arg1, arg2); |
|
||||
} |
|
||||
|
|
||||
protected static (object, uint, bool) ReadMessage_vub(Message message, IBusObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
var arg0 = reader.ReadVariant(); |
|
||||
var arg1 = reader.ReadUInt32(); |
|
||||
var arg2 = reader.ReadBool(); |
|
||||
return (arg0, arg1, arg2); |
|
||||
} |
|
||||
|
|
||||
protected static (object, uint, bool, uint) ReadMessage_vubu(Message message, IBusObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
var arg0 = reader.ReadVariant(); |
|
||||
var arg1 = reader.ReadUInt32(); |
|
||||
var arg2 = reader.ReadBool(); |
|
||||
var arg3 = reader.ReadUInt32(); |
|
||||
return (arg0, arg1, arg2, arg3); |
|
||||
} |
|
||||
|
|
||||
protected static (object, bool) ReadMessage_vb(Message message, IBusObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
var arg0 = reader.ReadVariant(); |
|
||||
var arg1 = reader.ReadBool(); |
|
||||
return (arg0, arg1); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,18 @@ |
|||||
|
using Tmds.DBus.SourceGenerator; |
||||
|
|
||||
|
namespace Avalonia.FreeDesktop |
||||
|
{ |
||||
|
[DBusInterface("./DBusXml/DBus.xml")] |
||||
|
[DBusInterface("./DBusXml/StatusNotifierWatcher.xml")] |
||||
|
[DBusInterface("./DBusXml/com.canonical.AppMenu.Registrar.xml")] |
||||
|
[DBusInterface("./DBusXml/org.fcitx.Fcitx.InputContext.xml")] |
||||
|
[DBusInterface("./DBusXml/org.fcitx.Fcitx.InputMethod.xml")] |
||||
|
[DBusInterface("./DBusXml/org.fcitx.Fcitx.InputContext1.xml")] |
||||
|
[DBusInterface("./DBusXml/org.fcitx.Fcitx.InputMethod1.xml")] |
||||
|
[DBusInterface("./DBusXml/org.freedesktop.portal.FileChooser.xml")] |
||||
|
[DBusInterface("./DBusXml/org.freedesktop.portal.Request.xml")] |
||||
|
[DBusInterface("./DBusXml/org.freedesktop.IBus.Portal.xml")] |
||||
|
[DBusHandler("./DBusXml/DBusMenu.xml")] |
||||
|
[DBusHandler("./DBusXml/StatusNotifierItem.xml")] |
||||
|
internal class DBusInterfaces { } |
||||
|
} |
||||
@ -1,500 +0,0 @@ |
|||||
using System; |
|
||||
using Tmds.DBus.Protocol; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Threading.Tasks; |
|
||||
|
|
||||
namespace Avalonia.FreeDesktop |
|
||||
{ |
|
||||
internal record DBusMenuProperties |
|
||||
{ |
|
||||
public uint Version { get; set; } |
|
||||
public string TextDirection { get; set; } = default!; |
|
||||
public string Status { get; set; } = default!; |
|
||||
public string[] IconThemePath { get; set; } = default!; |
|
||||
} |
|
||||
|
|
||||
internal class DBusMenu : DBusMenuObject |
|
||||
{ |
|
||||
private const string Interface = "com.canonical.dbusmenu"; |
|
||||
|
|
||||
public DBusMenu(DBusMenuService service, ObjectPath path) : base(service, path) { } |
|
||||
|
|
||||
public Task<(uint Revision, (int, Dictionary<string, object>, object[]) Layout)> GetLayoutAsync(int parentId, int recursionDepth, string[] propertyNames) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, _) => ReadMessage_uriaesvavz(m), this); |
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "iias", |
|
||||
member: "GetLayout"); |
|
||||
writer.WriteInt32(parentId); |
|
||||
writer.WriteInt32(recursionDepth); |
|
||||
writer.WriteArray(propertyNames); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<(int, Dictionary<string, object>)[]> GetGroupPropertiesAsync(int[] ids, string[] propertyNames) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, _) => ReadMessage_ariaesvz(m), this); |
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "aias", |
|
||||
member: "GetGroupProperties"); |
|
||||
writer.WriteArray(ids); |
|
||||
writer.WriteArray(propertyNames); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<object> GetPropertyAsync(int id, string name) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, _) => ReadMessage_v(m), this); |
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "is", |
|
||||
member: "GetProperty"); |
|
||||
writer.WriteInt32(id); |
|
||||
writer.WriteString(name); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task EventAsync(int id, string eventId, object data, uint timestamp) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "isvu", |
|
||||
member: "Event"); |
|
||||
writer.WriteInt32(id); |
|
||||
writer.WriteString(eventId); |
|
||||
writer.WriteVariant(data); |
|
||||
writer.WriteUInt32(timestamp); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<int[]> EventGroupAsync((int, string, object, uint)[] events) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, _) => ReadMessage_ai(m), this); |
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "a(isvu)", |
|
||||
member: "EventGroup"); |
|
||||
writer.WriteArray(events); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<bool> AboutToShowAsync(int id) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, _) => ReadMessage_b(m), this); |
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "i", |
|
||||
member: "AboutToShow"); |
|
||||
writer.WriteInt32(id); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<(int[] UpdatesNeeded, int[] IdErrors)> AboutToShowGroupAsync(int[] ids) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, _) => ReadMessage_aiai(m), this); |
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "ai", |
|
||||
member: "AboutToShowGroup"); |
|
||||
writer.WriteArray(ids); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchItemsPropertiesUpdatedAsync(Action<Exception?, ((int, Dictionary<string, object>)[] UpdatedProps, (int, string[])[] RemovedProps)> handler, bool emitOnCapturedContext = true) |
|
||||
=> WatchSignalAsync(Service.Destination, Interface, Path, "ItemsPropertiesUpdated", static (m, _) => ReadMessage_ariaesvzariasz(m), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchLayoutUpdatedAsync(Action<Exception?, (uint Revision, int Parent)> handler, bool emitOnCapturedContext = true) |
|
||||
=> WatchSignalAsync(Service.Destination, Interface, Path, "LayoutUpdated", static (m, _) => ReadMessage_ui(m), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchItemActivationRequestedAsync(Action<Exception?, (int Id, uint Timestamp)> handler, bool emitOnCapturedContext = true) |
|
||||
=> WatchSignalAsync(Service.Destination, Interface, Path, "ItemActivationRequested", static (m, _) => ReadMessage_iu(m), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public Task SetVersionAsync(uint value) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "ssv", |
|
||||
member: "Set"); |
|
||||
writer.WriteString(Interface); |
|
||||
writer.WriteString("Version"); |
|
||||
writer.WriteSignature("u"); |
|
||||
writer.WriteUInt32(value); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetTextDirectionAsync(string value) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "ssv", |
|
||||
member: "Set"); |
|
||||
writer.WriteString(Interface); |
|
||||
writer.WriteString("TextDirection"); |
|
||||
writer.WriteSignature("s"); |
|
||||
writer.WriteString(value); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetStatusAsync(string value) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "ssv", |
|
||||
member: "Set"); |
|
||||
writer.WriteString(Interface); |
|
||||
writer.WriteString("Status"); |
|
||||
writer.WriteSignature("s"); |
|
||||
writer.WriteString(value); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetIconThemePathAsync(string[] value) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "ssv", |
|
||||
member: "Set"); |
|
||||
writer.WriteString(Interface); |
|
||||
writer.WriteString("IconThemePath"); |
|
||||
writer.WriteSignature("as"); |
|
||||
writer.WriteArray(value); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<uint> GetVersionAsync() |
|
||||
=> Connection.CallMethodAsync(CreateGetPropertyMessage(Interface, "Version"), static (m, _) => ReadMessage_v_u(m), this); |
|
||||
|
|
||||
public Task<string> GetTextDirectionAsync() |
|
||||
=> Connection.CallMethodAsync(CreateGetPropertyMessage(Interface, "TextDirection"), static (m, _) => ReadMessage_v_s(m), this); |
|
||||
|
|
||||
public Task<string> GetStatusAsync() |
|
||||
=> Connection.CallMethodAsync(CreateGetPropertyMessage(Interface, "Status"), static (m, _) => ReadMessage_v_s(m), this); |
|
||||
|
|
||||
public Task<string[]> GetIconThemePathAsync() |
|
||||
=> Connection.CallMethodAsync(CreateGetPropertyMessage(Interface, "IconThemePath"), static (m, _) => ReadMessage_v_as(m), this); |
|
||||
|
|
||||
public Task<DBusMenuProperties> GetPropertiesAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateGetAllPropertiesMessage(Interface), static (m, _) => ReadMessage(m), this); |
|
||||
static DBusMenuProperties ReadMessage(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return ReadProperties(ref reader); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchPropertiesChangedAsync(Action<Exception?, PropertyChanges<DBusMenuProperties>> handler, bool emitOnCapturedContext = true) |
|
||||
{ |
|
||||
return base.WatchPropertiesChangedAsync(Interface, static (m, _) => ReadMessage(m), handler, emitOnCapturedContext); |
|
||||
static PropertyChanges<DBusMenuProperties> ReadMessage(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
reader.ReadString(); // interface
|
|
||||
List<string> changed = new(); |
|
||||
return new PropertyChanges<DBusMenuProperties>(ReadProperties(ref reader, changed), changed.ToArray(), ReadInvalidated(ref reader)); |
|
||||
} |
|
||||
static string[] ReadInvalidated(ref Reader reader) |
|
||||
{ |
|
||||
List<string>? invalidated = null; |
|
||||
var headersEnd = reader.ReadArrayStart(DBusType.String); |
|
||||
while (reader.HasNext(headersEnd)) |
|
||||
{ |
|
||||
invalidated ??= new List<string>(); |
|
||||
var property = reader.ReadString(); |
|
||||
switch (property) |
|
||||
{ |
|
||||
case "Version": invalidated.Add("Version"); break; |
|
||||
case "TextDirection": invalidated.Add("TextDirection"); break; |
|
||||
case "Status": invalidated.Add("Status"); break; |
|
||||
case "IconThemePath": invalidated.Add("IconThemePath"); break; |
|
||||
} |
|
||||
} |
|
||||
return invalidated?.ToArray() ?? Array.Empty<string>(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private static DBusMenuProperties ReadProperties(ref Reader reader, ICollection<string>? changedList = null) |
|
||||
{ |
|
||||
var props = new DBusMenuProperties(); |
|
||||
var headersEnd = reader.ReadArrayStart(DBusType.Struct); |
|
||||
while (reader.HasNext(headersEnd)) |
|
||||
{ |
|
||||
var property = reader.ReadString(); |
|
||||
switch (property) |
|
||||
{ |
|
||||
case "Version": |
|
||||
reader.ReadSignature("u"); |
|
||||
props.Version = reader.ReadUInt32(); |
|
||||
changedList?.Add("Version"); |
|
||||
break; |
|
||||
case "TextDirection": |
|
||||
reader.ReadSignature("s"); |
|
||||
props.TextDirection = reader.ReadString(); |
|
||||
changedList?.Add("TextDirection"); |
|
||||
break; |
|
||||
case "Status": |
|
||||
reader.ReadSignature("s"); |
|
||||
props.Status = reader.ReadString(); |
|
||||
changedList?.Add("Status"); |
|
||||
break; |
|
||||
case "IconThemePath": |
|
||||
reader.ReadSignature("as"); |
|
||||
props.IconThemePath = reader.ReadArray<string>(); |
|
||||
changedList?.Add("IconThemePath"); |
|
||||
break; |
|
||||
default: |
|
||||
reader.ReadVariant(); |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
return props; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
internal class DBusMenuService |
|
||||
{ |
|
||||
public Connection Connection { get; } |
|
||||
public string Destination { get; } |
|
||||
public DBusMenuService(Connection connection, string destination) |
|
||||
=> (Connection, Destination) = (connection, destination); |
|
||||
public DBusMenu CreateDbusmenu(string path) => new(this, path); |
|
||||
} |
|
||||
|
|
||||
internal class DBusMenuObject |
|
||||
{ |
|
||||
public DBusMenuService Service { get; } |
|
||||
public ObjectPath Path { get; } |
|
||||
protected Connection Connection => Service.Connection; |
|
||||
protected DBusMenuObject(DBusMenuService service, ObjectPath path) |
|
||||
=> (Service, Path) = (service, path); |
|
||||
|
|
||||
protected MessageBuffer CreateGetPropertyMessage(string @interface, string property) |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "ss", |
|
||||
member: "Get"); |
|
||||
writer.WriteString(@interface); |
|
||||
writer.WriteString(property); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
|
|
||||
protected MessageBuffer CreateGetAllPropertiesMessage(string @interface) |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "s", |
|
||||
member: "GetAll"); |
|
||||
writer.WriteString(@interface); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
|
|
||||
protected ValueTask<IDisposable> WatchPropertiesChangedAsync<TProperties>(string @interface, MessageValueReader<PropertyChanges<TProperties>> reader, Action<Exception?, PropertyChanges<TProperties>> handler, bool emitOnCapturedContext) |
|
||||
{ |
|
||||
var rule = new MatchRule |
|
||||
{ |
|
||||
Type = MessageType.Signal, |
|
||||
Sender = Service.Destination, |
|
||||
Path = Path, |
|
||||
Interface = "org.freedesktop.DBus.Properties", |
|
||||
Member = "PropertiesChanged", |
|
||||
Arg0 = @interface |
|
||||
}; |
|
||||
return Connection.AddMatchAsync(rule, reader, static (ex, changes, _, hs) |
|
||||
=> ((Action<Exception?, PropertyChanges<TProperties>>)hs!).Invoke(ex, changes), this, handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
protected ValueTask<IDisposable> WatchSignalAsync<TArg>(string sender, string @interface, ObjectPath path, string signal, MessageValueReader<TArg> reader, Action<Exception?, TArg> handler, bool emitOnCapturedContext) |
|
||||
{ |
|
||||
var rule = new MatchRule |
|
||||
{ |
|
||||
Type = MessageType.Signal, |
|
||||
Sender = sender, |
|
||||
Path = path, |
|
||||
Member = signal, |
|
||||
Interface = @interface |
|
||||
}; |
|
||||
return Connection.AddMatchAsync(rule, reader, static (ex, arg, _, hs) |
|
||||
=> ((Action<Exception?, TArg>)hs!).Invoke(ex, arg), this, handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
protected ValueTask<IDisposable> WatchSignalAsync(string sender, string @interface, ObjectPath path, string signal, Action<Exception?> handler, bool emitOnCapturedContext) |
|
||||
{ |
|
||||
var rule = new MatchRule |
|
||||
{ |
|
||||
Type = MessageType.Signal, |
|
||||
Sender = sender, |
|
||||
Path = path, |
|
||||
Member = signal, |
|
||||
Interface = @interface |
|
||||
}; |
|
||||
return Connection.AddMatchAsync<object>(rule, static (_, _) |
|
||||
=> null!, static (ex, _, _, hs) |
|
||||
=> ((Action<Exception?>)hs!).Invoke(ex), this, handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
protected static (uint, (int, Dictionary<string, object>, object[])) ReadMessage_uriaesvavz(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
var arg0 = reader.ReadUInt32(); |
|
||||
var arg1 = reader.ReadStruct<int, Dictionary<string, object>, object[]>(); |
|
||||
return (arg0, arg1); |
|
||||
} |
|
||||
|
|
||||
protected static (int, Dictionary<string, object>)[] ReadMessage_ariaesvz(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return reader.ReadArray<(int, Dictionary<string, object>)>(); |
|
||||
} |
|
||||
|
|
||||
protected static object ReadMessage_v(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return reader.ReadVariant(); |
|
||||
} |
|
||||
|
|
||||
protected static int[] ReadMessage_ai(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return reader.ReadArray<int>(); |
|
||||
} |
|
||||
|
|
||||
protected static bool ReadMessage_b(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return reader.ReadBool(); |
|
||||
} |
|
||||
|
|
||||
protected static (int[], int[]) ReadMessage_aiai(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
var arg0 = reader.ReadArray<int>(); |
|
||||
var arg1 = reader.ReadArray<int>(); |
|
||||
return (arg0, arg1); |
|
||||
} |
|
||||
|
|
||||
protected static ((int, Dictionary<string, object>)[], (int, string[])[]) ReadMessage_ariaesvzariasz(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
var arg0 = reader.ReadArray<(int, Dictionary<string, object>)>(); |
|
||||
var arg1 = reader.ReadArray<(int, string[])>(); |
|
||||
return (arg0, arg1); |
|
||||
} |
|
||||
|
|
||||
protected static (uint, int) ReadMessage_ui(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
var arg0 = reader.ReadUInt32(); |
|
||||
var arg1 = reader.ReadInt32(); |
|
||||
return (arg0, arg1); |
|
||||
} |
|
||||
|
|
||||
protected static (int, uint) ReadMessage_iu(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
var arg0 = reader.ReadInt32(); |
|
||||
var arg1 = reader.ReadUInt32(); |
|
||||
return (arg0, arg1); |
|
||||
} |
|
||||
|
|
||||
protected static uint ReadMessage_v_u(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
reader.ReadSignature("u"); |
|
||||
return reader.ReadUInt32(); |
|
||||
} |
|
||||
|
|
||||
protected static string ReadMessage_v_s(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
reader.ReadSignature("s"); |
|
||||
return reader.ReadString(); |
|
||||
} |
|
||||
|
|
||||
protected static string[] ReadMessage_v_as(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
reader.ReadSignature("as"); |
|
||||
return reader.ReadArray<string>(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,938 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Runtime.InteropServices; |
|
||||
using System.Threading.Tasks; |
|
||||
using Tmds.DBus.Protocol; |
|
||||
|
|
||||
namespace Avalonia.FreeDesktop |
|
||||
{ |
|
||||
internal record NotificationProperties |
|
||||
{ |
|
||||
public uint Version { get; set; } |
|
||||
} |
|
||||
|
|
||||
internal class Notification : DesktopObject |
|
||||
{ |
|
||||
private const string Interface = "org.freedesktop.portal.Notification"; |
|
||||
|
|
||||
public Notification(DesktopService service, ObjectPath path) : base(service, path) { } |
|
||||
|
|
||||
public Task AddNotificationAsync(string id, Dictionary<string, object> notification) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "sa{sv}", |
|
||||
member: "AddNotification"); |
|
||||
writer.WriteString(id); |
|
||||
writer.WriteDictionary(notification); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task RemoveNotificationAsync(string id) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "s", |
|
||||
member: "RemoveNotification"); |
|
||||
writer.WriteString(id); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchActionInvokedAsync(Action<Exception?, (string Id, string Action, object[] Parameter)> handler, |
|
||||
bool emitOnCapturedContext = true) |
|
||||
=> WatchSignalAsync(Service.Destination, Interface, Path, "ActionInvoked", static (m, s) |
|
||||
=> ReadMessage_ssav(m, (DesktopObject)s!), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public Task SetVersionAsync(uint value) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "ssv", |
|
||||
member: "Set"); |
|
||||
writer.WriteString(Interface); |
|
||||
writer.WriteString("version"); |
|
||||
writer.WriteSignature("u"); |
|
||||
writer.WriteUInt32(value); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<uint> GetVersionAsync() |
|
||||
=> Connection.CallMethodAsync(CreateGetPropertyMessage(Interface, "version"), static (m, s) |
|
||||
=> ReadMessage_v_u(m, (DesktopObject)s!), this); |
|
||||
|
|
||||
public Task<NotificationProperties> GetPropertiesAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateGetAllPropertiesMessage(Interface), static (m, _) |
|
||||
=> ReadMessage(m), this); |
|
||||
|
|
||||
static NotificationProperties ReadMessage(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return ReadProperties(ref reader); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchPropertiesChangedAsync(Action<Exception?, PropertyChanges<NotificationProperties>> handler, |
|
||||
bool emitOnCapturedContext = true) |
|
||||
{ |
|
||||
return base.WatchPropertiesChangedAsync(Interface, static (m, _) |
|
||||
=> ReadMessage(m), handler, emitOnCapturedContext); |
|
||||
|
|
||||
static PropertyChanges<NotificationProperties> ReadMessage(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
reader.ReadString(); // interface
|
|
||||
List<string> changed = new(); |
|
||||
return new PropertyChanges<NotificationProperties>(ReadProperties(ref reader, changed), changed.ToArray(), |
|
||||
ReadInvalidated(ref reader)); |
|
||||
} |
|
||||
|
|
||||
static string[] ReadInvalidated(ref Reader reader) |
|
||||
{ |
|
||||
List<string>? invalidated = null; |
|
||||
var headersEnd = reader.ReadArrayStart(DBusType.String); |
|
||||
while (reader.HasNext(headersEnd)) |
|
||||
{ |
|
||||
invalidated ??= new List<string>(); |
|
||||
var property = reader.ReadString(); |
|
||||
switch (property) |
|
||||
{ |
|
||||
case "version": |
|
||||
invalidated.Add("Version"); |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return invalidated?.ToArray() ?? Array.Empty<string>(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private static NotificationProperties ReadProperties(ref Reader reader, ICollection<string>? changedList = null) |
|
||||
{ |
|
||||
var props = new NotificationProperties(); |
|
||||
var headersEnd = reader.ReadArrayStart(DBusType.Struct); |
|
||||
while (reader.HasNext(headersEnd)) |
|
||||
{ |
|
||||
var property = reader.ReadString(); |
|
||||
switch (property) |
|
||||
{ |
|
||||
case "version": |
|
||||
reader.ReadSignature("u"); |
|
||||
props.Version = reader.ReadUInt32(); |
|
||||
changedList?.Add("Version"); |
|
||||
break; |
|
||||
default: |
|
||||
reader.ReadVariant(); |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return props; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
internal record OpenURIProperties |
|
||||
{ |
|
||||
public uint Version { get; set; } |
|
||||
} |
|
||||
|
|
||||
internal class OpenURI : DesktopObject |
|
||||
{ |
|
||||
private const string Interface = "org.freedesktop.portal.OpenURI"; |
|
||||
|
|
||||
public OpenURI(DesktopService service, ObjectPath path) : base(service, path) { } |
|
||||
|
|
||||
public Task<ObjectPath> OpenUriAsync(string parentWindow, string uri, Dictionary<string, object> options) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_o(m, (DesktopObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "ssa{sv}", |
|
||||
member: "OpenURI"); |
|
||||
writer.WriteString(parentWindow); |
|
||||
writer.WriteString(uri); |
|
||||
writer.WriteDictionary(options); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<ObjectPath> OpenFileAsync(string parentWindow, SafeHandle fd, Dictionary<string, object> options) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_o(m, (DesktopObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "sha{sv}", |
|
||||
member: "OpenFile"); |
|
||||
writer.WriteString(parentWindow); |
|
||||
writer.WriteHandle(fd); |
|
||||
writer.WriteDictionary(options); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<ObjectPath> OpenDirectoryAsync(string parentWindow, SafeHandle fd, Dictionary<string, object> options) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_o(m, (DesktopObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "sha{sv}", |
|
||||
member: "OpenDirectory"); |
|
||||
writer.WriteString(parentWindow); |
|
||||
writer.WriteHandle(fd); |
|
||||
writer.WriteDictionary(options); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetVersionAsync(uint value) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "ssv", |
|
||||
member: "Set"); |
|
||||
writer.WriteString(Interface); |
|
||||
writer.WriteString("version"); |
|
||||
writer.WriteSignature("u"); |
|
||||
writer.WriteUInt32(value); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<uint> GetVersionAsync() |
|
||||
=> Connection.CallMethodAsync(CreateGetPropertyMessage(Interface, "version"), static (m, s) |
|
||||
=> ReadMessage_v_u(m, (DesktopObject)s!), this); |
|
||||
|
|
||||
public Task<OpenURIProperties> GetPropertiesAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateGetAllPropertiesMessage(Interface), static (m, _) |
|
||||
=> ReadMessage(m), this); |
|
||||
|
|
||||
static OpenURIProperties ReadMessage(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return ReadProperties(ref reader); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchPropertiesChangedAsync(Action<Exception?, PropertyChanges<OpenURIProperties>> handler, |
|
||||
bool emitOnCapturedContext = true) |
|
||||
{ |
|
||||
return base.WatchPropertiesChangedAsync(Interface, static (m, _) |
|
||||
=> ReadMessage(m), handler, emitOnCapturedContext); |
|
||||
|
|
||||
static PropertyChanges<OpenURIProperties> ReadMessage(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
reader.ReadString(); // interface
|
|
||||
List<string> changed = new(); |
|
||||
return new PropertyChanges<OpenURIProperties>(ReadProperties(ref reader, changed), changed.ToArray(), ReadInvalidated(ref reader)); |
|
||||
} |
|
||||
|
|
||||
static string[] ReadInvalidated(ref Reader reader) |
|
||||
{ |
|
||||
List<string>? invalidated = null; |
|
||||
var headersEnd = reader.ReadArrayStart(DBusType.String); |
|
||||
while (reader.HasNext(headersEnd)) |
|
||||
{ |
|
||||
invalidated ??= new List<string>(); |
|
||||
var property = reader.ReadString(); |
|
||||
switch (property) |
|
||||
{ |
|
||||
case "version": |
|
||||
invalidated.Add("Version"); |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return invalidated?.ToArray() ?? Array.Empty<string>(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private static OpenURIProperties ReadProperties(ref Reader reader, ICollection<string>? changedList = null) |
|
||||
{ |
|
||||
var props = new OpenURIProperties(); |
|
||||
var headersEnd = reader.ReadArrayStart(DBusType.Struct); |
|
||||
while (reader.HasNext(headersEnd)) |
|
||||
{ |
|
||||
var property = reader.ReadString(); |
|
||||
switch (property) |
|
||||
{ |
|
||||
case "version": |
|
||||
reader.ReadSignature("u"); |
|
||||
props.Version = reader.ReadUInt32(); |
|
||||
changedList?.Add("Version"); |
|
||||
break; |
|
||||
default: |
|
||||
reader.ReadVariant(); |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return props; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
internal record DynamicLauncherProperties |
|
||||
{ |
|
||||
public uint SupportedLauncherTypes { get; set; } |
|
||||
public uint Version { get; set; } |
|
||||
} |
|
||||
|
|
||||
internal class DynamicLauncher : DesktopObject |
|
||||
{ |
|
||||
private const string Interface = "org.freedesktop.portal.DynamicLauncher"; |
|
||||
|
|
||||
public DynamicLauncher(DesktopService service, ObjectPath path) : base(service, path) { } |
|
||||
|
|
||||
public Task InstallAsync(string token, string desktopFileId, string desktopEntry, Dictionary<string, object> options) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "sssa{sv}", |
|
||||
member: "Install"); |
|
||||
writer.WriteString(token); |
|
||||
writer.WriteString(desktopFileId); |
|
||||
writer.WriteString(desktopEntry); |
|
||||
writer.WriteDictionary(options); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<ObjectPath> PrepareInstallAsync(string parentWindow, string name, object iconV, Dictionary<string, object> options) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_o(m, (DesktopObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "ssva{sv}", |
|
||||
member: "PrepareInstall"); |
|
||||
writer.WriteString(parentWindow); |
|
||||
writer.WriteString(name); |
|
||||
writer.WriteVariant(iconV); |
|
||||
writer.WriteDictionary(options); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<string> RequestInstallTokenAsync(string name, object iconV, Dictionary<string, object> options) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) |
|
||||
=> ReadMessage_s(m, (DesktopObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "sva{sv}", |
|
||||
member: "RequestInstallToken"); |
|
||||
writer.WriteString(name); |
|
||||
writer.WriteVariant(iconV); |
|
||||
writer.WriteDictionary(options); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task UninstallAsync(string desktopFileId, Dictionary<string, object> options) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "sa{sv}", |
|
||||
member: "Uninstall"); |
|
||||
writer.WriteString(desktopFileId); |
|
||||
writer.WriteDictionary(options); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<string> GetDesktopEntryAsync(string desktopFileId) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) |
|
||||
=> ReadMessage_s(m, (DesktopObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "s", |
|
||||
member: "GetDesktopEntry"); |
|
||||
writer.WriteString(desktopFileId); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<(object IconV, string IconFormat, uint IconSize)> GetIconAsync(string desktopFileId) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) |
|
||||
=> ReadMessage_vsu(m, (DesktopObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "s", |
|
||||
member: "GetIcon"); |
|
||||
writer.WriteString(desktopFileId); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task LaunchAsync(string desktopFileId, Dictionary<string, object> options) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "sa{sv}", |
|
||||
member: "Launch"); |
|
||||
writer.WriteString(desktopFileId); |
|
||||
writer.WriteDictionary(options); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetSupportedLauncherTypesAsync(uint value) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "ssv", |
|
||||
member: "Set"); |
|
||||
writer.WriteString(Interface); |
|
||||
writer.WriteString("SupportedLauncherTypes"); |
|
||||
writer.WriteSignature("u"); |
|
||||
writer.WriteUInt32(value); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetVersionAsync(uint value) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "ssv", |
|
||||
member: "Set"); |
|
||||
writer.WriteString(Interface); |
|
||||
writer.WriteString("version"); |
|
||||
writer.WriteSignature("u"); |
|
||||
writer.WriteUInt32(value); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<uint> GetSupportedLauncherTypesAsync() |
|
||||
=> Connection.CallMethodAsync(CreateGetPropertyMessage(Interface, "SupportedLauncherTypes"), static (m, s) |
|
||||
=> ReadMessage_v_u(m, (DesktopObject)s!), this); |
|
||||
|
|
||||
public Task<uint> GetVersionAsync() |
|
||||
=> Connection.CallMethodAsync(CreateGetPropertyMessage(Interface, "version"), static (m, s) |
|
||||
=> ReadMessage_v_u(m, (DesktopObject)s!), this); |
|
||||
|
|
||||
public Task<DynamicLauncherProperties> GetPropertiesAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateGetAllPropertiesMessage(Interface), static (m, _) |
|
||||
=> ReadMessage(m), this); |
|
||||
|
|
||||
static DynamicLauncherProperties ReadMessage(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return ReadProperties(ref reader); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchPropertiesChangedAsync(Action<Exception?, PropertyChanges<DynamicLauncherProperties>> handler, |
|
||||
bool emitOnCapturedContext = true) |
|
||||
{ |
|
||||
return base.WatchPropertiesChangedAsync(Interface, static (m, _) |
|
||||
=> ReadMessage(m), handler, |
|
||||
emitOnCapturedContext); |
|
||||
|
|
||||
static PropertyChanges<DynamicLauncherProperties> ReadMessage(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
reader.ReadString(); // interface
|
|
||||
List<string> changed = new(); |
|
||||
return new PropertyChanges<DynamicLauncherProperties>(ReadProperties(ref reader, changed), changed.ToArray(), |
|
||||
ReadInvalidated(ref reader)); |
|
||||
} |
|
||||
|
|
||||
static string[] ReadInvalidated(ref Reader reader) |
|
||||
{ |
|
||||
List<string>? invalidated = null; |
|
||||
var headersEnd = reader.ReadArrayStart(DBusType.String); |
|
||||
while (reader.HasNext(headersEnd)) |
|
||||
{ |
|
||||
invalidated ??= new List<string>(); |
|
||||
var property = reader.ReadString(); |
|
||||
switch (property) |
|
||||
{ |
|
||||
case "SupportedLauncherTypes": |
|
||||
invalidated.Add("SupportedLauncherTypes"); |
|
||||
break; |
|
||||
case "version": |
|
||||
invalidated.Add("Version"); |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return invalidated?.ToArray() ?? Array.Empty<string>(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private static DynamicLauncherProperties ReadProperties(ref Reader reader, ICollection<string>? changedList = null) |
|
||||
{ |
|
||||
var props = new DynamicLauncherProperties(); |
|
||||
var headersEnd = reader.ReadArrayStart(DBusType.Struct); |
|
||||
while (reader.HasNext(headersEnd)) |
|
||||
{ |
|
||||
var property = reader.ReadString(); |
|
||||
switch (property) |
|
||||
{ |
|
||||
case "SupportedLauncherTypes": |
|
||||
reader.ReadSignature("u"); |
|
||||
props.SupportedLauncherTypes = reader.ReadUInt32(); |
|
||||
changedList?.Add("SupportedLauncherTypes"); |
|
||||
break; |
|
||||
case "version": |
|
||||
reader.ReadSignature("u"); |
|
||||
props.Version = reader.ReadUInt32(); |
|
||||
changedList?.Add("Version"); |
|
||||
break; |
|
||||
default: |
|
||||
reader.ReadVariant(); |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return props; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
internal record FileChooserProperties |
|
||||
{ |
|
||||
public uint Version { get; set; } |
|
||||
} |
|
||||
|
|
||||
internal class FileChooser : DesktopObject |
|
||||
{ |
|
||||
private const string Interface = "org.freedesktop.portal.FileChooser"; |
|
||||
|
|
||||
public FileChooser(DesktopService service, ObjectPath path) : base(service, path) { } |
|
||||
|
|
||||
public Task<ObjectPath> OpenFileAsync(string parentWindow, string title, Dictionary<string, object> options) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_o(m, (DesktopObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "ssa{sv}", |
|
||||
member: "OpenFile"); |
|
||||
writer.WriteString(parentWindow); |
|
||||
writer.WriteString(title); |
|
||||
writer.WriteDictionary(options); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<ObjectPath> SaveFileAsync(string parentWindow, string title, Dictionary<string, object> options) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_o(m, (DesktopObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "ssa{sv}", |
|
||||
member: "SaveFile"); |
|
||||
writer.WriteString(parentWindow); |
|
||||
writer.WriteString(title); |
|
||||
writer.WriteDictionary(options); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<ObjectPath> SaveFilesAsync(string parentWindow, string title, Dictionary<string, object> options) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage(), static (m, s) => ReadMessage_o(m, (DesktopObject)s!), this); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "ssa{sv}", |
|
||||
member: "SaveFiles"); |
|
||||
writer.WriteString(parentWindow); |
|
||||
writer.WriteString(title); |
|
||||
writer.WriteDictionary(options); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetVersionAsync(uint value) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "ssv", |
|
||||
member: "Set"); |
|
||||
writer.WriteString(Interface); |
|
||||
writer.WriteString("version"); |
|
||||
writer.WriteSignature("u"); |
|
||||
writer.WriteUInt32(value); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<uint> GetVersionAsync() |
|
||||
=> Connection.CallMethodAsync(CreateGetPropertyMessage(Interface, "version"), static (m, s) |
|
||||
=> ReadMessage_v_u(m, (DesktopObject)s!), this); |
|
||||
|
|
||||
public Task<FileChooserProperties> GetPropertiesAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateGetAllPropertiesMessage(Interface), static (m, _) |
|
||||
=> ReadMessage(m), this); |
|
||||
|
|
||||
static FileChooserProperties ReadMessage(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return ReadProperties(ref reader); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchPropertiesChangedAsync(Action<Exception?, PropertyChanges<FileChooserProperties>> handler, |
|
||||
bool emitOnCapturedContext = true) |
|
||||
{ |
|
||||
return base.WatchPropertiesChangedAsync(Interface, static (m, _) |
|
||||
=> ReadMessage(m), handler, emitOnCapturedContext); |
|
||||
|
|
||||
static PropertyChanges<FileChooserProperties> ReadMessage(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
reader.ReadString(); // interface
|
|
||||
List<string> changed = new(); |
|
||||
return new PropertyChanges<FileChooserProperties>(ReadProperties(ref reader, changed), changed.ToArray(), |
|
||||
ReadInvalidated(ref reader)); |
|
||||
} |
|
||||
|
|
||||
static string[] ReadInvalidated(ref Reader reader) |
|
||||
{ |
|
||||
List<string>? invalidated = null; |
|
||||
var headersEnd = reader.ReadArrayStart(DBusType.String); |
|
||||
while (reader.HasNext(headersEnd)) |
|
||||
{ |
|
||||
invalidated ??= new List<string>(); |
|
||||
var property = reader.ReadString(); |
|
||||
switch (property) |
|
||||
{ |
|
||||
case "version": |
|
||||
invalidated.Add("Version"); |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return invalidated?.ToArray() ?? Array.Empty<string>(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private static FileChooserProperties ReadProperties(ref Reader reader, ICollection<string>? changedList = null) |
|
||||
{ |
|
||||
var props = new FileChooserProperties(); |
|
||||
var headersEnd = reader.ReadArrayStart(DBusType.Struct); |
|
||||
while (reader.HasNext(headersEnd)) |
|
||||
{ |
|
||||
var property = reader.ReadString(); |
|
||||
switch (property) |
|
||||
{ |
|
||||
case "version": |
|
||||
reader.ReadSignature("u"); |
|
||||
props.Version = reader.ReadUInt32(); |
|
||||
changedList?.Add("Version"); |
|
||||
break; |
|
||||
default: |
|
||||
reader.ReadVariant(); |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return props; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
internal class Request : DesktopObject |
|
||||
{ |
|
||||
private const string Interface = "org.freedesktop.portal.Request"; |
|
||||
|
|
||||
public Request(DesktopService service, ObjectPath path) : base(service, path) { } |
|
||||
|
|
||||
public Task CloseAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
"Close"); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchResponseAsync(Action<Exception?, (uint response, IDictionary<string, object> results)> handler, bool emitOnCapturedContext = true) |
|
||||
=> WatchSignalAsync(Service.Destination, Interface, Path, "Response", |
|
||||
static (m, s) => ReadMessage_uaesv(m, (DesktopObject)s!), handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
internal class DesktopService |
|
||||
{ |
|
||||
public DesktopService(Connection connection, string destination) |
|
||||
=> (Connection, Destination) = (connection, destination); |
|
||||
|
|
||||
public Connection Connection { get; } |
|
||||
public string Destination { get; } |
|
||||
public Notification CreateNotification(string path) => new(this, path); |
|
||||
public OpenURI CreateOpenUri(string path) => new(this, path); |
|
||||
public DynamicLauncher CreateDynamicLauncher(string path) => new(this, path); |
|
||||
public FileChooser CreateFileChooser(string path) => new(this, path); |
|
||||
public Request CreateRequest(string path) => new(this, path); |
|
||||
} |
|
||||
|
|
||||
internal class DesktopObject |
|
||||
{ |
|
||||
protected DesktopObject(DesktopService service, ObjectPath path) |
|
||||
=> (Service, Path) = (service, path); |
|
||||
|
|
||||
protected DesktopService Service { get; } |
|
||||
protected ObjectPath Path { get; } |
|
||||
protected Connection Connection => Service.Connection; |
|
||||
|
|
||||
protected MessageBuffer CreateGetPropertyMessage(string @interface, string property) |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "ss", |
|
||||
member: "Get"); |
|
||||
writer.WriteString(@interface); |
|
||||
writer.WriteString(property); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
|
|
||||
protected MessageBuffer CreateGetAllPropertiesMessage(string @interface) |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "s", |
|
||||
member: "GetAll"); |
|
||||
writer.WriteString(@interface); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
|
|
||||
protected ValueTask<IDisposable> WatchPropertiesChangedAsync<TProperties>(string @interface, |
|
||||
MessageValueReader<PropertyChanges<TProperties>> reader, Action<Exception?, PropertyChanges<TProperties>> handler, |
|
||||
bool emitOnCapturedContext) |
|
||||
{ |
|
||||
var rule = new MatchRule |
|
||||
{ |
|
||||
Type = MessageType.Signal, |
|
||||
Sender = Service.Destination, |
|
||||
Path = Path, |
|
||||
Interface = "org.freedesktop.DBus.Properties", |
|
||||
Member = "PropertiesChanged", |
|
||||
Arg0 = @interface |
|
||||
}; |
|
||||
return Connection.AddMatchAsync(rule, reader, static (ex, changes, _, hs) |
|
||||
=> ((Action<Exception?, PropertyChanges<TProperties>>)hs!).Invoke(ex, changes), this, handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
protected ValueTask<IDisposable> WatchSignalAsync<TArg>(string sender, string @interface, ObjectPath path, string signal, |
|
||||
MessageValueReader<TArg> reader, Action<Exception?, TArg> handler, bool emitOnCapturedContext) |
|
||||
{ |
|
||||
var rule = new MatchRule |
|
||||
{ |
|
||||
Type = MessageType.Signal, |
|
||||
Sender = sender, |
|
||||
Path = path, |
|
||||
Member = signal, |
|
||||
Interface = @interface |
|
||||
}; |
|
||||
return Connection.AddMatchAsync(rule, reader, static (ex, arg, _, hs) => |
|
||||
((Action<Exception?, TArg>)hs!).Invoke(ex, arg), this, handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
protected static ObjectPath ReadMessage_o(Message message, DesktopObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return reader.ReadObjectPath(); |
|
||||
} |
|
||||
|
|
||||
protected static uint ReadMessage_v_u(Message message, DesktopObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
reader.ReadSignature("u"); |
|
||||
return reader.ReadUInt32(); |
|
||||
} |
|
||||
|
|
||||
protected static (string, string, object[]) ReadMessage_ssav(Message message, DesktopObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
var arg0 = reader.ReadString(); |
|
||||
var arg1 = reader.ReadString(); |
|
||||
var arg2 = reader.ReadArray<object>(); |
|
||||
return (arg0, arg1, arg2); |
|
||||
} |
|
||||
|
|
||||
protected static (uint, Dictionary<string, object>) ReadMessage_uaesv(Message message, DesktopObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
var arg0 = reader.ReadUInt32(); |
|
||||
var arg1 = reader.ReadDictionary<string, object>(); |
|
||||
return (arg0, arg1); |
|
||||
} |
|
||||
|
|
||||
protected static string ReadMessage_s(Message message, DesktopObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return reader.ReadString(); |
|
||||
} |
|
||||
|
|
||||
protected static (object, string, uint) ReadMessage_vsu(Message message, DesktopObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
var arg0 = reader.ReadVariant(); |
|
||||
var arg1 = reader.ReadString(); |
|
||||
var arg2 = reader.ReadUInt32(); |
|
||||
return (arg0, arg1, arg2); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
internal class PropertyChanges<TProperties> |
|
||||
{ |
|
||||
public PropertyChanges(TProperties properties, string[] invalidated, string[] changed) |
|
||||
=> (Properties, Invalidated, Changed) = (properties, invalidated, changed); |
|
||||
|
|
||||
public TProperties Properties { get; } |
|
||||
public string[] Invalidated { get; } |
|
||||
public string[] Changed { get; } |
|
||||
public bool HasChanged(string property) => Array.IndexOf(Changed, property) != -1; |
|
||||
public bool IsInvalidated(string property) => Array.IndexOf(Invalidated, property) != -1; |
|
||||
} |
|
||||
} |
|
||||
@ -1,350 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Threading.Tasks; |
|
||||
using Tmds.DBus.Protocol; |
|
||||
|
|
||||
namespace Avalonia.FreeDesktop |
|
||||
{ |
|
||||
internal record StatusNotifierWatcherProperties |
|
||||
{ |
|
||||
public string[] RegisteredStatusNotifierItems { get; set; } = default!; |
|
||||
public bool IsStatusNotifierHostRegistered { get; set; } |
|
||||
public int ProtocolVersion { get; set; } |
|
||||
} |
|
||||
|
|
||||
internal class StatusNotifierWatcher : StatusNotifierWatcherObject |
|
||||
{ |
|
||||
private const string Interface = "org.kde.StatusNotifierWatcher"; |
|
||||
|
|
||||
public StatusNotifierWatcher(StatusNotifierWatcherService service, ObjectPath path) : base(service, path) { } |
|
||||
|
|
||||
public Task RegisterStatusNotifierItemAsync(string service) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "s", |
|
||||
member: "RegisterStatusNotifierItem"); |
|
||||
writer.WriteString(service); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task RegisterStatusNotifierHostAsync(string service) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
Interface, |
|
||||
signature: "s", |
|
||||
member: "RegisterStatusNotifierHost"); |
|
||||
writer.WriteString(service); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchStatusNotifierItemRegisteredAsync(Action<Exception?, string> handler, bool emitOnCapturedContext = true) => |
|
||||
WatchSignalAsync(Service.Destination, Interface, Path, "StatusNotifierItemRegistered", static (m, s) => |
|
||||
ReadMessage_s(m, (StatusNotifierWatcherObject)s!), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchStatusNotifierItemUnregisteredAsync(Action<Exception?, string> handler, bool emitOnCapturedContext = true) |
|
||||
=> WatchSignalAsync(Service.Destination, Interface, Path, "StatusNotifierItemUnregistered", static (m, s) |
|
||||
=> ReadMessage_s(m, (StatusNotifierWatcherObject)s!), handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchStatusNotifierHostRegisteredAsync(Action<Exception?> handler, bool emitOnCapturedContext = true) => |
|
||||
WatchSignalAsync(Service.Destination, Interface, Path, "StatusNotifierHostRegistered", handler, emitOnCapturedContext); |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchStatusNotifierHostUnregisteredAsync(Action<Exception?> handler, bool emitOnCapturedContext = true) => |
|
||||
WatchSignalAsync(Service.Destination, Interface, Path, "StatusNotifierHostUnregistered", handler, emitOnCapturedContext); |
|
||||
|
|
||||
public Task SetRegisteredStatusNotifierItemsAsync(string[] value) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "ssv", |
|
||||
member: "Set"); |
|
||||
writer.WriteString(Interface); |
|
||||
writer.WriteString("RegisteredStatusNotifierItems"); |
|
||||
writer.WriteSignature("as"); |
|
||||
writer.WriteArray(value); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetIsStatusNotifierHostRegisteredAsync(bool value) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "ssv", |
|
||||
member: "Set"); |
|
||||
writer.WriteString(Interface); |
|
||||
writer.WriteString("IsStatusNotifierHostRegistered"); |
|
||||
writer.WriteSignature("b"); |
|
||||
writer.WriteBool(value); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task SetProtocolVersionAsync(int value) |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateMessage()); |
|
||||
|
|
||||
MessageBuffer CreateMessage() |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "ssv", |
|
||||
member: "Set"); |
|
||||
writer.WriteString(Interface); |
|
||||
writer.WriteString("ProtocolVersion"); |
|
||||
writer.WriteSignature("i"); |
|
||||
writer.WriteInt32(value); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public Task<string[]> GetRegisteredStatusNotifierItemsAsync() => |
|
||||
Connection.CallMethodAsync(CreateGetPropertyMessage(Interface, "RegisteredStatusNotifierItems"), static (m, s) |
|
||||
=> ReadMessage_v_as(m, (StatusNotifierWatcherObject)s!), this); |
|
||||
|
|
||||
public Task<bool> GetIsStatusNotifierHostRegisteredAsync() => |
|
||||
Connection.CallMethodAsync(CreateGetPropertyMessage(Interface, "IsStatusNotifierHostRegistered"), static (m, s) => |
|
||||
ReadMessage_v_b(m, (StatusNotifierWatcherObject)s!), this); |
|
||||
|
|
||||
public Task<int> GetProtocolVersionAsync() => |
|
||||
Connection.CallMethodAsync(CreateGetPropertyMessage(Interface, "ProtocolVersion"), static (m, s) |
|
||||
=> ReadMessage_v_i(m, (StatusNotifierWatcherObject)s!), this); |
|
||||
|
|
||||
public Task<StatusNotifierWatcherProperties> GetPropertiesAsync() |
|
||||
{ |
|
||||
return Connection.CallMethodAsync(CreateGetAllPropertiesMessage(Interface), static (m, _) |
|
||||
=> ReadMessage(m), this); |
|
||||
|
|
||||
static StatusNotifierWatcherProperties ReadMessage(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return ReadProperties(ref reader); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public ValueTask<IDisposable> WatchPropertiesChangedAsync(Action<Exception?, PropertyChanges<StatusNotifierWatcherProperties>> handler, bool emitOnCapturedContext = true) |
|
||||
{ |
|
||||
return base.WatchPropertiesChangedAsync(Interface, static (m, _) => ReadMessage(m), handler, emitOnCapturedContext); |
|
||||
|
|
||||
static PropertyChanges<StatusNotifierWatcherProperties> ReadMessage(Message message) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
reader.ReadString(); // interface
|
|
||||
List<string> changed = new(); |
|
||||
return new PropertyChanges<StatusNotifierWatcherProperties>(ReadProperties(ref reader, changed), changed.ToArray(), |
|
||||
ReadInvalidated(ref reader)); |
|
||||
} |
|
||||
|
|
||||
static string[] ReadInvalidated(ref Reader reader) |
|
||||
{ |
|
||||
List<string>? invalidated = null; |
|
||||
var headersEnd = reader.ReadArrayStart(DBusType.String); |
|
||||
while (reader.HasNext(headersEnd)) |
|
||||
{ |
|
||||
invalidated ??= new List<string>(); |
|
||||
var property = reader.ReadString(); |
|
||||
switch (property) |
|
||||
{ |
|
||||
case "RegisteredStatusNotifierItems": |
|
||||
invalidated.Add("RegisteredStatusNotifierItems"); |
|
||||
break; |
|
||||
case "IsStatusNotifierHostRegistered": |
|
||||
invalidated.Add("IsStatusNotifierHostRegistered"); |
|
||||
break; |
|
||||
case "ProtocolVersion": |
|
||||
invalidated.Add("ProtocolVersion"); |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return invalidated?.ToArray() ?? Array.Empty<string>(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private static StatusNotifierWatcherProperties ReadProperties(ref Reader reader, ICollection<string>? changedList = null) |
|
||||
{ |
|
||||
var props = new StatusNotifierWatcherProperties(); |
|
||||
var headersEnd = reader.ReadArrayStart(DBusType.Struct); |
|
||||
while (reader.HasNext(headersEnd)) |
|
||||
{ |
|
||||
var property = reader.ReadString(); |
|
||||
switch (property) |
|
||||
{ |
|
||||
case "RegisteredStatusNotifierItems": |
|
||||
reader.ReadSignature("as"); |
|
||||
props.RegisteredStatusNotifierItems = reader.ReadArray<string>(); |
|
||||
changedList?.Add("RegisteredStatusNotifierItems"); |
|
||||
break; |
|
||||
case "IsStatusNotifierHostRegistered": |
|
||||
reader.ReadSignature("b"); |
|
||||
props.IsStatusNotifierHostRegistered = reader.ReadBool(); |
|
||||
changedList?.Add("IsStatusNotifierHostRegistered"); |
|
||||
break; |
|
||||
case "ProtocolVersion": |
|
||||
reader.ReadSignature("i"); |
|
||||
props.ProtocolVersion = reader.ReadInt32(); |
|
||||
changedList?.Add("ProtocolVersion"); |
|
||||
break; |
|
||||
default: |
|
||||
reader.ReadVariant(); |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return props; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
internal class StatusNotifierWatcherService |
|
||||
{ |
|
||||
public StatusNotifierWatcherService(Connection connection, string destination) => (Connection, Destination) = (connection, destination); |
|
||||
|
|
||||
public Connection Connection { get; } |
|
||||
public string Destination { get; } |
|
||||
|
|
||||
public StatusNotifierWatcher CreateStatusNotifierWatcher(string path) => new(this, path); |
|
||||
} |
|
||||
|
|
||||
internal class StatusNotifierWatcherObject |
|
||||
{ |
|
||||
protected StatusNotifierWatcherObject(StatusNotifierWatcherService service, ObjectPath path) |
|
||||
{ |
|
||||
(Service, Path) = (service, path); |
|
||||
} |
|
||||
|
|
||||
protected StatusNotifierWatcherService Service { get; } |
|
||||
protected ObjectPath Path { get; } |
|
||||
protected Connection Connection => Service.Connection; |
|
||||
|
|
||||
protected MessageBuffer CreateGetPropertyMessage(string @interface, string property) |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "ss", |
|
||||
member: "Get"); |
|
||||
writer.WriteString(@interface); |
|
||||
writer.WriteString(property); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
|
|
||||
protected MessageBuffer CreateGetAllPropertiesMessage(string @interface) |
|
||||
{ |
|
||||
using var writer = Connection.GetMessageWriter(); |
|
||||
writer.WriteMethodCallHeader( |
|
||||
Service.Destination, |
|
||||
Path, |
|
||||
"org.freedesktop.DBus.Properties", |
|
||||
signature: "s", |
|
||||
member: "GetAll"); |
|
||||
writer.WriteString(@interface); |
|
||||
return writer.CreateMessage(); |
|
||||
} |
|
||||
|
|
||||
protected ValueTask<IDisposable> WatchPropertiesChangedAsync<TProperties>(string @interface, MessageValueReader<PropertyChanges<TProperties>> reader, Action<Exception?, PropertyChanges<TProperties>> handler, bool emitOnCapturedContext) |
|
||||
{ |
|
||||
var rule = new MatchRule |
|
||||
{ |
|
||||
Type = MessageType.Signal, |
|
||||
Sender = Service.Destination, |
|
||||
Path = Path, |
|
||||
Interface = "org.freedesktop.DBus.Properties", |
|
||||
Member = "PropertiesChanged", |
|
||||
Arg0 = @interface |
|
||||
}; |
|
||||
return Connection.AddMatchAsync(rule, reader, static (ex, changes, _, hs) => |
|
||||
((Action<Exception?, PropertyChanges<TProperties>>)hs!).Invoke(ex, changes), this, handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
protected ValueTask<IDisposable> WatchSignalAsync<TArg>(string sender, string @interface, ObjectPath path, string signal, MessageValueReader<TArg> reader, Action<Exception?, TArg> handler, bool emitOnCapturedContext) |
|
||||
{ |
|
||||
var rule = new MatchRule |
|
||||
{ |
|
||||
Type = MessageType.Signal, |
|
||||
Sender = sender, |
|
||||
Path = path, |
|
||||
Member = signal, |
|
||||
Interface = @interface |
|
||||
}; |
|
||||
return Connection.AddMatchAsync(rule, reader, static (ex, arg, _, hs) |
|
||||
=> ((Action<Exception?, TArg>)hs!).Invoke(ex, arg), this, handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
protected ValueTask<IDisposable> WatchSignalAsync(string sender, string @interface, ObjectPath path, string signal, Action<Exception?> handler, bool emitOnCapturedContext) |
|
||||
{ |
|
||||
var rule = new MatchRule |
|
||||
{ |
|
||||
Type = MessageType.Signal, |
|
||||
Sender = sender, |
|
||||
Path = path, |
|
||||
Member = signal, |
|
||||
Interface = @interface |
|
||||
}; |
|
||||
return Connection.AddMatchAsync(rule, static (_, _) |
|
||||
=> null!, static (Exception? ex, object _, object? _, object? hs) |
|
||||
=> ((Action<Exception?>)hs!).Invoke(ex), this, handler, emitOnCapturedContext); |
|
||||
} |
|
||||
|
|
||||
protected static string ReadMessage_s(Message message, StatusNotifierWatcherObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
return reader.ReadString(); |
|
||||
} |
|
||||
|
|
||||
protected static string[] ReadMessage_v_as(Message message, StatusNotifierWatcherObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
reader.ReadSignature("as"); |
|
||||
return reader.ReadArray<string>(); |
|
||||
} |
|
||||
|
|
||||
protected static bool ReadMessage_v_b(Message message, StatusNotifierWatcherObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
reader.ReadSignature("b"); |
|
||||
return reader.ReadBool(); |
|
||||
} |
|
||||
|
|
||||
protected static int ReadMessage_v_i(Message message, StatusNotifierWatcherObject _) |
|
||||
{ |
|
||||
var reader = message.GetBodyReader(); |
|
||||
reader.ReadSignature("i"); |
|
||||
return reader.ReadInt32(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1 @@ |
|||||
|
Subproject commit 1cf4faba30741f799a33313a2842cf70eeb6c67e |
||||
Loading…
Reference in new issue