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}