buninu-linux 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSES/Apache-2.0.txt +202 -0
- package/LICENSES/BSD-3-Clause-Skia.txt +29 -0
- package/LICENSES/Bitstream-Vera.txt +44 -0
- package/LICENSES/MIT-xterm.js.txt +21 -0
- package/LICENSES/OFL-1.1.txt +91 -0
- package/NOTICE.md +18 -1
- package/README.md +226 -22
- package/fetch-alpine.sh +9 -4
- package/graphics.md +213 -0
- package/initramfs/bin/bunterm +66 -0
- package/initramfs/bin/ip +2 -1
- package/initramfs/bin/mount +2 -1
- package/initramfs/bin/poweroff +6 -27
- package/initramfs/bin/ps +256 -0
- package/initramfs/bin/reboot +10 -0
- package/initramfs/bin/tar +169 -0
- package/initramfs/bin/top +129 -0
- package/initramfs/bin/umount +2 -1
- package/initramfs/buninu/CHANGELOG.md +40 -0
- package/initramfs/buninu/apps/bunmsh/CHANGELOG.md +36 -0
- package/initramfs/buninu/apps/bunmsh/README.md +7 -0
- package/initramfs/buninu/apps/bunmsh/package.json +1 -1
- package/initramfs/buninu/apps/bunmsh/src/fancy-ls.js +29 -14
- package/initramfs/buninu/apps/bunmsh/src/line-edit.js +43 -0
- package/initramfs/buninu/apps/bunmsh/src/main.js +15 -1
- package/initramfs/buninu/apps/bunmsh/src/mouse.js +29 -4
- package/initramfs/buninu/apps/bunmsh/src/shell.js +9 -1
- package/initramfs/buninu/apps/bunmsh/test/shell1.test.js +70 -0
- package/initramfs/buninu/apps/jsgotty/gotty.js +4 -3
- package/initramfs/buninu/apps/jsgotty/package.json +1 -1
- package/initramfs/buninu/apps/jsmdcui/CHANGELOG.md +10 -0
- package/initramfs/buninu/apps/jsmdcui/README.md +2 -0
- package/initramfs/buninu/apps/jsmdcui/package.json +1 -1
- package/initramfs/buninu/apps/jsmdcui/runtime/help/commands.md +4 -1
- package/initramfs/buninu/apps/jsmdcui/runtime/help/help.md +2 -0
- package/initramfs/buninu/apps/jsmdcui/src/index.js +40 -13
- package/initramfs/buninu/package.json +1 -1
- package/initramfs/init.js +6 -0
- package/initramfs/lib/bunterm/glyphs.js +446 -0
- package/initramfs/lib/bunterm/images.js +225 -0
- package/initramfs/lib/bunterm/input.js +140 -0
- package/initramfs/lib/bunterm/renderer.js +424 -0
- package/initramfs/lib/bunterm/terminal.js +203 -0
- package/initramfs/lib/canvas.js +181 -0
- package/initramfs/lib/canvaskit/LICENSE +29 -0
- package/initramfs/lib/canvaskit/canvaskit.js +264 -0
- package/initramfs/lib/canvaskit/canvaskit.wasm +0 -0
- package/initramfs/lib/dlopen.js +14 -11
- package/initramfs/lib/document.js +6 -0
- package/initramfs/lib/fbdev.js +581 -0
- package/initramfs/lib/power.js +35 -0
- package/initramfs/lib/xterm/LICENSE +21 -0
- package/initramfs/lib/xterm/addon-unicode-graphemes.mjs +44 -0
- package/initramfs/lib/xterm/xterm-headless.mjs +46 -0
- package/initramfs/usr/share/doc/buninu-linux/bunterm.md +83 -0
- package/initramfs/usr/share/doc/buninu-linux/canvas.md +91 -0
- package/initramfs/usr/share/doc/buninu-linux/fbdev.md +113 -0
- package/initramfs/usr/share/doc/buninu-linux/ps.md +94 -0
- package/initramfs/usr/share/doc/buninu-linux/reboot.md +15 -0
- package/initramfs/usr/share/doc/buninu-linux/tar.md +73 -0
- package/initramfs/usr/share/doc/buninu-linux/top.md +23 -0
- package/initramfs/usr/share/fonts/DejaVuSansMono-Bold.ttf +0 -0
- package/initramfs/usr/share/fonts/DejaVuSansMono.ttf +0 -0
- package/initramfs/usr/share/fonts/LICENSE-Apache-2.0.txt +202 -0
- package/initramfs/usr/share/fonts/LICENSE-DejaVu.txt +44 -0
- package/initramfs/usr/share/fonts/LICENSE-OFL-1.1.txt +91 -0
- package/initramfs/usr/share/fonts/NotoColorEmoji.ttf +0 -0
- package/initramfs/usr/share/fonts/NotoColorEmojiFlags.ttf +0 -0
- package/initramfs/usr/share/fonts/NotoSansCJK-Regular.ttc +0 -0
- package/initramfs/usr/share/fonts/NotoSansSymbols-Regular-Subsetted.ttf +0 -0
- package/initramfs/usr/share/fonts/NotoSansSymbols-Regular-Subsetted2.ttf +0 -0
- package/initramfs/usr/share/fonts/Roboto-Regular.ttf +0 -0
- package/initramfs/usr/share/fonts/fonts.json +28 -0
- package/package.json +2 -2
- package/run-qemu.sh +1 -1
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
// /lib/canvas.js — CanvasKit (Skia in WebAssembly) on the Linux framebuffer.
|
|
2
|
+
//
|
|
3
|
+
// Skia draws into a buffer inside the wasm heap that already has the
|
|
4
|
+
// framebuffer's own pixel layout, so a frame reaches /dev/fb0 with a single
|
|
5
|
+
// copy: exactly what /lib/fbdev.js does with its JavaScript back buffer. The
|
|
6
|
+
// Framebuffer's `pixels` view is pointed at that heap buffer while a canvas is
|
|
7
|
+
// open, so the fbdev.js drawing calls and flush() keep working on the same
|
|
8
|
+
// frame and Skia and JavaScript drawing can be mixed freely.
|
|
9
|
+
|
|
10
|
+
import { readFileSync } from "node:fs";
|
|
11
|
+
import CanvasKitInit from "./canvaskit/canvaskit.js";
|
|
12
|
+
import { flush as flushFramebuffer } from "./fbdev.js";
|
|
13
|
+
|
|
14
|
+
export const canvasKitDirectory = `${import.meta.dir}/canvaskit`;
|
|
15
|
+
export const fontDirectory = `${import.meta.dir}/../usr/share/fonts`;
|
|
16
|
+
|
|
17
|
+
let canvasKitPromise = null;
|
|
18
|
+
|
|
19
|
+
// One CanvasKit instance per process; the wasm heap starts at 128 MiB.
|
|
20
|
+
export const loadCanvasKit = () => {
|
|
21
|
+
canvasKitPromise ??= CanvasKitInit({
|
|
22
|
+
wasmBinary: readFileSync(`${canvasKitDirectory}/canvaskit.wasm`),
|
|
23
|
+
});
|
|
24
|
+
return canvasKitPromise;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const fieldIs = (field, offset, length) =>
|
|
28
|
+
field.offset === offset && field.length === length;
|
|
29
|
+
|
|
30
|
+
// Maps the kernel's bitfield description to a Skia ColorType with the same
|
|
31
|
+
// byte order in memory. The fields are little-endian bit offsets, so 32-bit
|
|
32
|
+
// red@16 green@8 blue@0 is B,G,R,X in memory: Skia's BGRA_8888. Only formats
|
|
33
|
+
// Skia can rasterize into directly are accepted; others must go through
|
|
34
|
+
// blitImageData() in fbdev.js.
|
|
35
|
+
export const pickColorType = (CanvasKit, display) => {
|
|
36
|
+
const { red, green, blue } = display.fields;
|
|
37
|
+
if (display.bitsPerPixel === 32) {
|
|
38
|
+
if (fieldIs(red, 16, 8) && fieldIs(green, 8, 8) && fieldIs(blue, 0, 8)) {
|
|
39
|
+
return CanvasKit.ColorType.BGRA_8888;
|
|
40
|
+
}
|
|
41
|
+
if (fieldIs(red, 0, 8) && fieldIs(green, 8, 8) && fieldIs(blue, 16, 8)) {
|
|
42
|
+
return CanvasKit.ColorType.RGBA_8888;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (display.bitsPerPixel === 16
|
|
46
|
+
&& fieldIs(red, 11, 5) && fieldIs(green, 5, 6) && fieldIs(blue, 0, 5)) {
|
|
47
|
+
return CanvasKit.ColorType.RGB_565;
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const describeFields = ({ red, green, blue }) =>
|
|
53
|
+
`red@${red.offset}/${red.length} green@${green.offset}/${green.length} blue@${blue.offset}/${blue.length}`;
|
|
54
|
+
|
|
55
|
+
// Binds a Skia raster surface to an open Framebuffer. `display` only needs
|
|
56
|
+
// the fields fbdev.js's Framebuffer exposes (width, height, stride,
|
|
57
|
+
// bitsPerPixel, fields, pixels), so a plain object backed by memory works for
|
|
58
|
+
// tests and off-screen rendering.
|
|
59
|
+
export const openCanvas = (CanvasKit, display) => {
|
|
60
|
+
const colorType = pickColorType(CanvasKit, display);
|
|
61
|
+
if (colorType === null) {
|
|
62
|
+
throw new Error(`no Skia color type for a ${display.bitsPerPixel} bpp framebuffer `
|
|
63
|
+
+ `(${describeFields(display.fields)}); use blitImageData() instead`);
|
|
64
|
+
}
|
|
65
|
+
const length = display.stride * display.height;
|
|
66
|
+
const memory = CanvasKit.Malloc(Uint8Array, length);
|
|
67
|
+
const surface = CanvasKit.MakeRasterDirectSurface({
|
|
68
|
+
width: display.width,
|
|
69
|
+
height: display.height,
|
|
70
|
+
colorType,
|
|
71
|
+
alphaType: CanvasKit.AlphaType.Opaque,
|
|
72
|
+
colorSpace: CanvasKit.ColorSpace.SRGB,
|
|
73
|
+
}, memory, display.stride);
|
|
74
|
+
if (!surface) {
|
|
75
|
+
CanvasKit.Free(memory);
|
|
76
|
+
throw new Error("MakeRasterDirectSurface failed");
|
|
77
|
+
}
|
|
78
|
+
const previousPixels = display.pixels;
|
|
79
|
+
// Start from whatever the JavaScript back buffer held (usually zeros).
|
|
80
|
+
memory.toTypedArray().set(previousPixels.subarray(0, length));
|
|
81
|
+
display.pixels = memory.toTypedArray();
|
|
82
|
+
let open = true;
|
|
83
|
+
return {
|
|
84
|
+
CanvasKit,
|
|
85
|
+
display,
|
|
86
|
+
surface,
|
|
87
|
+
canvas: surface.getCanvas(),
|
|
88
|
+
colorType,
|
|
89
|
+
width: display.width,
|
|
90
|
+
height: display.height,
|
|
91
|
+
// Finishes pending Skia work and copies the frame to the framebuffer.
|
|
92
|
+
// toTypedArray() is re-read because wasm heap growth detaches old views.
|
|
93
|
+
flush() {
|
|
94
|
+
if (!open) throw new Error("canvas is closed");
|
|
95
|
+
surface.flush();
|
|
96
|
+
display.pixels = memory.toTypedArray();
|
|
97
|
+
flushFramebuffer(display);
|
|
98
|
+
},
|
|
99
|
+
// Releases the Skia surface and heap buffer; the Framebuffer stays open
|
|
100
|
+
// and gets its own back buffer back, holding the last frame.
|
|
101
|
+
close() {
|
|
102
|
+
if (!open) return;
|
|
103
|
+
open = false;
|
|
104
|
+
previousPixels.set(memory.toTypedArray().subarray(0, previousPixels.length));
|
|
105
|
+
display.pixels = previousPixels;
|
|
106
|
+
surface.delete();
|
|
107
|
+
CanvasKit.Free(memory);
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// Font catalogue: /usr/share/fonts/fonts.json names every bundled file and
|
|
113
|
+
// the family sets built from them. Files load lazily, since the CJK
|
|
114
|
+
// collection alone is 32 MiB and is copied into the wasm heap.
|
|
115
|
+
let catalogue = null;
|
|
116
|
+
|
|
117
|
+
export const fontCatalogue = () => {
|
|
118
|
+
catalogue ??= JSON.parse(readFileSync(`${fontDirectory}/fonts.json`, "utf8"));
|
|
119
|
+
return catalogue;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export const fontPath = (name) => {
|
|
123
|
+
const entry = fontCatalogue().fonts[name];
|
|
124
|
+
if (!entry) throw new Error(`unknown font ${JSON.stringify(name)}`);
|
|
125
|
+
return `${fontDirectory}/${entry.file}`;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const fontData = new Map();
|
|
129
|
+
|
|
130
|
+
export const loadFontData = (name) => {
|
|
131
|
+
let data = fontData.get(name);
|
|
132
|
+
if (!data) {
|
|
133
|
+
const bytes = readFileSync(fontPath(name));
|
|
134
|
+
data = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
|
|
135
|
+
fontData.set(name, data);
|
|
136
|
+
}
|
|
137
|
+
return data;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
// A named font set from fonts.json as CanvasKit objects:
|
|
141
|
+
// typefaces the "regular", "bold" and each fallback font as a Typeface
|
|
142
|
+
// (a collection such as Noto Sans CJK yields its preferred face)
|
|
143
|
+
// fontMgr every file of the set registered by family name, for the
|
|
144
|
+
// Paragraph API; a collection registers all of its families
|
|
145
|
+
// families family names for ParagraphStyle.textStyle.fontFamilies, in
|
|
146
|
+
// lookup order
|
|
147
|
+
export const loadFontSet = (CanvasKit, setName = "terminal") => {
|
|
148
|
+
const { sets, fonts } = fontCatalogue();
|
|
149
|
+
const set = sets[setName];
|
|
150
|
+
if (!set) throw new Error(`unknown font set ${JSON.stringify(setName)}`);
|
|
151
|
+
const names = [set.regular, set.bold, ...(set.fallback ?? [])].filter(Boolean);
|
|
152
|
+
const buffers = names.map(loadFontData);
|
|
153
|
+
const fontMgr = CanvasKit.FontMgr.FromData(...buffers);
|
|
154
|
+
if (!fontMgr) throw new Error("FontMgr.FromData failed");
|
|
155
|
+
const typefaces = {};
|
|
156
|
+
names.forEach((name, index) => {
|
|
157
|
+
// A collection's "preferred" family picks the face (Noto Sans CJK TC for
|
|
158
|
+
// Taiwanese glyph forms); a single-face file loads directly.
|
|
159
|
+
const preferred = fonts[name].preferred;
|
|
160
|
+
const typeface = preferred
|
|
161
|
+
? fontMgr.matchFamilyStyle(preferred, {})
|
|
162
|
+
: CanvasKit.Typeface.MakeFreeTypeFaceFromData(buffers[index]);
|
|
163
|
+
if (!typeface) throw new Error(`cannot load font ${name} (${fonts[name].file})`);
|
|
164
|
+
typefaces[name] = typeface;
|
|
165
|
+
});
|
|
166
|
+
const families = names.flatMap((name) => fonts[name].families ?? [name]);
|
|
167
|
+
return {
|
|
168
|
+
set,
|
|
169
|
+
names,
|
|
170
|
+
typefaces,
|
|
171
|
+
regular: typefaces[set.regular],
|
|
172
|
+
bold: set.bold ? typefaces[set.bold] : null,
|
|
173
|
+
fallback: (set.fallback ?? []).map((name) => typefaces[name]),
|
|
174
|
+
fontMgr,
|
|
175
|
+
families,
|
|
176
|
+
delete() {
|
|
177
|
+
for (const typeface of Object.values(typefaces)) typeface.delete();
|
|
178
|
+
fontMgr.delete();
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Copyright (c) 2011 Google Inc. All rights reserved.
|
|
2
|
+
//
|
|
3
|
+
// Redistribution and use in source and binary forms, with or without
|
|
4
|
+
// modification, are permitted provided that the following conditions are
|
|
5
|
+
// met:
|
|
6
|
+
//
|
|
7
|
+
// * Redistributions of source code must retain the above copyright
|
|
8
|
+
// notice, this list of conditions and the following disclaimer.
|
|
9
|
+
// * Redistributions in binary form must reproduce the above
|
|
10
|
+
// copyright notice, this list of conditions and the following disclaimer
|
|
11
|
+
// in the documentation and/or other materials provided with the
|
|
12
|
+
// distribution.
|
|
13
|
+
// * Neither the name of Google Inc. nor the names of its
|
|
14
|
+
// contributors may be used to endorse or promote products derived from
|
|
15
|
+
// this software without specific prior written permission.
|
|
16
|
+
//
|
|
17
|
+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
18
|
+
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
19
|
+
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
20
|
+
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
21
|
+
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
22
|
+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
23
|
+
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
24
|
+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
25
|
+
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
26
|
+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
27
|
+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
28
|
+
|
|
29
|
+
--------------------------------------------------------------------------------
|