code wiki / (root) / nx_nishios_wm.nx

nx_nishios_wm.nx source

↩ module page · 98 lines · 7361 B

1// nx_nishios_wm.nx -- NishiOS GUI rung-2: a WINDOW MANAGER / COMPOSITOR. 2// A desktop is more than one window: it's multiple windows composited in z-order over a wallpaper, with 3// a mouse cursor on top. This draws a gradient wallpaper, two windows that OVERLAP (the higher-z one 4// drawn last so it correctly occludes the lower one), a taskbar with buttons, and a shadowed arrow 5// cursor above everything -- then exports the composite as a real BMP via the nx_fb library. 6// KAT: z-order is correct (the overlap region shows the TOP window, not the bottom), the wallpaper is a 7// real gradient (rows differ), the cursor is drawn on top, and the BMP is well-formed. 8// HONEST SCOPE: a STATIC composite (one frame, fixed cursor). Live input (mouse/keyboard event loop), 9// dragging, and wiring this framebuffer into the boot kernel are the next rungs. No hw writes (Rule 26). 10// expect_exit: 0 license_tier: ORIGINAL 11import "nx_fb.nx" 12import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 13const K_MAGIC_192054: i64 = 192054 14 15func wm_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 16// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 17// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 18// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 19// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 20func wm_num(v: i64) -> i64 { nxi_out(v); return 0 } 21 22// draw a window: body + title strip + 1px black border + title text 23func draw_window(fb: *u8, W: i64, H: i64, font: *u8, idx: *u8, x: i64, y: i64, w: i64, h: i64, tr: i64, tg: i64, tb: i64, br: i64, bg: i64, bb: i64) -> i64 { 24 fb_rect(fb,W,H, x,y, w,h, br,bg,bb) // body 25 fb_rect(fb,W,H, x,y, w,14, tr,tg,tb) // title strip 26 fb_rect(fb,W,H, x,y, w,1, 0,0,0) // border top 27 fb_rect(fb,W,H, x,y+h-1, w,1, 0,0,0) // border bottom 28 fb_rect(fb,W,H, x,y, 1,h, 0,0,0) // border left 29 fb_rect(fb,W,H, x+w-1,y, 1,h, 0,0,0) // border right 30 fb_text(fb,W,H, font, idx, 7, x+3, y+3, 1, 240,240,250) // title "NISHIOS" 31 return 0 32} 33 34func main() -> i64 { 35 wm_puts("NishiOS GUI rung-2: a WINDOW MANAGER (gradient wallpaper + z-ordered overlapping windows + cursor)\n" as *u8) 36 let W: i64 = 320 37 let H: i64 = 200 38 let fb: *u8 = sys_mmap(W*H*3) 39 40 let font: *u8 = sys_mmap(64) 41 fb_gly(font,0, 0x81,0xC1,0xA1,0x91,0x89,0x85,0x83,0x81) // N 42 fb_gly(font,1, 0x7C,0x10,0x10,0x10,0x10,0x10,0x7C,0x00) // I 43 fb_gly(font,2, 0x7E,0x80,0x80,0x7C,0x02,0x02,0x7C,0x00) // S 44 fb_gly(font,3, 0x81,0x81,0x81,0xFF,0x81,0x81,0x81,0x00) // H 45 fb_gly(font,4, 0x7C,0x82,0x82,0x82,0x82,0x82,0x7C,0x00) // O 46 let idx: *u8 = sys_mmap(8) 47 idx[0]=0 as u8; idx[1]=1 as u8; idx[2]=2 as u8; idx[3]=3 as u8; idx[4]=1 as u8; idx[5]=4 as u8; idx[6]=2 as u8 48 49 // wallpaper: vertical gradient (12,12,48) -> (2,60,80) 50 var y: i64=0 51 while y<H { let r: i64=12-(10*y)/H; let g: i64=12+(48*y)/H; let b: i64=48+(32*y)/H; fb_rect(fb,W,H, 0,y, W,1, r,g,b); y=y+1 } 52 53 // two windows, drawn back-to-front (z-order): win1 first, win2 on top 54 draw_window(fb,W,H, font,idx, 40,45, 130,95, 40,120,60, 35,35,45) // win1 "terminal" (green title, dark body) -- BELOW 55 draw_window(fb,W,H, font,idx, 120,80, 150,95, 50,80,180, 200,200,215) // win2 "files" (blue title, light body) -- ON TOP 56 57 // taskbar + two buttons 58 fb_rect(fb,W,H, 0,186, W,14, 25,25,40) 59 fb_rect(fb,W,H, 4,189, 40,8, 80,200,80) 60 fb_rect(fb,W,H, 50,189, 40,8, 80,140,220) 61 62 // mouse cursor (shadowed arrow) on top of everything, at (185,100) -- over win2 63 let curs: *u8 = sys_mmap(16) 64 curs[0]=0x80 as u8; curs[1]=0xC0 as u8; curs[2]=0xE0 as u8; curs[3]=0xF0 as u8; curs[4]=0xF8 as u8; curs[5]=0xFC as u8; curs[6]=0xFE as u8; curs[7]=0xFF as u8; curs[8]=0xFC as u8; curs[9]=0xEC as u8; curs[10]=0xC6 as u8; curs[11]=0x86 as u8 65 let cx: i64=185 66 let cy: i64=100 67 var cr: i64=0 68 while cr<12 { let bits: i64=curs[cr] as i64; var cc: i64=0; while cc<8 { if ((bits>>(7-cc))&1)==1 { fb_setpx(fb,W,H, cx+cc+1, cy+cr+1, 0,0,0) } cc=cc+1 } cr=cr+1 } // shadow 69 cr=0 70 while cr<12 { let bits2: i64=curs[cr] as i64; var cc2: i64=0; while cc2<8 { if ((bits2>>(7-cc2))&1)==1 { fb_setpx(fb,W,H, cx+cc2, cy+cr, 255,255,255) } cc2=cc2+1 } cr=cr+1 } // white arrow 71 72 let sz: i64 = fb_bmp_save(fb, W, H, "knowledge/status/nishios_wm.bmp\x00" as *u8) 73 let html: *u8 = "<!doctype html><html><body style=\x27margin:0;background:#0a0a12;display:flex;align-items:center;justify-content:center;height:100vh\x27><div><img src=\x27nishios_wm.bmp\x27 style=\x27image-rendering:pixelated;width:640px;border:1px solid #333\x27><div style=\x27color:#8af;font-family:monospace;text-align:center;margin-top:8px\x27>NishiOS window manager -- 2 windows composited in z-order + cursor, drawn by the kernel</div></div></body></html>\x00" 74 let hd: i64 = sys_openat_wr("knowledge/status/nishios_wm.html\x00" as *u8, 0x1a4) 75 if hd>0 { var hn: i64=0; while html[hn]!=(0 as u8){hn=hn+1} sys_write(hd, html, hn); sys_close(hd) } 76 wm_puts(" composited desktop -> knowledge/status/nishios_wm.bmp (" as *u8); wm_num(sz); wm_puts(" bytes) + nishios_wm.html\n" as *u8) 77 78 var pass: i64=0 79 var ttl: i64=0 80 // z-order: overlap point (140,110) must be win2 body (200,200,215), NOT win1 (35,35,45) 81 let p_ov: i64 = (110*W+140)*3 82 ttl=ttl+1; wm_puts(" T1 z-order correct (overlap shows TOP window 200,200,215): " as *u8); if (fb[p_ov] as i64)==200 { if (fb[p_ov+2] as i64)==215 { pass=pass+1; wm_puts("PASS\n" as *u8) } else { wm_puts("FAIL\n" as *u8) } } else { wm_puts("FAIL\n" as *u8) } 83 // win1-only point (60,75) must be win1 body (35,35,45) 84 let p_w1: i64 = (75*W+60)*3 85 ttl=ttl+1; wm_puts(" T2 lower window visible where not occluded (35,35,45): " as *u8); if (fb[p_w1] as i64)==35 { if (fb[p_w1+2] as i64)==45 { pass=pass+1; wm_puts("PASS\n" as *u8) } else { wm_puts("FAIL\n" as *u8) } } else { wm_puts("FAIL\n" as *u8) } 86 // gradient wallpaper: column x=300 differs between y=10 and y=180 87 let g_top: i64 = (10*W+300)*3+1 88 let g_bot: i64 = (180*W+300)*3+1 89 ttl=ttl+1; wm_puts(" T3 wallpaper is a real gradient (rows differ): " as *u8); if (fb[g_top] as i64) != (fb[g_bot] as i64) { pass=pass+1; wm_puts("PASS\n" as *u8) } else { wm_puts("FAIL\n" as *u8) } 90 // cursor tip (185,100) white on top 91 let p_cu: i64 = (100*W+185)*3 92 ttl=ttl+1; wm_puts(" T4 mouse cursor drawn on top (white tip @185,100): " as *u8); if (fb[p_cu] as i64)==255 { if (fb[p_cu+1] as i64)==255 { pass=pass+1; wm_puts("PASS\n" as *u8) } else { wm_puts("FAIL\n" as *u8) } } else { wm_puts("FAIL\n" as *u8) } 93 ttl=ttl+1; wm_puts(" T5 BMP exported (192054 bytes): " as *u8); if sz==K_MAGIC_192054 { pass=pass+1; wm_puts("PASS\n" as *u8) } else { wm_puts("FAIL\n" as *u8) } 94 95 wm_puts("NISHIOS-WM-GATE passed " as *u8); wm_num(pass); wm_puts("/" as *u8); wm_num(ttl) 96 if pass==ttl { wm_puts(" verdict=GREEN (a real window manager composites z-ordered windows + cursor; open nishios_wm.bmp/html to SEE it)\n" as *u8); sys_exit(0); return 0 } 97 wm_puts(" verdict=RED\n" as *u8); sys_exit(1); return 1 98}