aboutsummaryrefslogtreecommitdiff
path: root/src/main.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.zig')
-rw-r--r--src/main.zig51
1 files changed, 49 insertions, 2 deletions
diff --git a/src/main.zig b/src/main.zig
index 4902176..436e14d 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -6,6 +6,10 @@ const wayland = @import("wayland");
const wl = wayland.client.wl;
const xdg = wayland.client.xdg;
+const pangocairo = @import("pangocairo.zig");
+const cairo = pangocairo.cairo;
+const pango = pangocairo.pango;
+
/// Global Wayland registry context; contains pointers to the globals we expect
/// from the compositor.
const RegistryContext = struct {
@@ -22,6 +26,8 @@ const WindowBuffer = struct {
wl_buffer: *wl.Buffer,
/// Backing data slice from memory mapping for this buffer
map: []u8,
+ /// Cairo surface for painting with cairo
+ c_surface: cairo.Surface,
/// Are we being read by the compositor right now?
busy: bool = false,
};
@@ -41,6 +47,8 @@ pub const Window = struct {
buffers: [2]WindowBuffer = undefined,
/// Memory mapped for both buffers
buffers_map: []align(mem.page_size) u8 = undefined,
+ /// Pango font description for rendering our text
+ font: pango.FontDescription,
/// This window's title
title: [*:0]const u8,
/// Width in pixels
@@ -51,6 +59,8 @@ pub const Window = struct {
offset: f32 = 0.0,
/// Last frame's timestamp in ms
last_frame: u32 = 0,
+ /// Frames per second statistic
+ current_fps: f32 = 0.0,
/// Should we keep this window open?
open: bool = true,
@@ -64,10 +74,16 @@ pub const Window = struct {
.allocator = allocator,
.wl_surface = try compositor.createSurface(),
.title = title,
+ // .font = try pango.FontDescription.fromString("monospace 24"),
+ .font = try pango.FontDescription.create(),
};
win.xdg_surface = try wm_base.getXdgSurface(win.wl_surface);
win.xdg_toplevel = try win.xdg_surface.getToplevel();
+ win.font.setFamily("monospace");
+ win.font.setWeight(600);
+ win.font.setSizePt(18);
+
try win.allocBuffers();
win.xdg_surface.setListener(*Window, xdgSurfaceListener, win);
@@ -86,6 +102,7 @@ pub const Window = struct {
/// Destroy this window and all its associated resources
pub fn destroy(win: *Window) void {
win.destroyBuffers();
+ win.font.destroy();
win.xdg_toplevel.destroy();
win.xdg_surface.destroy();
win.wl_surface.destroy();
@@ -94,7 +111,8 @@ pub const Window = struct {
/// Allocate new buffers for this window
fn allocBuffers(win: *Window) !void {
- const stride = win.width * 4;
+ const c_format = cairo.Format.argb32;
+ const stride = cairo.Surface.formatStrideForWidth(c_format, win.width);
const buffer_size = stride * win.height;
const total_size = buffer_size * 2; // we need two buffers
@@ -124,12 +142,21 @@ pub const Window = struct {
const bsize: usize = @intCast(buffer_size);
buffer.busy = false;
buffer.map = win.buffers_map[bsize *% i .. bsize *% (i + 1)];
+ buffer.c_surface = try cairo.Surface.createImageForData(
+ buffer.map,
+ c_format,
+ win.width,
+ win.height,
+ stride,
+ );
buffer.wl_buffer.setListener(*WindowBuffer, bufferListener, buffer);
}
}
/// Destroy this window's buffers
fn destroyBuffers(win: *Window) void {
+ win.buffers[0].c_surface.destroy();
+ win.buffers[1].c_surface.destroy();
win.buffers[0].wl_buffer.destroy();
win.buffers[1].wl_buffer.destroy();
posix.munmap(win.buffers_map);
@@ -163,6 +190,25 @@ pub const Window = struct {
}
}
+ const layout = try pango.Layout.createForCairo(&buffer.c_surface);
+ defer layout.unref();
+ buffer.c_surface.setSourceRgba(1, 1, 1, 1);
+
+ layout.setFont(win.font);
+ layout.setText("Hello, wayland!", -1);
+ buffer.c_surface.moveTo(5, 5);
+ layout.show(&buffer.c_surface);
+
+ var fps_buf: [32]u8 = undefined;
+ const fps_output = std.fmt.bufPrintZ(
+ &fps_buf,
+ "{d} FPS",
+ .{win.current_fps},
+ ) catch unreachable;
+ layout.setText(fps_output, -1);
+ buffer.c_surface.moveTo(5, 40);
+ layout.show(&buffer.c_surface);
+
buffer.busy = true;
return buffer.wl_buffer;
}
@@ -230,8 +276,9 @@ pub const Window = struct {
if (win.last_frame != 0) {
const elapsed: f32 = @floatFromInt(done.callback_data -% win.last_frame);
win.offset -= elapsed / 1000.0 * 32.0;
+ win.current_fps = 1000.0 / elapsed;
}
- defer win.last_frame = done.callback_data;
+ win.last_frame = done.callback_data;
const wl_buffer = win.drawFrame() catch |err| {
std.debug.print("error drawing frame {}\n", .{err});