diff --git a/river/Control.zig b/river/Control.zig index 3a4ffe1..3da1f28 100644 --- a/river/Control.zig +++ b/river/Control.zig @@ -21,6 +21,7 @@ const std = @import("std"); const c = @import("c.zig"); const command = @import("command.zig"); +const util = @import("util.zig"); const Log = @import("log.zig").Log; const Seat = @import("Seat.zig"); @@ -65,7 +66,7 @@ fn handleDisplayDestroy(wl_listener: ?*c.wl_listener, data: ?*c_void) callconv(. /// Called when a client binds our global fn bind(wl_client: ?*c.wl_client, data: ?*c_void, version: u32, id: u32) callconv(.C) void { - const self = @ptrCast(*Self, @alignCast(@alignOf(*Self), data)); + const self = util.voidCast(Self, data.?); const wl_resource = c.wl_resource_create( wl_client, &c.zriver_control_v1_interface, @@ -85,7 +86,7 @@ fn bind(wl_client: ?*c.wl_client, data: ?*c_void, version: u32, id: u32) callcon /// Remove the resource from the hash map and free all stored args fn handleResourceDestroy(wl_resource: ?*c.wl_resource) callconv(.C) void { - const self = @ptrCast(*Self, @alignCast(@alignOf(*Self), c.wl_resource_get_user_data(wl_resource))); + const self = util.voidCast(Self, c.wl_resource_get_user_data(wl_resource).?); const id = c.wl_resource_get_id(wl_resource); const list = self.args_map.remove(id).?.value; for (list.items) |arg| list.allocator.free(arg); @@ -97,7 +98,7 @@ fn destroy(wl_client: ?*c.wl_client, wl_resource: ?*c.wl_resource) callconv(.C) } fn addArgument(wl_client: ?*c.wl_client, wl_resource: ?*c.wl_resource, arg: ?[*:0]const u8) callconv(.C) void { - const self = @ptrCast(*Self, @alignCast(@alignOf(*Self), c.wl_resource_get_user_data(wl_resource))); + const self = util.voidCast(Self, c.wl_resource_get_user_data(wl_resource).?); const id = c.wl_resource_get_id(wl_resource); const allocator = self.server.allocator; @@ -119,10 +120,10 @@ fn runCommand( seat_wl_resource: ?*c.wl_resource, callback_id: u32, ) callconv(.C) void { - const self = @ptrCast(*Self, @alignCast(@alignOf(*Self), c.wl_resource_get_user_data(wl_resource))); + const self = util.voidCast(Self, c.wl_resource_get_user_data(wl_resource).?); // This can be null if the seat is inert, in which case we ignore the request const wlr_seat_client = c.wlr_seat_client_from_resource(seat_wl_resource) orelse return; - const seat = @ptrCast(*Seat, @alignCast(@alignOf(*Seat), wlr_seat_client.*.seat.*.data)); + const seat = util.voidCast(Seat, wlr_seat_client.*.seat.*.data.?); const allocator = self.server.allocator; const callback_resource = c.wl_resource_create( diff --git a/river/Cursor.zig b/river/Cursor.zig index 9eede57..b716da7 100644 --- a/river/Cursor.zig +++ b/river/Cursor.zig @@ -21,6 +21,7 @@ const build_options = @import("build_options"); const std = @import("std"); const c = @import("c.zig"); +const util = @import("util.zig"); const LayerSurface = @import("LayerSurface.zig"); const Log = @import("log.zig").Log; @@ -133,10 +134,7 @@ fn handleAxis(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { // This event is forwarded by the cursor when a pointer emits an axis event, // for example when you move the scroll wheel. const cursor = @fieldParentPtr(Self, "listen_axis", listener.?); - const event = @ptrCast( - *c.wlr_event_pointer_axis, - @alignCast(@alignOf(*c.wlr_event_pointer_axis), data), - ); + const event = util.voidCast(c.wlr_event_pointer_axis, data.?); // Notify the client with pointer focus of the axis event. c.wlr_seat_pointer_notify_axis( @@ -153,10 +151,7 @@ fn handleButton(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { // This event is forwarded by the cursor when a pointer emits a button // event. const self = @fieldParentPtr(Self, "listen_button", listener.?); - const event = @ptrCast( - *c.wlr_event_pointer_button, - @alignCast(@alignOf(*c.wlr_event_pointer_button), data), - ); + const event = util.voidCast(c.wlr_event_pointer_button, data.?); var sx: f64 = undefined; var sy: f64 = undefined; @@ -166,10 +161,7 @@ fn handleButton(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { if (c.wlr_surface_is_layer_surface(wlr_surface)) { const wlr_layer_surface = c.wlr_layer_surface_v1_from_wlr_surface(wlr_surface); if (wlr_layer_surface.*.current.keyboard_interactive) { - const layer_surface = @ptrCast( - *LayerSurface, - @alignCast(@alignOf(*LayerSurface), wlr_layer_surface.*.data), - ); + const layer_surface = util.voidCast(LayerSurface, wlr_layer_surface.*.data.?); self.seat.setFocusRaw(.{ .layer = layer_surface }); } } @@ -179,7 +171,7 @@ fn handleButton(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { if (c.wlr_surface_is_xdg_surface(wlr_surface)) { const wlr_xdg_surface = c.wlr_xdg_surface_from_wlr_surface(wlr_surface); if (wlr_xdg_surface.*.role == .WLR_XDG_SURFACE_ROLE_TOPLEVEL) { - const view = @ptrCast(*View, @alignCast(@alignOf(*View), wlr_xdg_surface.*.data)); + const view = util.voidCast(View, wlr_xdg_surface.*.data.?); self.seat.focus(view); } } @@ -211,10 +203,7 @@ fn handleMotionAbsolute(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) // so we have to warp the mouse there. There is also some hardware which // emits these events. const self = @fieldParentPtr(Self, "listen_motion_absolute", listener.?); - const event = @ptrCast( - *c.wlr_event_pointer_motion_absolute, - @alignCast(@alignOf(*c.wlr_event_pointer_motion_absolute), data), - ); + const event = util.voidCast(c.wlr_event_pointer_motion_absolute, data.?); c.wlr_cursor_warp_absolute(self.wlr_cursor, event.device, event.x, event.y); self.processMotion(event.time_msec); } @@ -223,10 +212,7 @@ fn handleMotion(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { // This event is forwarded by the cursor when a pointer emits a _relative_ // pointer motion event (i.e. a delta) const self = @fieldParentPtr(Self, "listen_motion", listener.?); - const event = @ptrCast( - *c.wlr_event_pointer_motion, - @alignCast(@alignOf(*c.wlr_event_pointer_motion), data), - ); + const event = util.voidCast(c.wlr_event_pointer_motion, data.?); // The cursor doesn't move unless we tell it to. The cursor automatically // handles constraining the motion to the output layout, as well as any // special configuration applied for the specific input device which @@ -239,10 +225,7 @@ fn handleMotion(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { fn handleRequestSetCursor(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { // This event is rasied by the seat when a client provides a cursor image const self = @fieldParentPtr(Self, "listen_request_set_cursor", listener.?); - const event = @ptrCast( - *c.wlr_seat_pointer_request_set_cursor_event, - @alignCast(@alignOf(*c.wlr_seat_pointer_request_set_cursor_event), data), - ); + const event = util.voidCast(c.wlr_seat_pointer_request_set_cursor_event, data.?); const focused_client = self.seat.wlr_seat.pointer_state.focused_client; // This can be sent by any client, so we check to make sure this one is @@ -307,10 +290,7 @@ fn surfaceAt(self: Self, lx: f64, ly: f64, sx: *f64, sy: *f64) ?*c.wlr_surface { const root = self.seat.input_manager.server.root; const wlr_output = c.wlr_output_layout_output_at(root.wlr_output_layout, lx, ly) orelse return null; - const output = @ptrCast( - *Output, - @alignCast(@alignOf(*Output), wlr_output.*.data orelse return null), - ); + const output = util.voidCast(Output, wlr_output.*.data orelse return null); // Get output-local coords from the layout coords var ox = lx; diff --git a/river/DecorationManager.zig b/river/DecorationManager.zig index 5a9abb4..0e280d1 100644 --- a/river/DecorationManager.zig +++ b/river/DecorationManager.zig @@ -20,6 +20,7 @@ const Self = @This(); const std = @import("std"); const c = @import("c.zig"); +const util = @import("util.zig"); const Decoration = @import("Decoration.zig"); const Server = @import("Server.zig"); @@ -46,10 +47,7 @@ pub fn init(self: *Self, server: *Server) !void { fn handleNewToplevelDecoration(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { const self = @fieldParentPtr(Self, "listen_new_toplevel_decoration", listener.?); - const wlr_xdg_toplevel_decoration = @ptrCast( - *c.wlr_xdg_toplevel_decoration_v1, - @alignCast(@alignOf(*c.wlr_xdg_toplevel_decoration_v1), data), - ); + const wlr_xdg_toplevel_decoration = util.voidCast(c.wlr_xdg_toplevel_decoration_v1, data.?); const node = self.decorations.allocateNode(self.server.allocator) catch unreachable; node.data.init(self, wlr_xdg_toplevel_decoration); diff --git a/river/InputManager.zig b/river/InputManager.zig index 3a95346..62acc2d 100644 --- a/river/InputManager.zig +++ b/river/InputManager.zig @@ -20,6 +20,7 @@ const Self = @This(); const std = @import("std"); const c = @import("c.zig"); +const util = @import("util.zig"); const Log = @import("log.zig").Log; const Seat = @import("Seat.zig"); @@ -137,7 +138,7 @@ fn handleInhibitDeactivate(listener: ?*c.wl_listener, data: ?*c_void) callconv(. /// This event is raised by the backend when a new input device becomes available. fn handleNewInput(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { const self = @fieldParentPtr(Self, "listen_new_input", listener.?); - const device = @ptrCast(*c.wlr_input_device, @alignCast(@alignOf(*c.wlr_input_device), data)); + const device = util.voidCast(c.wlr_input_device, data.?); // TODO: suport multiple seats if (self.seats.first) |seat_node| { diff --git a/river/Keyboard.zig b/river/Keyboard.zig index cbfd6cd..8f57370 100644 --- a/river/Keyboard.zig +++ b/river/Keyboard.zig @@ -20,6 +20,7 @@ const Self = @This(); const std = @import("std"); const c = @import("c.zig"); +const util = @import("util.zig"); const Log = @import("log.zig").Log; const Seat = @import("Seat.zig"); @@ -72,10 +73,7 @@ pub fn init(self: *Self, seat: *Seat, wlr_input_device: *c.wlr_input_device) !vo fn handleKey(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { // This event is raised when a key is pressed or released. const self = @fieldParentPtr(Self, "listen_key", listener.?); - const event = @ptrCast( - *c.wlr_event_keyboard_key, - @alignCast(@alignOf(*c.wlr_event_keyboard_key), data), - ); + const event = util.voidCast(c.wlr_event_keyboard_key, data.?); const wlr_keyboard = self.wlr_keyboard; diff --git a/river/LayerSurface.zig b/river/LayerSurface.zig index 088dd97..c33678f 100644 --- a/river/LayerSurface.zig +++ b/river/LayerSurface.zig @@ -20,6 +20,7 @@ const Self = @This(); const std = @import("std"); const c = @import("c.zig"); +const util = @import("util.zig"); const Box = @import("Box.zig"); const Log = @import("log.zig").Log; @@ -187,7 +188,7 @@ fn handleCommit(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { fn handleNewPopup(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { const self = @fieldParentPtr(Self, "listen_new_popup", listener.?); - const wlr_xdg_popup = @ptrCast(*c.wlr_xdg_popup, @alignCast(@alignOf(*c.wlr_xdg_popup), data)); + const wlr_xdg_popup = util.voidCast(c.wlr_xdg_popup, data.?); const allocator = self.output.root.server.allocator; // This will free itself on destroy diff --git a/river/OutputStatus.zig b/river/OutputStatus.zig index b08c195..563e42b 100644 --- a/river/OutputStatus.zig +++ b/river/OutputStatus.zig @@ -20,6 +20,7 @@ const Self = @This(); const std = @import("std"); const c = @import("c.zig"); +const util = @import("util.zig"); const Log = @import("log.zig").Log; const Output = @import("Output.zig"); @@ -45,7 +46,7 @@ pub fn init(self: *Self, output: *Output, wl_resource: *c.wl_resource) void { } fn handleResourceDestroy(wl_resource: ?*c.wl_resource) callconv(.C) void { - const self = @ptrCast(*Self, @alignCast(@alignOf(*Self), c.wl_resource_get_user_data(wl_resource))); + const self = util.voidCast(Self, @ptrCast(*c_void, c.wl_resource_get_user_data(wl_resource))); const node = @fieldParentPtr(std.SinglyLinkedList(Self).Node, "data", self); self.output.status_trackers.remove(node); } @@ -65,7 +66,7 @@ pub fn sendViewTags(self: Self) void { Log.Error.log("out of memory", .{}); return; }; - const ptr_u32 = @ptrCast(*u32, @alignCast(@alignOf(u32), ptr)); + const ptr_u32 = util.voidCast(u32, ptr); ptr_u32.* = node.view.current_tags; } c.zriver_output_status_v1_send_view_tags(self.wl_resource, &view_tags); diff --git a/river/Root.zig b/river/Root.zig index 601b415..806d0a5 100644 --- a/river/Root.zig +++ b/river/Root.zig @@ -21,6 +21,7 @@ const std = @import("std"); const build_options = @import("build_options"); const c = @import("c.zig"); +const util = @import("util.zig"); const Log = @import("log.zig").Log; const Output = @import("Output.zig"); @@ -175,7 +176,7 @@ fn startTransaction(self: *Self) void { } fn handleTimeout(data: ?*c_void) callconv(.C) c_int { - const self = @ptrCast(*Self, @alignCast(@alignOf(*Self), data)); + const self = util.voidCast(Self, data.?); Log.Error.log("Transaction timed out. Some imperfect frames may be shown.", .{}); diff --git a/river/Seat.zig b/river/Seat.zig index 5fc1320..40d64a9 100644 --- a/river/Seat.zig +++ b/river/Seat.zig @@ -21,6 +21,7 @@ const std = @import("std"); const c = @import("c.zig"); const command = @import("command.zig"); +const util = @import("util.zig"); const Cursor = @import("Cursor.zig"); const InputManager = @import("InputManager.zig"); @@ -328,9 +329,6 @@ fn addPointer(self: Self, device: *c.struct_wlr_input_device) void { fn handleRequestSetSelection(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { const self = @fieldParentPtr(Self, "listen_request_set_selection", listener.?); - const event = @ptrCast( - *c.wlr_seat_request_set_selection_event, - @alignCast(@alignOf(*c.wlr_seat_request_set_selection_event), data), - ); + const event = util.voidCast(c.wlr_seat_request_set_selection_event, data.?); c.wlr_seat_set_selection(self.wlr_seat, event.source, event.serial); } diff --git a/river/SeatStatus.zig b/river/SeatStatus.zig index 3f50f90..1f6b408 100644 --- a/river/SeatStatus.zig +++ b/river/SeatStatus.zig @@ -20,6 +20,7 @@ const Self = @This(); const std = @import("std"); const c = @import("c.zig"); +const util = @import("util.zig"); const Log = @import("log.zig").Log; const Seat = @import("Seat.zig"); @@ -50,7 +51,7 @@ pub fn init(self: *Self, seat: *Seat, wl_resource: *c.wl_resource) void { } fn handleResourceDestroy(wl_resource: ?*c.wl_resource) callconv(.C) void { - const self = @ptrCast(*Self, @alignCast(@alignOf(*Self), c.wl_resource_get_user_data(wl_resource))); + const self = util.voidCast(Self, c.wl_resource_get_user_data(wl_resource).?); const node = @fieldParentPtr(std.SinglyLinkedList(Self).Node, "data", self); self.seat.status_trackers.remove(node); } diff --git a/river/Server.zig b/river/Server.zig index b10918a..27eebba 100644 --- a/river/Server.zig +++ b/river/Server.zig @@ -21,6 +21,7 @@ const build_options = @import("build_options"); const std = @import("std"); const c = @import("c.zig"); +const util = @import("util.zig"); const Config = @import("Config.zig"); const Control = @import("Control.zig"); @@ -183,7 +184,7 @@ pub fn run(self: Self) void { fn handleNewOutput(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { const self = @fieldParentPtr(Self, "listen_new_output", listener.?); - const wlr_output = @ptrCast(*c.wlr_output, @alignCast(@alignOf(*c.wlr_output), data)); + const wlr_output = util.voidCast(c.wlr_output, data.?); Log.Debug.log("New output {}", .{wlr_output.name}); self.root.addOutput(wlr_output); } @@ -192,7 +193,7 @@ fn handleNewXdgSurface(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) v // This event is raised when wlr_xdg_shell receives a new xdg surface from a // client, either a toplevel (application window) or popup. const self = @fieldParentPtr(Self, "listen_new_xdg_surface", listener.?); - const wlr_xdg_surface = @ptrCast(*c.wlr_xdg_surface, @alignCast(@alignOf(*c.wlr_xdg_surface), data)); + const wlr_xdg_surface = util.voidCast(c.wlr_xdg_surface, data.?); if (wlr_xdg_surface.role == .WLR_XDG_SURFACE_ROLE_POPUP) { Log.Debug.log("New xdg_popup", .{}); @@ -210,10 +211,7 @@ fn handleNewXdgSurface(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) v /// This event is raised when the layer_shell recieves a new surface from a client. fn handleNewLayerSurface(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { const self = @fieldParentPtr(Self, "listen_new_layer_surface", listener.?); - const wlr_layer_surface = @ptrCast( - *c.wlr_layer_surface_v1, - @alignCast(@alignOf(*c.wlr_layer_surface_v1), data), - ); + const wlr_layer_surface = util.voidCast(c.wlr_layer_surface_v1, data.?); Log.Debug.log( "New layer surface: namespace {}, layer {}, anchor {}, size {}x{}, margin ({},{},{},{}), exclusive_zone {}", @@ -252,17 +250,14 @@ fn handleNewLayerSurface(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) } // The layer surface will add itself to the proper list of the output on map - const output = @ptrCast(*Output, @alignCast(@alignOf(*Output), wlr_layer_surface.output.*.data)); + const output = util.voidCast(Output, wlr_layer_surface.output.*.data.?); const node = self.allocator.create(std.TailQueue(LayerSurface).Node) catch unreachable; node.data.init(output, wlr_layer_surface); } fn handleNewXwaylandSurface(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { const self = @fieldParentPtr(Self, "listen_new_xwayland_surface", listener.?); - const wlr_xwayland_surface = @ptrCast( - *c.wlr_xwayland_surface, - @alignCast(@alignOf(*c.wlr_xwayland_surface), data), - ); + const wlr_xwayland_surface = util.voidCast(c.wlr_xwayland_surface, data.?); if (wlr_xwayland_surface.override_redirect) { Log.Debug.log("New unmanaged xwayland surface", .{}); diff --git a/river/StatusManager.zig b/river/StatusManager.zig index fb2630c..69f77fb 100644 --- a/river/StatusManager.zig +++ b/river/StatusManager.zig @@ -20,6 +20,7 @@ const Self = @This(); const std = @import("std"); const c = @import("c.zig"); +const util = @import("util.zig"); const Log = @import("log.zig").Log; const Output = @import("Output.zig"); @@ -63,7 +64,7 @@ fn handleDisplayDestroy(wl_listener: ?*c.wl_listener, data: ?*c_void) callconv(. /// Called when a client binds our global fn bind(wl_client: ?*c.wl_client, data: ?*c_void, version: u32, id: u32) callconv(.C) void { - const self = @ptrCast(*Self, @alignCast(@alignOf(*Self), data)); + const self = util.voidCast(Self, data.?); const wl_resource = c.wl_resource_create( wl_client, &c.zriver_status_manager_v1_interface, @@ -87,10 +88,10 @@ fn getRiverOutputStatus( new_id: u32, output_wl_resource: ?*c.wl_resource, ) callconv(.C) void { - const self = @ptrCast(*Self, @alignCast(@alignOf(*Self), c.wl_resource_get_user_data(wl_resource))); + const self = util.voidCast(Self, c.wl_resource_get_user_data(wl_resource).?); // This can be null if the output is inert, in which case we ignore the request const wlr_output = c.wlr_output_from_resource(output_wl_resource) orelse return; - const output = @ptrCast(*Output, @alignCast(@alignOf(*Output), wlr_output.*.data)); + const output = util.voidCast(Output, wlr_output.*.data.?); const allocator = self.server.allocator; const node = allocator.create(std.SinglyLinkedList(OutputStatus).Node) catch { @@ -120,10 +121,10 @@ fn getRiverSeatStatus( new_id: u32, seat_wl_resource: ?*c.wl_resource, ) callconv(.C) void { - const self = @ptrCast(*Self, @alignCast(@alignOf(*Self), c.wl_resource_get_user_data(wl_resource))); + const self = util.voidCast(Self, c.wl_resource_get_user_data(wl_resource).?); // This can be null if the seat is inert, in which case we ignore the request const wlr_seat_client = c.wlr_seat_client_from_resource(seat_wl_resource) orelse return; - const seat = @ptrCast(*Seat, @alignCast(@alignOf(*Seat), wlr_seat_client.*.seat.*.data)); + const seat = util.voidCast(Seat, wlr_seat_client.*.seat.*.data.?); const allocator = self.server.allocator; const node = allocator.create(std.SinglyLinkedList(SeatStatus).Node) catch { diff --git a/river/View.zig b/river/View.zig index 4f8f0bb..6d6e147 100644 --- a/river/View.zig +++ b/river/View.zig @@ -21,6 +21,7 @@ const build_options = @import("build_options"); const std = @import("std"); const c = @import("c.zig"); +const util = @import("util.zig"); const Box = @import("Box.zig"); const Log = @import("log.zig").Log; @@ -173,10 +174,7 @@ fn saveBuffersIterator( surface_y: c_int, data: ?*c_void, ) callconv(.C) void { - const saved_buffers = @ptrCast( - *std.ArrayList(SavedBuffer), - @alignCast(@alignOf(*std.ArrayList(SavedBuffer)), data), - ); + const saved_buffers = util.voidCast(std.ArrayList(SavedBuffer), data.?); if (wlr_surface) |surface| { if (c.wlr_surface_has_buffer(surface)) { saved_buffers.append(.{ diff --git a/river/XdgPopup.zig b/river/XdgPopup.zig index b4ee56c..d56b7a2 100644 --- a/river/XdgPopup.zig +++ b/river/XdgPopup.zig @@ -20,6 +20,7 @@ const Self = @This(); const std = @import("std"); const c = @import("c.zig"); +const util = @import("util.zig"); const Box = @import("Box.zig"); const Output = @import("Output.zig"); @@ -73,7 +74,7 @@ fn handleDestroy(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { /// Called when a new xdg popup is requested by the client fn handleNewPopup(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { const self = @fieldParentPtr(Self, "listen_new_popup", listener.?); - const wlr_xdg_popup = @ptrCast(*c.wlr_xdg_popup, @alignCast(@alignOf(*c.wlr_xdg_popup), data)); + const wlr_xdg_popup = util.voidCast(c.wlr_xdg_popup, data.?); const allocator = self.output.root.server.allocator; // This will free itself on destroy diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig index c76312a..f329d9a 100644 --- a/river/XdgToplevel.zig +++ b/river/XdgToplevel.zig @@ -20,6 +20,7 @@ const Self = @This(); const std = @import("std"); const c = @import("c.zig"); +const util = @import("util.zig"); const Box = @import("Box.zig"); const Log = @import("log.zig").Log; @@ -242,7 +243,7 @@ fn handleCommit(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { /// Called when a new xdg popup is requested by the client fn handleNewPopup(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { const self = @fieldParentPtr(Self, "listen_new_popup", listener.?); - const wlr_xdg_popup = @ptrCast(*c.wlr_xdg_popup, @alignCast(@alignOf(*c.wlr_xdg_popup), data)); + const wlr_xdg_popup = util.voidCast(c.wlr_xdg_popup, data.?); const allocator = self.view.output.root.server.allocator; // This will free itself on destroy diff --git a/river/XwaylandUnmanaged.zig b/river/XwaylandUnmanaged.zig index fe33e73..ca70fa8 100644 --- a/river/XwaylandUnmanaged.zig +++ b/river/XwaylandUnmanaged.zig @@ -20,6 +20,7 @@ const Self = @This(); const std = @import("std"); const c = @import("c.zig"); +const util = @import("util.zig"); const Box = @import("Box.zig"); const Log = @import("log.zig").Log; @@ -71,10 +72,7 @@ pub fn surfaceAt(self: Self, ox: f64, oy: f64, sx: *f64, sy: *f64) ?*c.wlr_surfa fn handleRequestConfigure(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { const self = @fieldParentPtr(Self, "liseten_request_configure", listener.?); - const wlr_xwayland_surface_configure_event = @ptrCast( - *c.wlr_xwayland_surface_configure_event, - @alignCast(@alignOf(*c.wlr_xwayland_surface_configure_event), data), - ); + const wlr_xwayland_surface_configure_event = util.voidCast(c.wlr_xwayland_surface_configure_event, data.?); c.wlr_xwayland_surface_configure( self.wlr_xwayland_surface, wlr_xwayland_surface_configure_event.x, diff --git a/river/render.zig b/river/render.zig index 14e8ae0..8fe41db 100644 --- a/river/render.zig +++ b/river/render.zig @@ -19,6 +19,7 @@ const build_options = @import("build_options"); const std = @import("std"); const c = @import("c.zig"); +const util = @import("util.zig"); const Box = @import("Box.zig"); const LayerSurface = @import("LayerSurface.zig"); @@ -193,7 +194,7 @@ fn renderSurfaceIterator( surface_y: c_int, data: ?*c_void, ) callconv(.C) void { - const rdata = @ptrCast(*SurfaceRenderData, @alignCast(@alignOf(SurfaceRenderData), data)); + const rdata = util.voidCast(SurfaceRenderData, data.?); renderTexture( rdata.output.*, diff --git a/river/util.zig b/river/util.zig new file mode 100644 index 0000000..c1064cb --- /dev/null +++ b/river/util.zig @@ -0,0 +1,26 @@ +// This file is part of river, a dynamic tiling wayland compositor. +// +// Copyright 2020 Isaac Freund +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +/// Take a pointer to c_void and cast it to a pointer to T. This function +/// exists to avoid having the verbosity of the required alignment casts all +/// over the code. +pub fn voidCast(comptime T: type, ptr: var) *T { + // See https://github.com/ziglang/zig/issues/5618 + if (@TypeOf(ptr) != *c_void) + @compileError("voidCast takes *c_void but " ++ @typeName(@TypeOf(ptr)) ++ " was provided"); + return @ptrCast(*T, @alignCast(@alignOf(*T), ptr)); +}