image / surface spanning entire output
This commit is contained in:
		
							parent
							
								
									9d234eab11
								
							
						
					
					
						commit
						cc20141b6d
					
				
							
								
								
									
										114
									
								
								main.zig
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								main.zig
									
									
									
									
									
								
							|  | @ -48,6 +48,87 @@ const Selection = struct { | |||
|     } | ||||
| }; | ||||
| 
 | ||||
| const Buffer = struct { | ||||
|     const Self = @This(); | ||||
| 
 | ||||
|     buffer: *wl.Buffer = undefined, | ||||
|     cairo: struct { | ||||
|         surface: *cairo.cairo_surface_t = undefined, | ||||
|         ctx: *cairo.cairo_t = undefined, | ||||
|     } = .{}, | ||||
|     size: Size = .{}, | ||||
|     data: []u8 = undefined, | ||||
| 
 | ||||
|     fn randomName() [13]u8 { | ||||
|         var name = [_]u8{'/', 'z', 'l', 'u','r','p','-','0','0','0','0','0','0'}; | ||||
| 
 | ||||
|         var rng = std.rand.DefaultPrng.init(@intCast(u64, std.time.milliTimestamp())); | ||||
|         for (name[7..]) |*c| { | ||||
|             c.* = rng.random().intRangeAtMost(u8, 'A', 'Z'); | ||||
|         } | ||||
| 
 | ||||
|         return name; | ||||
|     } | ||||
| 
 | ||||
|     fn init(self: *Self, shm: *wl.Shm, size: Size) !void { | ||||
|         const name = randomName(); | ||||
|         const stride = size.width * 4; | ||||
|         const len = stride * size.height; | ||||
| 
 | ||||
|         const fd = try std.os.memfd_create(&name, 0); | ||||
|         defer std.os.close(fd); | ||||
|         try std.os.ftruncate(fd, len); | ||||
| 
 | ||||
|         const data = try std.os.mmap( | ||||
|             null, | ||||
|             len, | ||||
|             std.os.PROT.READ | std.os.PROT.WRITE, | ||||
|             std.os.MAP.SHARED, | ||||
|             fd, | ||||
|             0, | ||||
|         ); | ||||
| 
 | ||||
|         const pool = try shm.createPool(fd, @intCast(i32, len)); | ||||
|         defer pool.destroy(); | ||||
| 
 | ||||
|         const buffer = try pool.createBuffer( | ||||
|             0, | ||||
|             @intCast(i32, size.width), | ||||
|             @intCast(i32, size.height), | ||||
|             @intCast(i32, stride), | ||||
|             .argb8888, | ||||
|         ); | ||||
| 
 | ||||
|         const surface = cairo.cairo_image_surface_create_for_data( | ||||
|             @ptrCast([*c]u8, data), | ||||
|             cairo.CAIRO_FORMAT_ARGB32, | ||||
|             @intCast(c_int, size.width), | ||||
|             @intCast(c_int, size.height), | ||||
|             @intCast(c_int, stride), | ||||
|         ) orelse return error.NoCairoSurface; | ||||
| 
 | ||||
|         const cairo_ctx = cairo.cairo_create(surface) orelse return error.NoCairoContext; | ||||
| 
 | ||||
|         self.* = .{ | ||||
|             .buffer = buffer, | ||||
|             .size = size, | ||||
|             .data = data, | ||||
|             .cairo = .{ | ||||
|                 .surface = surface, | ||||
|                 .ctx = cairo_ctx, | ||||
|             }, | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     fn deinit(self: *Self) void { | ||||
|         std.os.munmap(@alignCast(0x1000, self.data)); | ||||
|         self.buffer.destroy(); | ||||
| 
 | ||||
|         cairo.cairo_destroy(self.cairo.ctx); | ||||
|         cairo.cairo_surface_destroy(self.cairo.surface); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| const Box = struct { | ||||
|     const Self = @This(); | ||||
| 
 | ||||
|  | @ -301,6 +382,10 @@ const Output = struct { | |||
|         self.output.destroy(); | ||||
|     } | ||||
| 
 | ||||
|     fn commitFrame(self: *Self) void { | ||||
|         _ = self; | ||||
|     } | ||||
| 
 | ||||
|     fn xdgOutputListener(output: *zxdg.OutputV1, event: zxdg.OutputV1.Event, self: *Self) void { | ||||
|         _ = output; | ||||
| 
 | ||||
|  | @ -336,7 +421,7 @@ const Output = struct { | |||
|                 }; | ||||
| 
 | ||||
|                 layer.ackConfigure(cfg.serial); | ||||
|                 // TODO: send frame | ||||
|                 self.commitFrame(); | ||||
|             }, | ||||
|             .closed => { | ||||
|                 self.state.removeOutput(self); | ||||
|  | @ -832,34 +917,21 @@ const State = struct { | |||
|             var it = self.outputs.iterator(.forward); | ||||
|             if (it.next()) |link| { | ||||
|                 const output = link.get(); | ||||
|                 const os = std.os; | ||||
| 
 | ||||
|                 const buffer = blk: { | ||||
|                     const width = 128; | ||||
|                     const height = 128; | ||||
|                     const stride = width * 4; | ||||
|                     const size = stride * height; | ||||
|                 var buffer: Buffer = undefined; | ||||
|                 const width = output.size.width * @intCast(u32, output.scale); | ||||
|                 const height = output.size.height * @intCast(u32, output.scale); | ||||
|                 try buffer.init(self.shm, .{.width = width, .height = height}); | ||||
|                 std.mem.copy(u8, buffer.data, @embedFile("cat.bgra")); | ||||
| 
 | ||||
|                     const fd = try os.memfd_create("hello-zig-wayland", 0); | ||||
|                     try os.ftruncate(fd, size); | ||||
|                     const data = try os.mmap(null, size, os.PROT.READ | os.PROT.WRITE, os.MAP.SHARED, fd, 0); | ||||
|                     std.mem.copy(u8, data, @embedFile("cat.bgra")); | ||||
| 
 | ||||
|                     const pool = try self.shm.createPool(fd, size); | ||||
|                     defer pool.destroy(); | ||||
| 
 | ||||
|                     break :blk try pool.createBuffer(0, width, height, stride, wl.Shm.Format.argb8888); | ||||
|                 }; | ||||
|                 defer buffer.destroy(); | ||||
| 
 | ||||
|                 output.surface.attach(buffer, 0, 0); | ||||
|                 output.surface.attach(buffer.buffer, 0, 0); | ||||
|                 output.surface.commit(); | ||||
|             } | ||||
| 
 | ||||
|             while (self.running) { | ||||
|                 if (self.dpy.dispatch() != .SUCCESS) return error.DispatchFailed; | ||||
|             } | ||||
|         } | ||||
|         } | ||||
| 
 | ||||
|         fn removeOutput(self: *Self, output: *Output) void { | ||||
|             const link = ListItem(Output).fromValue(output); | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue