code wiki / (root) / nx_fb.nx

nx_fb.nx source

↩ module page · 90 lines · 5107 B

1// nx_fb.nx -- sovereign FRAMEBUFFER library (the kernel's pixel/draw layer for the NishiOS GUI). 2// Reusable primitives extracted (Rule 15 DRY) so every GUI organ draws the same way: clipped pixel, 3// filled rect, 8x8 bitmap-font glyph install + draw (scalable), and a real 24-bit BMP export. A 4// framebuffer is just W*H*3 RGB bytes; on real x86 the kernel gets this region from VESA/VBE or UEFI GOP. 5// license_tier: ORIGINAL 6import "nx_syscalls.nx" 7const K_MAGIC_2835: i64 = 2835 8 9func fb_setpx(fb: *u8, W: i64, H: i64, x: i64, y: i64, r: i64, g: i64, b: i64) -> i64 { 10 if x>=0 { if x<W { if y>=0 { if y<H { let i: i64=(y*W+x)*3; fb[i]=r as u8; fb[i+1]=g as u8; fb[i+2]=b as u8 } } } } 11 return 0 12} 13func fb_rect(fb: *u8, W: i64, H: i64, x: i64, y: i64, w: i64, h: i64, r: i64, g: i64, b: i64) -> i64 { 14 var yy: i64=0 15 while yy<h { var xx: i64=0; while xx<w { fb_setpx(fb,W,H,x+xx,y+yy,r,g,b); xx=xx+1 } yy=yy+1 } 16 return 0 17} 18func fb_gly(f: *u8, i: i64, r0: i64, r1: i64, r2: i64, r3: i64, r4: i64, r5: i64, r6: i64, r7: i64) -> i64 { 19 let o: i64=i*8 20 f[o]=r0 as u8; f[o+1]=r1 as u8; f[o+2]=r2 as u8; f[o+3]=r3 as u8; f[o+4]=r4 as u8; f[o+5]=r5 as u8; f[o+6]=r6 as u8; f[o+7]=r7 as u8 21 return 0 22} 23func fb_char(fb: *u8, W: i64, H: i64, x: i64, y: i64, g: *u8, scale: i64, r: i64, gg: i64, b: i64) -> i64 { 24 var row: i64=0 25 while row<8 { 26 let bits: i64 = g[row] as i64 27 var col: i64=0 28 while col<8 { if ((bits >> (7-col)) & 1) == 1 { fb_rect(fb,W,H, x+col*scale, y+row*scale, scale, scale, r,gg,b) } col=col+1 } 29 row=row+1 30 } 31 return 0 32} 33func fb_text(fb: *u8, W: i64, H: i64, font: *u8, idx: *u8, n: i64, x: i64, y: i64, scale: i64, r: i64, g: i64, b: i64) -> i64 { 34 var k: i64=0 35 while k<n { let gi: i64 = idx[k] as i64; fb_char(fb,W,H, x + k*9*scale, y, ((font as i64) + gi*8) as *u8, scale, r,g,b); k=k+1 } 36 return 0 37} 38// draw a decorated window (body + title strip + 1px black border + "NISHIOS" title text) 39func fb_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 { 40 fb_rect(fb,W,H, x,y, w,h, br,bg,bb) 41 fb_rect(fb,W,H, x,y, w,14, tr,tg,tb) 42 fb_rect(fb,W,H, x,y, w,1, 0,0,0); fb_rect(fb,W,H, x,y+h-1, w,1, 0,0,0); fb_rect(fb,W,H, x,y, 1,h, 0,0,0); fb_rect(fb,W,H, x+w-1,y, 1,h, 0,0,0) 43 fb_text(fb,W,H, font, idx, 7, x+3, y+3, 1, 240,240,250) 44 return 0 45} 46// install the NISHIOS bitmap font (glyphs N I S H O at 0..4) and the "NISHIOS" index string into idx[0..6] 47func fb_nishi_font(font: *u8, idx: *u8) -> i64 { 48 fb_gly(font,0, 0x81,0xC1,0xA1,0x91,0x89,0x85,0x83,0x81) 49 fb_gly(font,1, 0x7C,0x10,0x10,0x10,0x10,0x10,0x7C,0x00) 50 fb_gly(font,2, 0x7E,0x80,0x80,0x7C,0x02,0x02,0x7C,0x00) 51 fb_gly(font,3, 0x81,0x81,0x81,0xFF,0x81,0x81,0x81,0x00) 52 fb_gly(font,4, 0x7C,0x82,0x82,0x82,0x82,0x82,0x7C,0x00) 53 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 54 return 0 55} 56// draw a shadowed white arrow mouse cursor at (cx,cy) 57func fb_cursor(fb: *u8, W: i64, H: i64, cx: i64, cy: i64) -> i64 { 58 let curs: *u8 = sys_mmap(16) 59 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 60 var cr: i64=0 61 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 } 62 cr=0 63 while cr<12 { let b2: i64=curs[cr] as i64; var c2: i64=0; while c2<8 { if ((b2>>(7-c2))&1)==1 { fb_setpx(fb,W,H, cx+c2, cy+cr, 255,255,255) } c2=c2+1 } cr=cr+1 } 64 return 0 65} 66func fb_p32(buf: *u8, o: i64, v: i64) -> i64 { buf[o]=(v & 0xFF) as u8; buf[o+1]=((v>>8)&0xFF) as u8; buf[o+2]=((v>>16)&0xFF) as u8; buf[o+3]=((v>>24)&0xFF) as u8; return o+4 } 67func fb_p16(buf: *u8, o: i64, v: i64) -> i64 { buf[o]=(v & 0xFF) as u8; buf[o+1]=((v>>8)&0xFF) as u8; return o+2 } 68 69// export the framebuffer as a real 24-bit BMP (BGR, bottom-up). returns filesize, or 0 on failure. 70func fb_bmp_save(fb: *u8, W: i64, H: i64, path: *u8) -> i64 { 71 let pixbytes: i64 = W*3*H 72 let filesize: i64 = 54 + pixbytes 73 let buf: *u8 = sys_mmap(filesize + 16) 74 buf[0]=66 as u8; buf[1]=77 as u8 75 var o: i64=2 76 o=fb_p32(buf,o,filesize); o=fb_p32(buf,o,0); o=fb_p32(buf,o,54) 77 o=fb_p32(buf,o,40); o=fb_p32(buf,o,W); o=fb_p32(buf,o,H); o=fb_p16(buf,o,1); o=fb_p16(buf,o,24) 78 o=fb_p32(buf,o,0); o=fb_p32(buf,o,pixbytes); o=fb_p32(buf,o,K_MAGIC_2835); o=fb_p32(buf,o,K_MAGIC_2835); o=fb_p32(buf,o,0); o=fb_p32(buf,o,0) 79 var fy: i64=0 80 while fy<H { 81 let srcrow: i64 = H-1-fy 82 var x: i64=0 83 while x<W { let i: i64=(srcrow*W+x)*3; buf[o]=fb[i+2]; buf[o+1]=fb[i+1]; buf[o+2]=fb[i]; o=o+3; x=x+1 } 84 fy=fy+1 85 } 86 let fd: i64 = sys_openat_wr(path, 0x1a4) 87 if fd<=0 { return 0 } 88 sys_write(fd, buf, filesize); sys_close(fd) 89 return filesize 90}