code wiki / (root) / nx_x11_paint.nx

nx_x11_paint.nx source

↩ module page · 219 lines · 7311 B

1// nx_x11_paint.nx -- bits-up X11 painting primitives. 2// 3// Session 3 of the bits-up browser arc. Adds the wire opcodes that 4// actually draw inside a window: CreateGC, ChangeGC, PolyFillRectangle, 5// ImageText8. Composes nx_x11_connect + nx_x11_window. 6// 7// Opcodes (X Protocol ยง10): 8// 55 CreateGC 9// 56 ChangeGC 10// 70 PolyFillRectangle 11// 76 ImageText8 12// 13// GC value mask bits we use: 14// GCForeground = 0x00000004 15// 16// Event mask bits (for the CreateWindow value list): 17// ExposureMask = 0x00008000 18// KeyPressMask = 0x00000001 19// ButtonPressMask = 0x00000004 20// StructureNotifyMask = 0x00020000 21// 22// license_tier: ORIGINAL 23// genealogy_id: international-research-sources/x_org/xproto_v11_r0 24// lineage_id: nishi_x11_paint_q10 25 26import "nx_syscalls.nx" 27import "nx_x11_connect.nx" 28import "nx_x11_window.nx" 29 30const NX_X11_EVENT_EXPOSURE: i64 = 0x00008000 31const NX_X11_EVENT_KEY_PRESS: i64 = 0x00000001 32const NX_X11_EVENT_BUTTON_PRESS: i64 = 0x00000004 33const NX_X11_EVENT_BUTTON_RELEASE: i64 = 0x00000008 34const NX_X11_EVENT_POINTER_MOTION: i64 = 0x00000040 35const NX_X11_EVENT_STRUCTURE: i64 = 0x00020000 36 37const NX_X11_GC_FOREGROUND: i64 = 0x00000004 38 39// CreateGC (opcode 55). Sets foreground pixel. Returns gc_id. 40func nx_x11_create_gc(conn: *X11Conn, drawable: i64, fg_pixel: i64) -> i64 { 41 let gc: i64 = nx_x11_alloc_id(conn) 42 43 // 16 bytes core + 4 bytes value (1 value = foreground) 44 let total: i64 = 20 45 let words: i64 = total / 4 46 47 let req: *u8 = sys_mmap(32) 48 var i: i64 = 0 49 while i < 32 { req[i] = 0; i = i + 1 } 50 51 req[0] = 55 52 req[1] = 0 53 _x11_wr_u16(req, 2, words) 54 _x11_wr_u32(req, 4, gc) 55 _x11_wr_u32(req, 8, drawable) 56 _x11_wr_u32(req, 12, NX_X11_GC_FOREGROUND) 57 _x11_wr_u32(req, 16, fg_pixel) 58 59 if _x11_send(conn, req, total) < 0 { return 0 - 1 } 60 return gc 61} 62 63// ChangeGC (opcode 56) -- update an existing GC's foreground. 64func nx_x11_set_gc_foreground(conn: *X11Conn, gc: i64, fg_pixel: i64) -> i64 { 65 let total: i64 = 16 66 let words: i64 = total / 4 67 let req: *u8 = sys_mmap(32) 68 var i: i64 = 0 69 while i < 32 { req[i] = 0; i = i + 1 } 70 req[0] = 56 71 req[1] = 0 72 _x11_wr_u16(req, 2, words) 73 _x11_wr_u32(req, 4, gc) 74 _x11_wr_u32(req, 8, NX_X11_GC_FOREGROUND) 75 _x11_wr_u32(req, 12, fg_pixel) 76 return _x11_send(conn, req, total) 77} 78 79// PolyFillRectangle (opcode 70) -- one rectangle. 80func nx_x11_fill_rect(conn: *X11Conn, drawable: i64, gc: i64, 81 x: i64, y: i64, w: i64, h: i64) -> i64 { 82 let total: i64 = 20 83 let words: i64 = total / 4 84 let req: *u8 = sys_mmap(32) 85 var i: i64 = 0 86 while i < 32 { req[i] = 0; i = i + 1 } 87 req[0] = 70 88 req[1] = 0 89 _x11_wr_u16(req, 2, words) 90 _x11_wr_u32(req, 4, drawable) 91 _x11_wr_u32(req, 8, gc) 92 _x11_wr_u16(req, 12, x) 93 _x11_wr_u16(req, 14, y) 94 _x11_wr_u16(req, 16, w) 95 _x11_wr_u16(req, 18, h) 96 return _x11_send(conn, req, total) 97} 98 99// ImageText8 (opcode 76) -- draw text using the server's default font. 100// Up to 255 bytes of string; we cap at 254 to be safe. 101func nx_x11_image_text8(conn: *X11Conn, drawable: i64, gc: i64, 102 x: i64, y: i64, text: *u8, text_len: i64) -> i64 { 103 var n: i64 = text_len 104 if n > 254 { n = 254 } 105 // request body: 16 bytes core + n bytes string padded to 4 106 var padded: i64 = n 107 if (padded & 3) != 0 { padded = padded + 4 - (padded & 3) } 108 let total: i64 = 16 + padded 109 let words: i64 = total / 4 110 111 let req: *u8 = sys_mmap(total + 16) 112 var i: i64 = 0 113 while i < total + 16 { req[i] = 0; i = i + 1 } 114 req[0] = 76 115 req[1] = n as u8 // string length 116 _x11_wr_u16(req, 2, words) 117 _x11_wr_u32(req, 4, drawable) 118 _x11_wr_u32(req, 8, gc) 119 _x11_wr_u16(req, 12, x) 120 _x11_wr_u16(req, 14, y) 121 var k: i64 = 0 122 while k < n { req[16 + k] = text[k]; k = k + 1 } 123 return _x11_send(conn, req, total) 124} 125 126// PolyText8 (opcode 74) -- draws text WITHOUT filling the glyph-cell background, so the 127// already-painted page/element background shows through (transparent text). This is what a real 128// browser needs: ImageText8 paints an opaque box (the GC background, default black) behind every 129// glyph, which is what made the page look like "black background + colored text". One TEXTITEM8: 130// [length][delta=0][string]. 131func nx_x11_poly_text8(conn: *X11Conn, drawable: i64, gc: i64, 132 x: i64, y: i64, text: *u8, text_len: i64) -> i64 { 133 var n: i64 = text_len 134 if n > 254 { n = 254 } 135 // 16-byte core + TEXTITEM8 (1 len + 1 delta + n string), padded to a 4-byte boundary 136 var total: i64 = 18 + n 137 if (total & 3) != 0 { total = total + 4 - (total & 3) } 138 let words: i64 = total / 4 139 let req: *u8 = sys_mmap(total + 16) 140 var i: i64 = 0 141 while i < total + 16 { req[i] = 0; i = i + 1 } 142 req[0] = 74 143 req[1] = 0 144 _x11_wr_u16(req, 2, words) 145 _x11_wr_u32(req, 4, drawable) 146 _x11_wr_u32(req, 8, gc) 147 _x11_wr_u16(req, 12, x) 148 _x11_wr_u16(req, 14, y) 149 req[16] = n as u8 // TEXTITEM8 string length 150 req[17] = 0 as u8 // delta 151 var k: i64 = 0 152 while k < n { req[18 + k] = text[k]; k = k + 1 } 153 return _x11_send(conn, req, total) 154} 155 156// OpenFont (opcode 45) -- load a server font by name (e.g. "9x15", "fixed", or an XLFD). 157// Returns the font id, or -1. Set it on a GC with nx_x11_set_gc_font before ImageText8. 158func nx_x11_open_font(conn: *X11Conn, name: *u8, name_len: i64) -> i64 { 159 let fid: i64 = nx_x11_alloc_id(conn) 160 var padded: i64 = name_len 161 if (padded & 3) != 0 { padded = padded + 4 - (padded & 3) } 162 let total: i64 = 12 + padded 163 let req: *u8 = sys_mmap(total + 16) 164 var i: i64 = 0 165 while i < total + 16 { req[i] = 0; i = i + 1 } 166 req[0] = 45 167 _x11_wr_u16(req, 2, total / 4) 168 _x11_wr_u32(req, 4, fid) 169 _x11_wr_u16(req, 8, name_len) 170 var k: i64 = 0 171 while k < name_len { req[12 + k] = name[k]; k = k + 1 } 172 if _x11_send(conn, req, total) < 0 { return 0 - 1 } 173 return fid 174} 175 176// ChangeGC (opcode 56) -- set the GC's FONT (GCFont value mask 0x4000), so ImageText8 has a font. 177func nx_x11_set_gc_font(conn: *X11Conn, gc: i64, fid: i64) -> i64 { 178 let total: i64 = 16 179 let req: *u8 = sys_mmap(32) 180 var i: i64 = 0 181 while i < 32 { req[i] = 0; i = i + 1 } 182 req[0] = 56 183 _x11_wr_u16(req, 2, total / 4) 184 _x11_wr_u32(req, 4, gc) 185 _x11_wr_u32(req, 8, 0x00004000) 186 _x11_wr_u32(req, 12, fid) 187 return _x11_send(conn, req, total) 188} 189 190// Read ONE 32-byte X11 event/error/reply. Caller dispatches by 191// out[0] (kind byte). 192// 193// kind: 194// 0 = Error reply (out[1] = error code) 195// 1 = (regular Reply) 196// 2 = KeyPress 197// 3 = KeyRelease 198// 4 = ButtonPress 199// 5 = ButtonRelease 200// 6 = MotionNotify 201// 12 = Expose 202// 17 = DestroyNotify 203// 22 = ConfigureNotify 204// ... 205// 206// Returns 0 on success, negative on read failure. 207func nx_x11_read_event(conn: *X11Conn, out: *u8) -> i64 { 208 var got: i64 = 0 209 while got < 32 { 210 let r: i64 = sys_read(conn.fd, ((out as i64) + got) as *u8, 32 - got) 211 if r <= 0 { return 0 - 1 } 212 got = got + r 213 } 214 return 0 215} 216 217func main() -> i64 { 218 return 0 219}