Changes
6 changed files (+235/-27)
-
-
@@ -63,6 +63,19 @@ // discoveryplac_discovery_scan_result *plac_discovery_scan(); plac_discovery_scan_result *plac_discovery_find(const char *server_id); // transport.NowPlaying typedef struct { void *__pri; const char *one_line_line1; const char *two_line_line1; const char *two_line_line2; const char *three_line_line1; const char *three_line_line2; const char *three_line_line3; } plac_transport_now_playing; plac_transport_now_playing *plac_transport_now_playing_retain(plac_transport_now_playing*); void plac_transport_now_playing_release(plac_transport_now_playing*); // transport.PlaybackState typedef enum { PLAC_TRANSPORT_PLAYBACK_LOADING = 0,
-
@@ -83,6 +96,7 @@ typedef struct {void *__pri; char *id; char *name; plac_transport_now_playing *now_playing; plac_transport_playback_state playback; uint16_t allowed_action; } plac_transport_zone;
-
-
-
@@ -81,6 +81,21 @@ }namespace Transport { [CCode ( cname = "plac_transport_now_playing", ref_function = "plac_transport_now_playing_retain", unref_function = "plac_transport_now_playing_release" )] [Compact] public class NowPlaying { public string one_line_line1; public string two_line_line1; public string? two_line_line2; public string three_line_line1; public string? three_line_line2; public string? three_line_line3; } [CCode ( cname = "plac_transport_playback_state", cprefix = "PLAC_TRANSPORT_PLAYBACK_", has_type_id = false
-
@@ -103,6 +118,7 @@ public string id;public string name; public PlaybackState playback; public uint16 allowed_action; public NowPlaying? now_playing; [CCode (cname = "plac_transport_zone_retain")] public void @ref ();
-
-
-
@@ -21,6 +21,21 @@pub const TransportService = struct { pub const id = "com.roonlabs.transport:2"; pub const NowPlaying = struct { one_line: struct { line1: []const u8, }, two_line: struct { line1: []const u8, line2: ?[]const u8 = null, }, three_line: struct { line1: []const u8, line2: ?[]const u8 = null, line3: ?[]const u8 = null, }, }; pub const PlaybackState = enum { playing, paused,
-
@@ -50,6 +65,7 @@pub const Zone = struct { zone_id: []const u8, display_name: []const u8, now_playing: ?NowPlaying = null, state: PlaybackState, is_next_allowed: bool = false, is_previous_allowed: bool = false,
-
-
-
@@ -19,6 +19,109 @@const Arc = @import("./Arc.zig"); const TransportService = @import("./services/transport.zig").TransportService; pub const NowPlaying = extern struct { const cname = "plac_transport_zone"; const allocator = std.heap.c_allocator; internal: *Internal, one_line_line1: [*:0]const u8, two_line_line1: [*:0]const u8, two_line_line2: ?[*:0]const u8, three_line_line1: [*:0]const u8, three_line_line2: ?[*:0]const u8, three_line_line3: ?[*:0]const u8, pub const Internal = struct { arc: Arc = .{}, }; pub fn make(src: *const TransportService.NowPlaying) std.mem.Allocator.Error!*NowPlaying { const one_line_line1 = try allocator.dupeZ(u8, src.one_line.line1); errdefer allocator.free(one_line_line1); const two_line_line1 = try allocator.dupeZ(u8, src.two_line.line1); errdefer allocator.free(two_line_line1); const two_line_line2 = if (src.two_line.line2) |input| try allocator.dupeZ(u8, input) else null; errdefer if (two_line_line2) |buf| allocator.free(buf); const three_line_line1 = try allocator.dupeZ(u8, src.three_line.line1); errdefer allocator.free(three_line_line1); const three_line_line2 = if (src.three_line.line2) |input| try allocator.dupeZ(u8, input) else null; errdefer if (three_line_line2) |buf| allocator.free(buf); const three_line_line3 = if (src.three_line.line3) |input| try allocator.dupeZ(u8, input) else null; errdefer if (three_line_line3) |buf| allocator.free(buf); const internal = try allocator.create(Internal); errdefer allocator.destroy(internal); internal.* = .{}; const self = try allocator.create(NowPlaying); errdefer allocator.destroy(self); self.* = .{ .internal = internal, .one_line_line1 = one_line_line1.ptr, .two_line_line1 = two_line_line1.ptr, .two_line_line2 = if (two_line_line2) |slice| slice.ptr else null, .three_line_line1 = three_line_line1, .three_line_line2 = if (three_line_line2) |slice| slice.ptr else null, .three_line_line3 = if (three_line_line3) |slice| slice.ptr else null, }; return self; } pub fn retain(ptr: ?*NowPlaying) callconv(.C) *NowPlaying { var self = ptr orelse @panic( std.fmt.comptimePrint("Received null pointer on {s}_{s}", .{ cname, @src().fn_name }), ); self.internal.arc.ref(); return self; } pub fn release(ptr: ?*NowPlaying) callconv(.C) void { var self = ptr orelse @panic( std.fmt.comptimePrint("Received null pointer on {s}_{s}", .{ cname, @src().fn_name }), ); if (self.internal.arc.unref()) { std.log.debug("Releasing {*}...", .{self}); allocator.free(std.mem.span(self.one_line_line1)); allocator.free(std.mem.span(self.two_line_line1)); if (self.two_line_line2) |line| { allocator.free(std.mem.span(line)); } allocator.free(std.mem.span(self.three_line_line1)); if (self.three_line_line2) |line| { allocator.free(std.mem.span(line)); } if (self.three_line_line3) |line| { allocator.free(std.mem.span(line)); } allocator.destroy(self.internal); allocator.destroy(self); } } pub fn export_capi() void { @export(&retain, .{ .name = std.fmt.comptimePrint("{s}_retain", .{cname}) }); @export(&release, .{ .name = std.fmt.comptimePrint("{s}_release", .{cname}) }); } }; pub const PlaybackState = enum(c_int) { loading = 0, stopped = 1,
-
@@ -42,6 +145,7 @@internal: *Internal, id: [*:0]const u8, name: [*:0]const u8, now_playing: ?*NowPlaying, playback: PlaybackState, allowed_action: Action,
-
@@ -59,6 +163,13 @@const name = try allocator.dupeZ(u8, src.display_name); errdefer allocator.free(name); const now_playing = if (src.now_playing) |*input| now_playing: { const n = try NowPlaying.make(input); break :now_playing n.retain(); } else null; errdefer if (now_playing) |n| n.release(); const internal = try allocator.create(Internal); errdefer allocator.destroy(internal);
-
@@ -87,6 +198,7 @@ .pause = src.is_pause_allowed,.play = src.is_play_allowed, .seek = src.is_seek_allowed, }, .now_playing = now_playing, }; return self;
-
@@ -107,6 +219,9 @@ );if (self.internal.arc.unref()) { std.log.debug("Releasing {*}...", .{self}); if (self.now_playing) |now_playing| { now_playing.release(); } allocator.free(self.internal.id); allocator.free(self.internal.name); allocator.destroy(self.internal);
-
-
-
@@ -25,31 +25,60 @@ <style><class name="toolbar" /> </style> <child> <object class="GtkButton" id="prev"> <property name="label">Previous</property> <property name="icon-name">skip-backward-large-symbolic</property> <property name="action-name">prev_current_zone</property> <object class="GtkBox"> <property name="orientation">vertical</property> <property name="valign">center</property> <property name="hexpand">true</property> <child> <object class="GtkLabel" id="playing_line1"> <property name="halign">start</property> <property name="label"></property> </object> </child> <child> <object class="GtkLabel" id="playing_line2"> <style> <class name="dimmed" /> <!-- ~libadwaita@1.7 --> <class name="dim-label" /> </style> <property name="halign">start</property> <property name="label"></property> </object> </child> </object> </child> <child> <object class="GtkButton" id="play"> <property name="label">Play</property> <property name="icon-name">play-large-symbolic</property> <property name="action-name">play_current_zone</property> </object> </child> <child> <object class="GtkButton" id="pause"> <property name="label">Pause</property> <property name="icon-name">pause-large-symbolic</property> <property name="action-name">pause_current_zone</property> </object> </child> <child> <object class="GtkButton" id="next"> <property name="label">Skip Next</property> <property name="icon-name">skip-forward-large-symbolic</property> <property name="action-name">next_current_zone</property> <object class="GtkBox"> <property name="orientation">horizontal</property> <child> <object class="GtkButton" id="prev"> <property name="label">Previous</property> <property name="icon-name">skip-backward-large-symbolic</property> <property name="action-name">prev_current_zone</property> </object> </child> <child> <object class="GtkButton" id="play"> <property name="label">Play</property> <property name="icon-name">play-large-symbolic</property> <property name="action-name">play_current_zone</property> </object> </child> <child> <object class="GtkButton" id="pause"> <property name="label">Pause</property> <property name="icon-name">pause-large-symbolic</property> <property name="action-name">pause_current_zone</property> </object> </child> <child> <object class="GtkButton" id="next"> <property name="label">Skip Next</property> <property name="icon-name">skip-forward-large-symbolic</property> <property name="action-name">next_current_zone</property> </object> </child> </object> </child> <child>
-
-
-
@@ -30,6 +30,12 @@ [GtkChild]private unowned Gtk.Button next; [GtkChild] private unowned Gtk.Label playing_line1; [GtkChild] private unowned Gtk.Label playing_line2; [GtkChild] private unowned Gtk.Popover zone_list_popover; [GtkChild]
-
@@ -157,12 +163,24 @@ pause.visible = false;return; } play.sensitive = (row.zone.allowed_action & Plac.Transport.ACTION_PLAY) != 0; pause.sensitive = (row.zone.allowed_action & Plac.Transport.ACTION_PAUSE) != 0; prev.sensitive = (row.zone.allowed_action & Plac.Transport.ACTION_PREV) != 0; next.sensitive = (row.zone.allowed_action & Plac.Transport.ACTION_NEXT) != 0; var zone = row.zone; play.sensitive = (zone.allowed_action & Plac.Transport.ACTION_PLAY) != 0; pause.sensitive = (zone.allowed_action & Plac.Transport.ACTION_PAUSE) != 0; prev.sensitive = (zone.allowed_action & Plac.Transport.ACTION_PREV) != 0; next.sensitive = (zone.allowed_action & Plac.Transport.ACTION_NEXT) != 0; switch (row.zone.playback) { if (zone.now_playing != null) { playing_line1.label = zone.now_playing.two_line_line1; playing_line2.label = zone.now_playing.two_line_line2 != null ? zone.now_playing.two_line_line2 : ""; } else { playing_line1.label = ""; playing_line2.label = ""; } switch (zone.playback) { case LOADING: case STOPPED: case PAUSED:
-