Skip to content

Commit

Permalink
feat: add some info for surfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
RossComputerGuy committed Mar 9, 2024
1 parent a03ba54 commit 551f9da
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 10 deletions.
2 changes: 2 additions & 0 deletions src/example.zig
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ pub fn main() !void {
@panic("Could not find an output");
};

std.debug.print("{}\n", .{output});

const surface = output.createSurface(.output, .{
.size = .{
.value = .{ 1024, 768 },
Expand Down
34 changes: 34 additions & 0 deletions src/phantom/display/backends/xcb/display.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const Allocator = std.mem.Allocator;
const phantom = @import("phantom");
const Output = @import("output.zig");
const xcb = @import("xcb");
const vizops = @import("vizops");
const Self = @This();

allocator: Allocator,
Expand Down Expand Up @@ -47,6 +48,39 @@ pub fn getXScreen(self: *Self) !*const xcb.xproto.SCREEN {
return error.ScreenNotFound;
}

pub fn getVisualInfo(self: *Self, depthId: u8, visualId: u32) !*const xcb.xproto.VISUALTYPE {
const xscreen = try self.getXScreen();
var depthIter = xscreen.allowedDepthsIterator();
while (depthIter.next()) |depth| {
if (depth.depth == depthId) {
var visualIter = depth.visualsIterator();
while (visualIter.next()) |visual| {
if (visual.visual_id == visualId) {
return visual;
}
}
return error.VisualNotFound;
}
}
return error.DepthNotFound;
}

inline fn getColorFormatFromVisualChannel(visual: *const xcb.xproto.VISUALTYPE, comptime field: []const u8) struct { u8, u8 } {
return .{ @ctz(@field(visual, field ++ "_mask")), @popCount(@field(visual, field ++ "_mask")) };
}

pub fn getColorFormatFromVisual(visual: *const xcb.xproto.VISUALTYPE) vizops.color.fourcc.Value {
const red = getColorFormatFromVisualChannel(visual, "red");
const green = getColorFormatFromVisualChannel(visual, "green");
const blue = getColorFormatFromVisualChannel(visual, "blue");

if (red[0] < blue[0]) {
return .{ .rgb = .{ red[1], green[1], blue[1] } };
}

return .{ .bgr = .{ blue[1], green[1], red[1] } };
}

fn impl_outputs(ctx: *anyopaque) anyerror!std.ArrayList(*phantom.display.Output) {
const self: *Self = @ptrCast(@alignCast(ctx));
var outputs = std.ArrayList(*phantom.display.Output).init(self.allocator);
Expand Down
40 changes: 32 additions & 8 deletions src/phantom/display/backends/xcb/output.zig
Original file line number Diff line number Diff line change
Expand Up @@ -40,39 +40,63 @@ fn impl_surfaces(ctx: *anyopaque) anyerror!std.ArrayList(*phantom.display.Surfac
var surfaces = std.ArrayList(*phantom.display.Surface).init(self.display.allocator);
errdefer surfaces.deinit();

const outputInfo = try xcb.randr.getOutputInfo(self.display.connection, self.id, 0).reply(self.display.connection);
const crtcInfo = try xcb.randr.getCrtcInfo(self.display.connection, outputInfo.crtc, 0).reply(self.display.connection);

const xscreen = try self.display.getXScreen();
const tree = try xcb.xproto.queryTree(self.display.connection, xscreen.root).reply(self.display.connection);
for (tree.children()) |child| {
const surf = try Surface.new(self, child);
errdefer surf.base.deinit();
try surfaces.append(&surf.base);
const geom = try xcb.xproto.getGeometry(self.display.connection, .{ .window = child }).reply(self.display.connection);

if (geom.x >= crtcInfo.x and (geom.x - @as(i16, @intCast(crtcInfo.width))) <= crtcInfo.width) {
if (geom.y >= crtcInfo.y and (geom.y - @as(i16, @intCast(crtcInfo.height))) <= crtcInfo.height) {
const surf = try Surface.new(self, child);
errdefer surf.base.deinit();
try surfaces.append(&surf.base);
}
}
}
return surfaces;
}

fn impl_create_surface(ctx: *anyopaque, kind: phantom.display.Surface.Kind, info: phantom.display.Surface.Info) anyerror!*phantom.display.Surface {
const self: *Self = @ptrCast(@alignCast(ctx));

_ = self;
_ = kind;
if (kind == .output and self.display.kind == .client) {
return error.NotSupported;
}

_ = info;
return error.NotImplemented;
}

fn impl_info(ctx: *anyopaque) anyerror!phantom.display.Output.Info {
const self: *Self = @ptrCast(@alignCast(ctx));

const xscreen = try self.display.getXScreen();

const outputInfo = try xcb.randr.getOutputInfo(self.display.connection, self.id, 0).reply(self.display.connection);
const crtcInfo = try xcb.randr.getCrtcInfo(self.display.connection, outputInfo.crtc, 0).reply(self.display.connection);

const modeInfo = blk: {
const screenRes = try xcb.randr.getScreenResources(self.display.connection, xscreen.root).reply(self.display.connection);
var modeIterator = screenRes.modesIterator();
while (modeIterator.next()) |mode| {
if (mode.id == crtcInfo.mode.value) break :blk mode;
}
return error.ModeNotFound;
};

const visual = try self.display.getVisualInfo(xscreen.root_depth, xscreen.root_visual);

return .{
.enable = true,
.enable = outputInfo.connection == 0,
.size = .{
.phys = .{ .value = .{ @floatFromInt(outputInfo.mm_width), @floatFromInt(outputInfo.mm_height) } },
.res = .{ .value = .{ crtcInfo.width, crtcInfo.height } },
.res = .{ .value = .{ modeInfo.width, modeInfo.height } },
},
.name = outputInfo.name(),
.colorFormat = .{ .rgba = @splat(8) },
.colorFormat = Display.getColorFormatFromVisual(visual),
.scale = self.scale,
};
}
Expand Down
13 changes: 11 additions & 2 deletions src/phantom/display/backends/xcb/surface.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const std = @import("std");
const phantom = @import("phantom");
const Display = @import("display.zig");
const Output = @import("output.zig");
const xcb = @import("xcb");
const Self = @This();
Expand Down Expand Up @@ -46,8 +47,16 @@ fn impl_destroy(ctx: *anyopaque) anyerror!void {

fn impl_info(ctx: *anyopaque) anyerror!phantom.display.Surface.Info {
const self: *Self = @ptrCast(@alignCast(ctx));
_ = self;
return error.NotImplemented;
const attrs = try xcb.xproto.getWindowAttributes(self.output.display.connection, self.id).reply(self.output.display.connection);
const geom = try xcb.xproto.getGeometry(self.output.display.connection, .{ .window = self.id }).reply(self.output.display.connection);

const xscreen = try self.output.display.getXScreen();
const visual = try self.output.display.getVisualInfo(xscreen.root_depth, attrs.visual);
return .{
.colorFormat = Display.getColorFormatFromVisual(visual),
.size = .{ .value = .{ geom.width, geom.height } },
.states = if (attrs.map_state == 2) &.{.mapped} else &.{},
};
}

fn impl_update_info(ctx: *anyopaque, info: phantom.display.Surface.Info, fields: []std.meta.FieldEnum(phantom.display.Surface.Info)) anyerror!void {
Expand Down

0 comments on commit 551f9da

Please sign in to comment.