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 Box = struct { | ||||||
|     const Self = @This(); |     const Self = @This(); | ||||||
| 
 | 
 | ||||||
|  | @ -301,6 +382,10 @@ const Output = struct { | ||||||
|         self.output.destroy(); |         self.output.destroy(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     fn commitFrame(self: *Self) void { | ||||||
|  |         _ = self; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     fn xdgOutputListener(output: *zxdg.OutputV1, event: zxdg.OutputV1.Event, self: *Self) void { |     fn xdgOutputListener(output: *zxdg.OutputV1, event: zxdg.OutputV1.Event, self: *Self) void { | ||||||
|         _ = output; |         _ = output; | ||||||
| 
 | 
 | ||||||
|  | @ -336,7 +421,7 @@ const Output = struct { | ||||||
|                 }; |                 }; | ||||||
| 
 | 
 | ||||||
|                 layer.ackConfigure(cfg.serial); |                 layer.ackConfigure(cfg.serial); | ||||||
|                 // TODO: send frame |                 self.commitFrame(); | ||||||
|             }, |             }, | ||||||
|             .closed => { |             .closed => { | ||||||
|                 self.state.removeOutput(self); |                 self.state.removeOutput(self); | ||||||
|  | @ -832,34 +917,21 @@ const State = struct { | ||||||
|             var it = self.outputs.iterator(.forward); |             var it = self.outputs.iterator(.forward); | ||||||
|             if (it.next()) |link| { |             if (it.next()) |link| { | ||||||
|                 const output = link.get(); |                 const output = link.get(); | ||||||
|                 const os = std.os; |  | ||||||
| 
 | 
 | ||||||
|                 const buffer = blk: { |                 var buffer: Buffer = undefined; | ||||||
|                     const width = 128; |                 const width = output.size.width * @intCast(u32, output.scale); | ||||||
|                     const height = 128; |                 const height = output.size.height * @intCast(u32, output.scale); | ||||||
|                     const stride = width * 4; |                 try buffer.init(self.shm, .{.width = width, .height = height}); | ||||||
|                     const size = stride * height; |                 std.mem.copy(u8, buffer.data, @embedFile("cat.bgra")); | ||||||
| 
 | 
 | ||||||
|                     const fd = try os.memfd_create("hello-zig-wayland", 0); |                 output.surface.attach(buffer.buffer, 0, 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.commit(); |                 output.surface.commit(); | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             while (self.running) { |             while (self.running) { | ||||||
|                 if (self.dpy.dispatch() != .SUCCESS) return error.DispatchFailed; |                 if (self.dpy.dispatch() != .SUCCESS) return error.DispatchFailed; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         fn removeOutput(self: *Self, output: *Output) void { |         fn removeOutput(self: *Self, output: *Output) void { | ||||||
|             const link = ListItem(Output).fromValue(output); |             const link = ListItem(Output).fromValue(output); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue