code wiki / (root) / nx_x11_screenshot.nx

nx_x11_screenshot.nx source

↩ module page · 67 lines · 2318 B

1// nx_x11_screenshot.nx -- capture a drawable's pixels and drop them 2// to a PPM file Claude (or any image viewer) can open. 3// 4// Self-closing-loop primitive: "Nishi troubleshoots Nishi natively." 5// Composes nx_x11_get_image (pull pixels back from the server) with 6// nx_ppm_writer (encode + write). Used by every visible bits-up 7// demo so we can verify renderings without asking the user "did 8// you see X?" 9// 10// API: 11// nx_x11_save_drawable_as_ppm(conn, drawable, w, h, path) -> 0 | <0 12// 13// license_tier: ORIGINAL 14// lineage_id: nishi_x11_screenshot_q10 15 16import "nx_syscalls.nx" 17import "nx_x11_connect.nx" 18import "nx_x11_get_image.nx" 19import "nx_ppm_writer.nx" 20 21// Capture w*h pixels from the top-left of `drawable` and write a PPM 22// P6 file at `path`. Returns 0 on success, negative on failure. 23func nx_x11_save_drawable_as_ppm(conn: *X11Conn, drawable: i64, 24 width: i64, height: i64, 25 path: *u8) -> i64 { 26 // Allocate buffer for the BGRX response (4 bytes/pixel). 27 let bgrx_cap: i64 = width * height * 4 + 64 28 let bgrx: *u8 = sys_mmap(bgrx_cap + 64) 29 let got: i64 = nx_x11_get_image(conn, drawable, 0, 0, width, height, 30 bgrx, bgrx_cap) 31 if got < 0 { return 0 - 10 } 32 33 // Transcode BGRX -> RGB (3 bytes/pixel) so we can pass to 34 // ppm_write_p6. Top-down rows preserved. 35 let rgb_bytes: i64 = width * height * 3 36 let rgb: *u8 = sys_mmap(rgb_bytes + 64) 37 var y: i64 = 0 38 while y < height { 39 var x: i64 = 0 40 while x < width { 41 let po: i64 = (y * width + x) * 4 42 let ro: i64 = (y * width + x) * 3 43 rgb[ro + 0] = bgrx[po + 2] // R 44 rgb[ro + 1] = bgrx[po + 1] // G 45 rgb[ro + 2] = bgrx[po + 0] // B 46 x = x + 1 47 } 48 y = y + 1 49 } 50 51 // Build PPM buffer (header + binary pixels). 52 let ppm_cap: i64 = 64 + rgb_bytes 53 let ppm: *u8 = sys_mmap(ppm_cap + 64) 54 let n: i64 = ppm_write_p6(ppm, ppm_cap, width, height, rgb) 55 if n < 0 { return 0 - 20 } 56 57 // Write to file. 58 let fd: i64 = sys_openat_wr(path, 0x1A4) // 0644 59 if fd < 0 { return 0 - 30 } 60 sys_write(fd, ppm, n) 61 sys_close(fd) 62 return 0 63} 64 65func main() -> i64 { 66 return 0 67}