Begin move to k3Menu

This commit is contained in:
Mid 2025-07-06 17:58:57 +03:00
parent c4d808833a
commit 93b885cb43
12 changed files with 410 additions and 547 deletions

View File

@ -199,37 +199,6 @@ foundStart:
return len;
}
static inline void pr(int c) {
asm volatile("outb %%al, $0xE9" :: "a"(c) :);
}
static inline void pri(size_t num) {
char buf[16] = {};
int i = 16;
do {
buf[--i] = num % 10;
num /= 10;
} while(num);
for(; i < 16; i++) {
pr(buf[i] + '0');
}
}
static inline void prs(const Str16 *str) {
for(int i = 0; i < str->len; i++) {
pr(str->data[i]);
}
}
static inline void prcs(const char *str) {
while(*str) {
pr(*str);
str++;
}
}
// I don't like this.
// Biggest ugly by far is how it operates in 512-byte chunks, even though lean_read_inode already handles unaligned access
uint64_t find_child(const struct INode *node, const Str16 *name) {

View File

@ -74,6 +74,34 @@ static inline unsigned char std_bytecomp(size_t len, const void *one_, const voi
#define std_min(a, b) ({__typeof__(a) _a = (a); __typeof__(b) _b = (b); _a<_b?_a:_b;})
#define std_max(a, b) ({__typeof__(a) _a = (a); __typeof__(b) _b = (b); _a>_b?_a:_b;})
static inline void pr(int c) {
asm volatile("outb %%al, $0xE9" :: "a"(c) :);
}
static inline void pri(size_t num) {
char buf[16] = {};
int i = 16;
do {
buf[--i] = num % 10;
num /= 10;
} while(num);
for(; i < 16; i++) {
pr(buf[i] + '0');
}
}
static inline void prs(const Str16 *str) {
for(int i = 0; i < str->len; i++) {
pr(str->data[i]);
}
}
static inline void prcs(const char *str) {
while(*str) {
pr(*str);
str++;
}
}
//#define S16_ARG(str) ((Str16*) &(struct {uint16_t len; char content[sizeof(str) - 1]}) {sizeof(str) - 1, (str)})
#endif

View File

@ -4,8 +4,13 @@
#include<stdint.h>
typedef enum {
LUMA_VID_COMMAND_END = 0, LUMA_VID_COMMAND_CLEAR = 1, LUMA_VID_COMMAND_RECT = 2, LUMA_VID_COMMAND_IMAGE = 3, LUMA_VID_COMMAND_IMAGE_NEW = 4, LUMA_VID_COMMAND_SET_COLOR_FLAT = 5,
LUMA_VID_COMMAND_SET_COLOR_GRAD = 6, LUMA_VID_COMMAND_IMAGE_DEL = 7, LUMA_VID_COMMAND_TEXT = 8, LUMA_VID_COMMAND_NEW_COLOR_FLAT = 9, LUMA_VID_COMMAND_NEW_COLOR_GRAD = 10, LUMA_VID_COMMAND_IMAGE_WRITE = 11,
LUMA_VID_COMMAND_END = 0, LUMA_VID_COMMAND_CLEAR = 1,
LUMA_VID_COMMAND_RECT = 2, LUMA_VID_COMMAND_IMAGE = 3,
LUMA_VID_COMMAND_IMAGE_NEW = 4, LUMA_VID_COMMAND_SET_COLOR_FLAT = 5,
LUMA_VID_COMMAND_SET_COLOR_GRAD = 6, LUMA_VID_COMMAND_IMAGE_DEL = 7,
LUMA_VID_COMMAND_TEXT = 8, LUMA_VID_COMMAND_NEW_COLOR_FLAT = 9,
LUMA_VID_COMMAND_NEW_COLOR_GRAD = 10, LUMA_VID_COMMAND_IMAGE_WRITE = 11,
LUMA_VID_COMMAND_TEXT_EXTENT = 12
} LumaVidCommandOp;
typedef enum {
@ -19,6 +24,12 @@ typedef enum {
LUMA_VID_ALIGN_BOTTOM_RIGHT = 3,
} LumaVidAlign;
typedef enum {
LUMA_VID_TEXT_ALIGN_LEFT = 0,
LUMA_VID_TEXT_ALIGN_CENTER = 1,
LUMA_VID_TEXT_ALIGN_RIGHT = 2,
} LumaVidTextAlign;
typedef union {
uint8_t op;
struct {
@ -73,6 +84,7 @@ typedef union {
uint16_t x;
uint16_t len;
uint16_t wall;
uint8_t align;
uint8_t data[];
} __attribute__((packed)) text;
struct {
@ -83,6 +95,14 @@ typedef union {
uint16_t len;
uint8_t data[];
} __attribute__((packed)) imageWrite;
struct {
uint8_t op;
uint16_t h;
uint16_t w;
uint16_t len;
uint16_t wall;
uint8_t data[];
} __attribute__((packed)) textExtent;
} __attribute__((packed)) LumaVidCommand;
#endif

View File

@ -129,83 +129,112 @@ __attribute__((optimize("Ofast"))) static void image(Image *img, uint16_t subX,
}
}
__attribute__((optimize("Ofast"))) static void text(const char *str, size_t len, uint16_t x, uint16_t y, uint16_t wall) {
if(wall <= x) wall = 320;
static const uint8_t font[] = {
0x20, 0x31, 0x95, 0x00, 0x21, 0x17, 0x15, 0x5f, 0x22, 0x32, 0x15, 0x2d,
0x23, 0x47, 0x15, 0xaa, 0xaf, 0x5f, 0x05, 0x24, 0x48, 0x15, 0x5e, 0x65,
0xcc, 0x47, 0x25, 0x57, 0x15, 0x6b, 0x1d, 0xc2, 0xb5, 0x06, 0x26, 0x57,
0x15, 0x44, 0x19, 0x9b, 0x92, 0x05, 0x27, 0x12, 0x15, 0x03, 0x28, 0x28,
0x15, 0x56, 0x95, 0x29, 0x28, 0x15, 0xa9, 0x6a, 0x2a, 0x34, 0x15, 0xfa,
0x05, 0x2b, 0x55, 0x35, 0x84, 0x7c, 0x42, 0x00, 0x2c, 0x22, 0x75, 0x06,
0x2d, 0x31, 0x55, 0x07, 0x2e, 0x11, 0x75, 0x01, 0x2f, 0x37, 0x15, 0xa4,
0xa4, 0x04, 0x30, 0x47, 0x15, 0x96, 0xb9, 0x99, 0x06, 0x31, 0x37, 0x15,
0x93, 0x24, 0x1d, 0x32, 0x47, 0x15, 0x87, 0x48, 0x12, 0x0f, 0x33, 0x47,
0x15, 0x87, 0x68, 0x88, 0x07, 0x34, 0x57, 0x15, 0x8c, 0xa9, 0xf4, 0x11,
0x02, 0x35, 0x47, 0x15, 0x1f, 0x71, 0x88, 0x07, 0x36, 0x47, 0x15, 0x1e,
0x71, 0x99, 0x06, 0x37, 0x47, 0x15, 0x8f, 0x44, 0x22, 0x01, 0x38, 0x47,
0x15, 0x96, 0x69, 0x99, 0x06, 0x39, 0x47, 0x15, 0x96, 0xe9, 0x88, 0x07,
0x3a, 0x15, 0x35, 0x11, 0x3b, 0x26, 0x35, 0x02, 0x06, 0x3c, 0x35, 0x25,
0x54, 0x44, 0x3d, 0x43, 0x45, 0x0f, 0x0f, 0x3e, 0x35, 0x25, 0x11, 0x15,
0x3f, 0x37, 0x15, 0x2a, 0x25, 0x08, 0x40, 0x57, 0x15, 0x2e, 0xf6, 0xde,
0x82, 0x03, 0x41, 0x57, 0x15, 0x84, 0x28, 0xe5, 0x62, 0x04, 0x42, 0x47,
0x15, 0x97, 0x79, 0x99, 0x07, 0x43, 0x47, 0x15, 0x1e, 0x11, 0x11, 0x0e,
0x44, 0x47, 0x15, 0x97, 0x99, 0x99, 0x07, 0x45, 0x47, 0x15, 0x1f, 0xf1,
0x11, 0x0f, 0x46, 0x47, 0x15, 0x1f, 0xf1, 0x11, 0x01, 0x47, 0x47, 0x15,
0x1e, 0x11, 0x9d, 0x0e, 0x48, 0x47, 0x15, 0x99, 0xf9, 0x99, 0x09, 0x49,
0x37, 0x15, 0x97, 0x24, 0x1d, 0x4a, 0x37, 0x15, 0x24, 0x49, 0x0e, 0x4b,
0x57, 0x15, 0x31, 0x95, 0x93, 0x52, 0x04, 0x4c, 0x47, 0x15, 0x11, 0x11,
0x11, 0x0f, 0x4d, 0x47, 0x15, 0xb9, 0xbf, 0x99, 0x09, 0x4e, 0x47, 0x15,
0xb9, 0xbb, 0xdd, 0x09, 0x4f, 0x47, 0x15, 0x96, 0x99, 0x99, 0x06, 0x50,
0x47, 0x15, 0x97, 0x79, 0x11, 0x01, 0x51, 0x48, 0x15, 0x96, 0x99, 0x99,
0x86, 0x52, 0x57, 0x15, 0x27, 0xa5, 0x53, 0x52, 0x04, 0x53, 0x47, 0x15,
0x1e, 0x61, 0x88, 0x07, 0x54, 0x57, 0x15, 0x9f, 0x10, 0x42, 0x08, 0x01,
0x55, 0x47, 0x15, 0x99, 0x99, 0x99, 0x06, 0x56, 0x57, 0x15, 0x31, 0x2a,
0xa5, 0x08, 0x01, 0x57, 0x57, 0x15, 0x31, 0xd6, 0xba, 0x94, 0x02, 0x58,
0x47, 0x15, 0x99, 0x66, 0x96, 0x09, 0x59, 0x57, 0x15, 0x51, 0x29, 0x42,
0x08, 0x01, 0x5a, 0x47, 0x15, 0x8f, 0x24, 0x12, 0x0f, 0x5b, 0x28, 0x15,
0x57, 0xd5, 0x5c, 0x37, 0x15, 0x89, 0x24, 0x12, 0x5d, 0x28, 0x15, 0xab,
0xea, 0x5e, 0x53, 0x25, 0x44, 0x45, 0x5f, 0x51, 0x95, 0x1f, 0x60, 0x22,
0x15, 0x09, 0x61, 0x45, 0x35, 0x87, 0x9e, 0x0e, 0x62, 0x47, 0x15, 0x11,
0x97, 0x99, 0x07, 0x63, 0x45, 0x35, 0x1e, 0x11, 0x0e, 0x64, 0x47, 0x15,
0x88, 0x9e, 0x99, 0x0e, 0x65, 0x45, 0x35, 0x96, 0x1f, 0x0e, 0x66, 0x47,
0x15, 0x2c, 0x2f, 0x22, 0x02, 0x67, 0x47, 0x35, 0x5e, 0x12, 0x9f, 0x06,
0x68, 0x47, 0x15, 0x11, 0xb5, 0x99, 0x09, 0x69, 0x27, 0x15, 0xb2, 0x2a,
0x6a, 0x39, 0x15, 0x84, 0x49, 0x92, 0x03, 0x6b, 0x57, 0x15, 0x21, 0xa4,
0x72, 0x52, 0x04, 0x6c, 0x37, 0x15, 0x93, 0x24, 0x19, 0x6d, 0x55, 0x35,
0xab, 0xd6, 0x5a, 0x01, 0x6e, 0x45, 0x35, 0xb5, 0x99, 0x09, 0x6f, 0x45,
0x35, 0x96, 0x99, 0x06, 0x70, 0x47, 0x35, 0x97, 0x99, 0x17, 0x01, 0x71,
0x47, 0x35, 0x9e, 0x99, 0x8e, 0x08, 0x72, 0x35, 0x35, 0x4f, 0x12, 0x73,
0x45, 0x35, 0x1f, 0x86, 0x07, 0x74, 0x46, 0x25, 0xf2, 0x22, 0xc2, 0x75,
0x45, 0x35, 0x99, 0x99, 0x0e, 0x76, 0x45, 0x35, 0xa9, 0x4a, 0x04, 0x77,
0x55, 0x35, 0xb1, 0x56, 0xa5, 0x00, 0x78, 0x45, 0x35, 0x69, 0x66, 0x09,
0x79, 0x47, 0x35, 0xa9, 0x4a, 0x44, 0x03, 0x7a, 0x45, 0x35, 0x4f, 0x12,
0x0f, 0x7b, 0x39, 0x15, 0x94, 0x14, 0x49, 0x04, 0x7c, 0x18, 0x15, 0xff,
0x7d, 0x39, 0x15, 0x91, 0x44, 0x49, 0x01, 0x7e, 0x52, 0x45, 0x36, 0x01
};
static const uint8_t font[] = {
0x20, 0x31, 0x95, 0x00, 0x21, 0x17, 0x15, 0x5f, 0x22, 0x32, 0x15, 0x2d,
0x23, 0x47, 0x15, 0xaa, 0xaf, 0x5f, 0x05, 0x24, 0x48, 0x15, 0x5e, 0x65,
0xcc, 0x47, 0x25, 0x57, 0x15, 0x6b, 0x1d, 0xc2, 0xb5, 0x06, 0x26, 0x57,
0x15, 0x44, 0x19, 0x9b, 0x92, 0x05, 0x27, 0x12, 0x15, 0x03, 0x28, 0x28,
0x15, 0x56, 0x95, 0x29, 0x28, 0x15, 0xa9, 0x6a, 0x2a, 0x34, 0x15, 0xfa,
0x05, 0x2b, 0x55, 0x35, 0x84, 0x7c, 0x42, 0x00, 0x2c, 0x22, 0x75, 0x06,
0x2d, 0x31, 0x55, 0x07, 0x2e, 0x11, 0x75, 0x01, 0x2f, 0x37, 0x15, 0xa4,
0xa4, 0x04, 0x30, 0x47, 0x15, 0x96, 0xb9, 0x99, 0x06, 0x31, 0x37, 0x15,
0x93, 0x24, 0x1d, 0x32, 0x47, 0x15, 0x87, 0x48, 0x12, 0x0f, 0x33, 0x47,
0x15, 0x87, 0x68, 0x88, 0x07, 0x34, 0x57, 0x15, 0x8c, 0xa9, 0xf4, 0x11,
0x02, 0x35, 0x47, 0x15, 0x1f, 0x71, 0x88, 0x07, 0x36, 0x47, 0x15, 0x1e,
0x71, 0x99, 0x06, 0x37, 0x47, 0x15, 0x8f, 0x44, 0x22, 0x01, 0x38, 0x47,
0x15, 0x96, 0x69, 0x99, 0x06, 0x39, 0x47, 0x15, 0x96, 0xe9, 0x88, 0x07,
0x3a, 0x15, 0x35, 0x11, 0x3b, 0x26, 0x35, 0x02, 0x06, 0x3c, 0x35, 0x25,
0x54, 0x44, 0x3d, 0x43, 0x45, 0x0f, 0x0f, 0x3e, 0x35, 0x25, 0x11, 0x15,
0x3f, 0x37, 0x15, 0x2a, 0x25, 0x08, 0x40, 0x57, 0x15, 0x2e, 0xf6, 0xde,
0x82, 0x03, 0x41, 0x57, 0x15, 0x84, 0x28, 0xe5, 0x62, 0x04, 0x42, 0x47,
0x15, 0x97, 0x79, 0x99, 0x07, 0x43, 0x47, 0x15, 0x1e, 0x11, 0x11, 0x0e,
0x44, 0x47, 0x15, 0x97, 0x99, 0x99, 0x07, 0x45, 0x47, 0x15, 0x1f, 0xf1,
0x11, 0x0f, 0x46, 0x47, 0x15, 0x1f, 0xf1, 0x11, 0x01, 0x47, 0x47, 0x15,
0x1e, 0x11, 0x9d, 0x0e, 0x48, 0x47, 0x15, 0x99, 0xf9, 0x99, 0x09, 0x49,
0x37, 0x15, 0x97, 0x24, 0x1d, 0x4a, 0x37, 0x15, 0x24, 0x49, 0x0e, 0x4b,
0x57, 0x15, 0x31, 0x95, 0x93, 0x52, 0x04, 0x4c, 0x47, 0x15, 0x11, 0x11,
0x11, 0x0f, 0x4d, 0x47, 0x15, 0xb9, 0xbf, 0x99, 0x09, 0x4e, 0x47, 0x15,
0xb9, 0xbb, 0xdd, 0x09, 0x4f, 0x47, 0x15, 0x96, 0x99, 0x99, 0x06, 0x50,
0x47, 0x15, 0x97, 0x79, 0x11, 0x01, 0x51, 0x48, 0x15, 0x96, 0x99, 0x99,
0x86, 0x52, 0x57, 0x15, 0x27, 0xa5, 0x53, 0x52, 0x04, 0x53, 0x47, 0x15,
0x1e, 0x61, 0x88, 0x07, 0x54, 0x57, 0x15, 0x9f, 0x10, 0x42, 0x08, 0x01,
0x55, 0x47, 0x15, 0x99, 0x99, 0x99, 0x06, 0x56, 0x57, 0x15, 0x31, 0x2a,
0xa5, 0x08, 0x01, 0x57, 0x57, 0x15, 0x31, 0xd6, 0xba, 0x94, 0x02, 0x58,
0x47, 0x15, 0x99, 0x66, 0x96, 0x09, 0x59, 0x57, 0x15, 0x51, 0x29, 0x42,
0x08, 0x01, 0x5a, 0x47, 0x15, 0x8f, 0x24, 0x12, 0x0f, 0x5b, 0x28, 0x15,
0x57, 0xd5, 0x5c, 0x37, 0x15, 0x89, 0x24, 0x12, 0x5d, 0x28, 0x15, 0xab,
0xea, 0x5e, 0x53, 0x25, 0x44, 0x45, 0x5f, 0x51, 0x95, 0x1f, 0x60, 0x22,
0x15, 0x09, 0x61, 0x45, 0x35, 0x87, 0x9e, 0x0e, 0x62, 0x47, 0x15, 0x11,
0x97, 0x99, 0x07, 0x63, 0x45, 0x35, 0x1e, 0x11, 0x0e, 0x64, 0x47, 0x15,
0x88, 0x9e, 0x99, 0x0e, 0x65, 0x45, 0x35, 0x96, 0x1f, 0x0e, 0x66, 0x47,
0x15, 0x2c, 0x2f, 0x22, 0x02, 0x67, 0x47, 0x35, 0x5e, 0x12, 0x9f, 0x06,
0x68, 0x47, 0x15, 0x11, 0xb5, 0x99, 0x09, 0x69, 0x27, 0x15, 0xb2, 0x2a,
0x6a, 0x39, 0x15, 0x84, 0x49, 0x92, 0x03, 0x6b, 0x57, 0x15, 0x21, 0xa4,
0x72, 0x52, 0x04, 0x6c, 0x37, 0x15, 0x93, 0x24, 0x19, 0x6d, 0x55, 0x35,
0xab, 0xd6, 0x5a, 0x01, 0x6e, 0x45, 0x35, 0xb5, 0x99, 0x09, 0x6f, 0x45,
0x35, 0x96, 0x99, 0x06, 0x70, 0x47, 0x35, 0x97, 0x99, 0x17, 0x01, 0x71,
0x47, 0x35, 0x9e, 0x99, 0x8e, 0x08, 0x72, 0x35, 0x35, 0x4f, 0x12, 0x73,
0x45, 0x35, 0x1f, 0x86, 0x07, 0x74, 0x46, 0x25, 0xf2, 0x22, 0xc2, 0x75,
0x45, 0x35, 0x99, 0x99, 0x0e, 0x76, 0x45, 0x35, 0xa9, 0x4a, 0x04, 0x77,
0x55, 0x35, 0xb1, 0x56, 0xa5, 0x00, 0x78, 0x45, 0x35, 0x69, 0x66, 0x09,
0x79, 0x47, 0x35, 0xa9, 0x4a, 0x44, 0x03, 0x7a, 0x45, 0x35, 0x4f, 0x12,
0x0f, 0x7b, 0x39, 0x15, 0x94, 0x14, 0x49, 0x04, 0x7c, 0x18, 0x15, 0xff,
0x7d, 0x39, 0x15, 0x91, 0x44, 0x49, 0x01, 0x7e, 0x52, 0x45, 0x36, 0x01
};
const uint8_t *find(char c) {
const uint8_t *a = font;
while(a - font < sizeof(font)) {
if(*a == c) {
return a;
} else {
a += 3 + ((a[1] & 15) * (a[1] >> 4) + 7) / 8;
}
const uint8_t *find(char c) {
const uint8_t *a = font;
while(a - font < sizeof(font)) {
if(*a == c) {
return a;
} else {
a += 3 + ((a[1] & 15) * (a[1] >> 4) + 7) / 8;
}
return NULL;
}
return NULL;
}
__attribute__((optimize("Ofast"))) static void line_extent(const char **strp, size_t len, size_t wall, uint16_t *w, uint16_t *h) {
*w = 0;
*h = 13;
const char *str = *strp;
while(len--) {
if(*str == 10) {
str++;
*strp = str;
return;
}
const uint8_t *data = find(*(str++));
if(data == NULL) continue;
uint8_t width = data[2] & 0x0F;
if(*w + width >= wall) {
if(*w != 0) {
str--;
}
*strp = str;
return;
}
*w += width;
}
*strp = str;
}
__attribute__((optimize("Ofast"))) static void text_line(const char *str, size_t len, uint16_t x, uint16_t y, uint16_t wall) {
if(wall <= x) wall = 320;
uint16_t startX = x;
int col = colorFunc(0, 0);
while(len--) {
if(*str == 10) {
str++;
x = startX;
y += 13;
continue;
return;
}
const uint8_t *data = find(*(str++));
@ -216,8 +245,8 @@ __attribute__((optimize("Ofast"))) static void text(const char *str, size_t len,
uint8_t width = data[2] & 0x0F;
if(x + width >= wall) {
x = startX;
y += 13;
return;
}
for(int ix = 0; ix < (data[1] >> 4); ix++) {
@ -234,6 +263,53 @@ __attribute__((optimize("Ofast"))) static void text(const char *str, size_t len,
}
}
__attribute__((optimize("Ofast"))) static void text_extent(const char *str, size_t len, size_t wall, uint16_t *w, uint16_t *h) {
*w = 0;
*h = 0;
const char *str2 = str;
while(len) {
uint16_t lineWidth = 0, lineHeight = 0;
line_extent(&str2, len, wall, &lineWidth, &lineHeight);
len = str + len - str2;
if(*w < lineWidth) {
*w = lineWidth;
}
*h += lineHeight;
}
}
__attribute__((optimize("Ofast"))) static void text(const char *str, size_t len, uint16_t x, uint16_t y, uint16_t wall, uint8_t align) {
if(wall <= x) wall = 320;
uint16_t lineW, lineH;
while(len) {
const char *lineEnd = str;
line_extent(&lineEnd, len, wall, &lineW, &lineH);
if(align == LUMA_VID_TEXT_ALIGN_LEFT) {
text_line(str, len, x, y, wall);
} else if(align == LUMA_VID_TEXT_ALIGN_CENTER) {
text_line(str, len, (wall + x) / 2 - lineW / 2, y, wall);
} else if(align == LUMA_VID_TEXT_ALIGN_RIGHT) {
text_line(str, len, wall - lineW, y, wall);
}
if(lineEnd == str) {
break;
}
len = str + len - lineEnd;
str = lineEnd;
y += lineH;
}
}
static void compileCommandList(uint8_t *src, uint8_t *dst) {
size_t len = 0;
while(1) {
@ -410,6 +486,9 @@ static void compileCommandList(uint8_t *src, uint8_t *dst) {
} else if(cmd->op == LUMA_VID_COMMAND_IMAGE_DEL) {
src += sizeof(cmd->imageDel);
} else if(cmd->op == LUMA_VID_COMMAND_TEXT) {
dst[len++] = 0x68;
*((uint32_t*) &dst[len]) = cmd->text.align;
len += 4;
dst[len++] = 0x68;
*((uint32_t*) &dst[len]) = cmd->text.wall;
len += 4;
@ -435,7 +514,7 @@ static void compileCommandList(uint8_t *src, uint8_t *dst) {
len += cmd->text.len;
dst[len++] = 0x83; /* add esp, imm8 */
dst[len++] = 0xC4;
dst[len++] = 0x14;
dst[len++] = 0x18;
src += sizeof(cmd->text) + cmd->text.len;
} else if(cmd->op == LUMA_VID_COMMAND_NEW_COLOR_FLAT) {
MiniCol minicol = ((cmd->colorFlat.r & ~7) << 8) | ((cmd->colorFlat.g & ~3) << 3) | (cmd->colorFlat.b >> 3);
@ -452,6 +531,12 @@ static void compileCommandList(uint8_t *src, uint8_t *dst) {
}
q_reavg();
src += sizeof(cmd->colorGrad);
} else if(cmd->op == LUMA_VID_COMMAND_TEXT_EXTENT) {
uint16_t w, h;
text_extent(cmd->textExtent.data, cmd->textExtent.len, cmd->textExtent.wall, &w, &h);
cmd->textExtent.w = w;
cmd->textExtent.h = h;
src += sizeof(cmd->textExtent) + cmd->textExtent.len;
}
}
}

View File

@ -10,4 +10,4 @@ mod: $(OBJECTS)
../../build/wm/%.o: %.c
mkdir -p $(@D)
i386-elf-gcc -march=i386 -Isrc -Os -pie -nodefaultlibs -nostdlib -nostartfiles -DEEBIE_MEMSET=__builtin_memset -fms-extensions -fomit-frame-pointer -c -o $@ -ffreestanding -mgeneral-regs-only -std=gnu11 -Wall $<
i386-elf-gcc -march=i386 -Isrc -Os -pie -nodefaultlibs -nostdlib -nostartfiles -DEEBIE_MEMSET=__builtin_memset -Dmalloc=tiny_malloc -Dcalloc=tiny_calloc -Dfree=tiny_free -Drealloc=tiny_realloc -fms-extensions -fomit-frame-pointer -c -o $@ -ffreestanding -mgeneral-regs-only -std=gnu11 -Wall $<

View File

@ -13,38 +13,6 @@ void ebml_reader_init(EBMLReader *this) {
static uint64_t VARINT_MASKS[] = {0, 0x80L, 0xC000L, 0xE00000L, 0xF0000000L, 0xF800000000L, 0xFC0000000000L, 0xFE000000000000L, 0L};
#include"../../std.h"
static inline void pr(int c) {
asm volatile("outb %%al, $0xE9" :: "a"(c) :);
}
static inline void pri(size_t num) {
char buf[25] = {};
int i = 16;
do {
buf[--i] = num % 10;
num /= 10;
} while(num);
for(; i < 16; i++) {
pr(buf[i] + '0');
}
}
static inline void prs(const Str16 *str) {
for(int i = 0; i < str->len; i++) {
pr(str->data[i]);
}
}
static inline void prcs(const char *str) {
while(*str) {
pr(*str);
str++;
}
}
#define I(x) ((uint64_t)(x))
static int read_varint(const uint8_t *data, size_t length, uint64_t *result) {
if(data[0] & 0x80) {

View File

@ -8,7 +8,7 @@
#define dynstr16_ends_with(ds16, cstr) (((ds16)->len < sizeof(cstr) - 1) ? 0 : !std_bytecomp(sizeof(cstr) - 1, (cstr), (ds16)->data + (ds16)->len - sizeof(cstr) + 1))
struct Ctx {
/*struct Ctx {
Str16 *cd;
size_t cdSize;
} ;
@ -190,12 +190,12 @@ static int files_window_back_cmd(void *ud, const DynStr16 *cmdline) {
update_listing(w);
return 1;
}
}*/
void FilesWindowCreate() {
if(!is_free_space()) return;
struct GList *list = glist_new(0, 0, 0, 0);
/*struct GList *list = glist_new(0, 0, 0, 0);
static const char name[] = "File Explorer";
struct GWindow *w = gwindow_new(0, 0, 0, 0, g_dynstr16_new(sizeof(name) - 1, sizeof(name) - 1, name), (struct GObj*) list, 0);
@ -215,5 +215,5 @@ void FilesWindowCreate() {
static const char backcmd[] = "back";
gwindow_regcmd(w, g_str16_new(sizeof(backcmd) - 1, backcmd), w, files_window_back_cmd);
add_window(w);
add_window(w);*/
}

View File

@ -12,6 +12,7 @@
#include"logserver.h"
#include"progdb.h"
#include"io.h"
#include"k3menu.h"
asm("modentry:\n"
"mov $stack + 2048, %esp\n"
@ -24,37 +25,6 @@ char stack[2048];
void *VidLink;
void *FSLink;
static inline void pr(int c) {
asm volatile("outb %%al, $0xE9" :: "a"(c) :);
}
static inline void pri(size_t num) {
char buf[16] = {};
int i = 16;
do {
buf[--i] = num % 10;
num /= 10;
} while(num);
for(; i < 16; i++) {
pr(buf[i] + '0');
}
}
static inline void prs(const Str16 *str) {
for(int i = 0; i < str->len; i++) {
pr(str->data[i]);
}
}
static inline void prcs(const char *str) {
while(*str) {
pr(*str);
str++;
}
}
void initvid(int col) {
static uint8_t logo[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
@ -275,241 +245,106 @@ void drawdesk(int x, int y, int w, int h) {
sys_signal_wait(VidLink, NULL);
}
struct GContainer *ui;
struct k3MScreen *ui;
struct k3MTextInput *cmdline;
struct GObj *windowTree;
struct WTreeNode *windowTreeRoot;
struct WTreeNode *windowTreeFocus;
struct GText *cmdline;
struct WindowTree {
bool split;
union {
struct GWindow gw;
struct {
struct WindowTree *a;
struct WindowTree *b;
} sub;
};
};
struct WindowTree *windowTree = NULL;
static void focus_next() {
if(windowTreeFocus->window) {
windowTreeFocus->window->focus = 0;
}
static int dirtyX1 = INT32_MAX;
static int dirtyX2 = INT32_MIN;
static int dirtyY1 = INT32_MAX;
static int dirtyY2 = INT32_MIN;
void dirty(int x1, int y1, int w, int h) {
int x2 = x1 + w;
int y2 = y1 + h;
if(dirtyX1 > x1) {
dirtyX1 = x1;
}
if(windowTreeFocus->parent) {
if(windowTreeFocus->parent->first == windowTreeFocus) {
windowTreeFocus = windowTreeFocus->parent->second;
} else if(windowTreeFocus->parent->second == windowTreeFocus) {
if(windowTreeFocus->parent->parent) {
windowTreeFocus = windowTreeFocus->parent->parent->second;
} else {
windowTreeFocus = windowTreeRoot;
}
while(!windowTreeFocus->window) {
windowTreeFocus = windowTreeFocus->first;
}
}
if(dirtyX2 < x2) {
dirtyX2 = x2;
}
if(windowTreeFocus->window) {
windowTreeFocus->window->focus = 1;
if(dirtyY1 > y1) {
dirtyY1 = y1;
}
if(dirtyY2 < y2) {
dirtyY2 = y2;
}
}
static KeyReactFunc baseinputonkey;
static void inputonkey(struct GObj *_, struct GKeyEvent ev) {
if(ev.scancode == LK_ENTER) {
struct GText *t = (void*) _;
perform(t->data);
t->data->len = 0;
cmdline->focus ^= 1;
windowTree->focus ^= 1;
dirty_obj(_);
} else {
baseinputonkey(_, ev);
}
}
static void wtree_render_recur(struct WTreeNode *node) {
if(node->window) {
if(node->window->onRender) {
node->window->onRender((struct GObj*) node->window);
}
} else {
if(node->first) wtree_render_recur(node->first);
if(node->second) wtree_render_recur(node->second);
}
}
static void wtree_render(struct GObj *this) {
wtree_render_recur(windowTreeRoot);
}
static void wtree_key(struct GObj *this, struct GKeyEvent ev) {
if(this->focus == 0) return;
if(windowTreeFocus && windowTreeFocus->window && windowTreeFocus->window->onKey) {
windowTreeFocus->window->onKey((struct GObj*) windowTreeFocus->window, ev);
}
}
static void wtree_fitter_recur(struct WTreeNode *node, uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
if(node->window) {
node->window->x = x;
node->window->y = y;
node->window->w = w;
node->window->h = h;
node->window->fitter((struct GObj*) node->window);
} else {
if(node->vertical) {
if(node->first) {
wtree_fitter_recur(node->first, x, y, w, h / 2);
}
if(node->second) {
wtree_fitter_recur(node->second, x, y + h / 2, w, h / 2);
}
static struct WindowTree *find_free_space(struct WindowTree *wt) {
if(wt->split) {
if(!wt->sub.a) {
wt->sub.a = tiny_calloc(1, sizeof(*wt->sub.a));
return wt->sub.a;
} else {
if(node->first) {
wtree_fitter_recur(node->first, x, y, w / 2, h);
}
if(node->second) {
wtree_fitter_recur(node->second, x + w / 2, y, w / 2, h);
}
wt = find_free_space(wt->sub.a);
if(wt) return wt;
}
}
}
static void wtree_fitter(struct GObj *_) {
wtree_fitter_recur(windowTreeRoot, windowTree->x, windowTree->y, windowTree->w, windowTree->h);
}
static void wtree_destroy_recur(struct WTreeNode *node) {
if(node->window) node->window->destroy((struct GObj*) node->window);
else {
if(node->first) wtree_destroy_recur(node->first);
if(node->second) wtree_destroy_recur(node->second);
}
}
static void wtree_destroy(struct GObj *_) {
wtree_destroy_recur(windowTreeRoot);
tiny_free(_);
}
static void init_ui() {
// Contains window tree and command bar
ui = gcont_new(0, 0, 320, 240, NULL);
// Contains windows
windowTree = tiny_calloc(sizeof(*windowTree), 1);
windowTree->onRender = wtree_render;
windowTree->onKey = wtree_key;
windowTree->destroy = wtree_destroy;
windowTree->fitter = wtree_fitter;
windowTree->x = windowTree->y = 0;
windowTree->w = 320;
windowTree->h = 226;
windowTree->focus = 0;
windowTreeRoot = tiny_calloc(sizeof(*windowTreeRoot), 1);
windowTreeRoot->vertical = 0;
windowTreeRoot->window = NULL;
windowTreeRoot->parent = NULL;
windowTreeRoot->first = NULL;
windowTreeRoot->second = NULL;
windowTreeFocus = windowTreeRoot;
gcont_add(ui, 0, (struct GObj*) windowTree);
static const char asdf[] = "Enter command, e.g. help";
cmdline = gtext_new(0, 226, 320, 14, g_dynstr16_new(sizeof(asdf) - 1, sizeof(asdf) - 1, asdf), NULL);
baseinputonkey = cmdline->onKey;
cmdline->onKey = inputonkey;
cmdline->focus = 1;
gcont_add(ui, 0, (struct GObj*) cmdline);
ui->focus = 1;
}
int add_window(struct GWindow *w) {
if(!windowTreeFocus) {
return 0;
}
if(windowTreeFocus && windowTreeFocus->window) {
windowTreeFocus->window->focus = 0;
}
if(!windowTreeFocus->window) {
windowTreeFocus->window = w;
} else {
struct WTreeNode *top = tiny_calloc(sizeof(*top), 1);
struct WTreeNode *second = tiny_calloc(sizeof(*second), 1);
top->vertical = windowTreeFocus->parent ? !windowTreeFocus->parent->vertical : 0;
top->window = NULL;
top->parent = windowTreeFocus->parent;
top->first = windowTreeFocus;
top->second = second;
second->window = w;
second->parent = top;
windowTreeFocus->parent = top;
if(top->parent) {
if(top->parent->first == windowTreeFocus) {
top->parent->first = top;
} else if(top->parent->second == windowTreeFocus) {
top->parent->second = top;
} else {
// wtf
}
if(!wt->sub.b) {
wt->sub.b = tiny_calloc(1, sizeof(*wt->sub.b));
return wt->sub.b;
} else {
windowTreeRoot = top;
wt = find_free_space(wt->sub.b);
if(wt) return wt;
}
windowTreeFocus = second;
} else if(wt->gw.whole == NULL) {
return wt;
}
windowTreeFocus->window->focus = 1;
windowTree->fitter(windowTree);
return 1;
return NULL;
}
struct GWindow *add_window(const char *titleText) {
struct WindowTree *wt = find_free_space(windowTree);
if(!wt) return NULL;
std_w8(wt, 0, sizeof(*wt));
struct GWindow *gw = &wt->gw;
gw->whole = k3MObj();
k3MenuSetBounds(gw->whole, 0, 0, 320, 224);
gw->title = k3MLabel(NULL, 14, titleText);
k3MenuSetBounds(gw->title, 0, 0, 320, 16);
k3MAddChild(gw->whole, gw->title);
gw->panel = k3MObj();
k3MenuSetBounds(gw->panel, 0, 0, 320, 224);
k3MAddChild(gw->whole, gw->panel);
k3MAddChild(ui, gw->whole);
return gw;
}
int is_free_space() {
return 1;
}
static void destroy_window() {
if(!windowTreeFocus) return;
if(windowTreeFocus->window) {
windowTreeFocus->window->focus = 0;
windowTreeFocus->window->destroy((struct GObj*) windowTreeFocus->window);
windowTreeFocus->window = NULL;
if(windowTreeFocus->parent) {
struct WTreeNode *parent = windowTreeFocus->parent;
struct WTreeNode *other = NULL;
if(parent->first == windowTreeFocus) {
other = parent->second;
} else if(parent->second == windowTreeFocus) {
other = parent->first;
}
other->parent = parent->parent;
std_copy(parent, other, sizeof(struct WTreeNode));
tiny_free(windowTreeFocus);
windowTreeFocus = parent;
}
}
if(windowTreeFocus->window) {
windowTreeFocus->window->focus = 1;
}
windowTree->fitter(windowTree);
}
// Next lexicographical permutation of windows
static void permute() {
// TODO.
// TODO: Next lexicographical permutation of windows
}
static size_t path_size(Str16 *p) {
@ -811,33 +646,63 @@ static void load_programs() {
tiny_free(png);
}
static int dirtyX1 = INT32_MAX;
static int dirtyX2 = INT32_MIN;
static int dirtyY1 = INT32_MAX;
static int dirtyY2 = INT32_MIN;
void dirty(int x1, int y1, int w, int h) {
int x2 = x1 + w;
int y2 = y1 + h;
if(dirtyX1 > x1) {
dirtyX1 = x1;
}
if(dirtyX2 < x2) {
dirtyX2 = x2;
}
if(dirtyY1 > y1) {
dirtyY1 = y1;
}
if(dirtyY2 < y2) {
dirtyY2 = y2;
}
void dirty_obj(struct k3MObj *o) {
dirty(o->x, o->y, o->w, o->h);
}
void dirty_obj(struct GObj *o) {
dirty(o->x, o->y, o->w, o->h);
bool input_enter(struct k3MEvent *ev, uint8_t *ud) {
DynStr16 *ds16 = tiny_malloc(sizeof(*ds16) + strlen(cmdline->txt));
ds16->cap = strlen(cmdline->txt);
ds16->len = ds16->cap;
std_copy(ds16->data, cmdline->txt, ds16->len);
perform(ds16);
tiny_free(ds16);
cmdline->txt[0] = '\0';
return true;
}
static void init_ui() {
windowTree = tiny_calloc(1, sizeof(*windowTree));
ui = k3MScreen();
ui->x = 0;
ui->y = 0;
ui->w = 320;
ui->h = 240;
cmdline = k3MTextInput(NULL, 14, "Enter command...", "");
cmdline->x = 0;
cmdline->y = 226;
cmdline->w = 320;
cmdline->h = 14;
k3MRegisterEventHandler(cmdline, k3M_EVENT_COMPLETE, input_enter, NULL, 0);
k3MAddChild(ui, cmdline);
ui->keyboardFocus = (struct k3MObj*) cmdline;
}
uint32_t scancode_to_codepoint(bool shift, uint8_t scancode) {
uint32_t ret = 0;
if(scancode >= LK_A && scancode <= LK_Z) {
ret = scancode - LK_A + (shift ? 'A' : 'a');
} else if(scancode == LK_SPACE) {
ret = ' ';
} else if(scancode >= LK_0 && scancode <= LK_9) {
ret = scancode - LK_0 + '0';
} else if(scancode == LK_SLASH) {
ret = '/';
} else if(scancode == LK_COMMA) {
ret = ',';
} else if(scancode == LK_PERIOD) {
ret = '.';
}
return ret;
}
void startc() {
@ -877,7 +742,14 @@ void startc() {
drawdesk(0, 0, 320, 240);
ui->onRender((struct GObj*) ui);
{
struct k3MEvent ev = {
.original = ui,
.target = ui,
.code = k3M_EVENT_DRAW,
};
k3MEventSend(&ev);
}
while(1) {
KEvent kev;
@ -919,7 +791,29 @@ void startc() {
focus_next();
}
} else {
ui->onKey((struct GObj*) ui, (struct GKeyEvent) {.scancode = keyBuf[keyBufIndex].scancode, .press = keyBuf[keyBufIndex].flag == KEYEV_FLAG_PRESS, .shift = shift, .alt = alt});
struct k3MEvent ev;
ev = (struct k3MEvent) {
.original = (void*) ui,
.target = (void*) ui,
.code = (keyBuf[keyBufIndex].flag == KEYEV_FLAG_PRESS) ? k3M_EVENT_KEY_PRESS : k3M_EVENT_KEY_RELEASE,
.key = { .num = keyBuf[keyBufIndex].scancode },
};
k3MEventSend(&ev);
if(keyBuf[keyBufIndex].flag == KEYEV_FLAG_PRESS) {
uint32_t codepoint = scancode_to_codepoint(shift, keyBuf[keyBufIndex].scancode);
ev = (struct k3MEvent) {
.original = (void*) ui,
.target = (void*) ui,
.code = k3M_EVENT_INPUT,
.input = { .code = codepoint },
};
k3MEventSend(&ev);
}
}
if(keyBuf[keyBufIndex].scancode == LK_LEFT_SHIFT) {
@ -943,8 +837,8 @@ void startc() {
alt &= ~ALT_LEFT;
if(sysNothingElseWasPressed) {
cmdline->focus ^= 1;
windowTree->focus ^= 1;
//cmdline->focus ^= 1;
//windowTree->focus ^= 1;
}
}
} else if(keyBuf[keyBufIndex].scancode == LK_LEFT_SYS) {
@ -968,7 +862,13 @@ void startc() {
dirtyY1 = INT32_MAX;
dirtyY2 = INT32_MIN;
}
ui->onRender((struct GObj*) ui);
struct k3MEvent ev = {
.original = ui,
.target = ui,
.code = k3M_EVENT_DRAW,
};
k3MEventSend(&ev);
}
memory_barrier();

View File

@ -9,37 +9,7 @@
#include"tiny.h"
#include"io.h"
#include"fileswindow.h"
static inline void pr(int c) {
asm volatile("outb %%al, $0xE9" :: "a"(c) :);
}
static inline void pri(size_t num) {
char buf[16] = {};
int i = 16;
do {
buf[--i] = num % 10;
num /= 10;
} while(num);
for(; i < 16; i++) {
pr(buf[i] + '0');
}
}
static inline void prs(const Str16 *str) {
for(int i = 0; i < str->len; i++) {
pr(str->data[i]);
}
}
static inline void prcs(const char *str) {
while(*str) {
pr(*str);
str++;
}
}
#include"k3menu.h"
__attribute__((optimize("Ofast"))) static void b2hex(uint8_t b, char *ret) {
uint8_t top = b >> 4;
@ -52,24 +22,32 @@ __attribute__((optimize("Ofast"))) static void b2hex(uint8_t b, char *ret) {
static void show_help_window() {
if(!is_free_space()) return;
static const char txt[] = "Luma's interface is designed around the keyboard. In fact, you are unlikely to find any use for a mouse except in niche cases.\n\nTurn to the command bar below by pressing the System (Sys) key. Start off by exploring Luma's software by entering \"list\" or your filesystem with \"files\".\n\nSys+H and Sys+V split the desktop to fit more windows. Use Sys+Escape to close windows or remove free space. Sys+P moves windows around.";
/*static const char txt[] = "Luma's interface is designed around the keyboard. In fact, you are unlikely to find any use for a mouse except in niche cases.\n\nTurn to the command bar below by pressing the System (Sys) key. Start off by exploring Luma's software by entering \"list\" or your filesystem with \"files\".\n\nSys+H and Sys+V split the desktop to fit more windows. Use Sys+Escape to close windows or remove free space. Sys+P moves windows around.";
struct GLabel *l = glabel_new(0, 0, 0, 0, g_dynstr16_new(sizeof(txt) - 1, sizeof(txt) - 1, txt), 1);
static const char name[] = "Welcome to Luma";
struct GWindow *w = gwindow_new(0, 0, 0, 0, g_dynstr16_new(sizeof(name) - 1, sizeof(name) - 1, name), (struct GObj*) l, 0);
add_window(w);
add_window(w);*/
struct GWindow *gw = add_window("Welcome to Luma");
struct k3MLabel *lbl = k3MLabel(NULL, 14, "Luma's interface is designed around the keyboard. In fact, you are unlikely to find any use for a mouse except in niche cases.\n\nTurn to the command bar below by pressing the System (Sys) key. Start off by exploring Luma's software by entering \"list\" or your filesystem with \"files\".\n\nSys+H and Sys+V split the desktop to fit more windows. Use Sys+Escape to close windows or remove free space. Sys+P moves windows around.");
k3MenuSetBounds(lbl, 0, 20, 320, 204);
k3MAddChild(gw->panel, lbl);
dirty_obj(gw->whole);
}
static void show_log_window() {
if(!is_free_space()) return;
struct GLabel *l = glabel_new(0, 0, 0, 0, log_get(), 0);
/*struct GLabel *l = glabel_new(0, 0, 0, 0, log_get(), 0);
static const char name[] = "System Logs";
struct GWindow *w = gwindow_new(0, 0, 0, 0, g_dynstr16_new(sizeof(name) - 1, sizeof(name) - 1, name), (struct GObj*) l, 0);
add_window(w);
add_window(w);*/
}
static void e9(const char *buf, size_t len) {
@ -301,7 +279,7 @@ void perform(DynStr16 *cmd) {
show_log_window();
} else if(cmd->len > 2 && cmd->data[0] == 'g' && cmd->data[1] == 'o' && cmd->data[2] == ' ') {
attempt_program_launch(cmd->data + 3, cmd->len - 3);
} else if(windowTreeFocus && windowTreeFocus->window) {
} /*else if(windowTreeFocus && windowTreeFocus->window) {
uint8_t *space = (uint8_t*) std_bytefind(cmd->len, (char*) cmd->data, ' ');
size_t end = space ? space - cmd->data : cmd->len;
@ -318,7 +296,7 @@ void perform(DynStr16 *cmd) {
break;
}
} else {
}*/ else {
// Failed.
}
}

View File

@ -7,7 +7,7 @@
#include"logserver.h"
static void gtext_render(struct GObj *_) {
/*static void gtext_render(struct GObj *_) {
struct GText *this = (void*) _;
LumaVidCommand *cmd = VidLink;
@ -444,7 +444,7 @@ void glist_clear(struct GList *this) {
tiny_free(this->children);
this->children = NULL;
this->cursor = 0;
}
}*/
DynStr16 *g_dynstr16_new(uint16_t cap, uint16_t len, const void *data) {
DynStr16 *ret = tiny_malloc(sizeof(*ret) + cap);

View File

@ -2,11 +2,7 @@
#include"../std.h"
#include"../ps2/api.h"
typedef uint16_t Coord;
struct GObj;
struct GContainer;
#include"k3menu.h"
#define SHIFT_LEFT 1
#define SHIFT_RIGHT 2
@ -14,58 +10,6 @@ struct GContainer;
#define ALT_RIGHT 2
#define SYS_LEFT 1
#define SYS_RIGHT 2
struct GKeyEvent {
uint8_t scancode;
uint8_t press;
uint8_t shift;
uint8_t alt;
uint8_t sys;
};
typedef void(*RenderFunc)(struct GObj*);
typedef void(*KeyReactFunc)(struct GObj*, struct GKeyEvent);
typedef void(*FitterFunc)(struct GObj*);
typedef void(*DestroyFunc)(struct GObj*);
struct GObj {
RenderFunc onRender;
KeyReactFunc onKey;
DestroyFunc destroy;
FitterFunc fitter;
Coord x, y;
Coord w, h;
uint8_t focus;
void *ud;
};
struct GText {
struct GObj;
DynStr16 *placeholder;
DynStr16 *data;
};
struct GText *gtext_new(Coord x, Coord y, Coord w, Coord h, DynStr16 *placeholder, DynStr16 *str);
typedef uint8_t GContainerChildMeta;
struct GContainerChild {
GContainerChildMeta meta;
struct GObj *obj;
};
struct GContainer {
struct GObj;
size_t childCount;
struct GContainerChild *children;
uint8_t meta;
};
struct GContainer *gcont_new(Coord x, Coord y, Coord w, Coord h, FitterFunc fitter);
int gcont_add(struct GContainer*, GContainerChildMeta, struct GObj*);
void gcont_set(struct GContainer*, size_t index, GContainerChildMeta, struct GObj*);
void gcont_del(struct GContainer*, size_t index);
void gcont_splitter_v(struct GObj*);
void gcont_splitter_h(struct GObj*);
typedef int(*GCMDFunc)(void*, const DynStr16 *line);
struct Command {
@ -78,44 +22,14 @@ struct CommandList {
struct Command *array;
};
struct GWindow {
struct GObj;
/*struct GWindow {
struct k3MObj;
DynStr16 *name;
struct GObj *child;
size_t owner;
struct CommandList cmds;
};
struct GWindow *gwindow_new(Coord x, Coord y, Coord w, Coord h, DynStr16 *name, struct GObj *child, size_t owner);
int gwindow_regcmd(struct GWindow*, Str16 *cmd, void *ud, GCMDFunc handler);
struct GLabel {
struct GObj;
DynStr16 *data;
int owned;
};
struct GLabel *glabel_new(Coord x, Coord y, Coord w, Coord h, DynStr16 *data, int owned);
struct GListChild {
DynStr16 *text;
void *ud;
uint8_t selected;
};
struct GList {
struct GObj;
size_t childCount;
struct GListChild *children;
size_t cursor;
};
struct GList *glist_new(Coord x, Coord y, Coord w, Coord h);
int glist_add(struct GList*, DynStr16*, void *ud);
void glist_clear(struct GList*);
int gwindow_regcmd(struct GWindow*, Str16 *cmd, void *ud, GCMDFunc handler);*/
DynStr16 *g_dynstr16_new(uint16_t cap, uint16_t len, const void *data);
DynStr16 *g_dynstr16_append(DynStr16*, uint16_t len, const void *data);

View File

@ -5,17 +5,18 @@
extern void *FSLink;
extern void *VidLink;
struct WTreeNode {
char vertical;
struct GWindow *window;
struct WTreeNode *parent;
struct WTreeNode *first;
struct WTreeNode *second;
};
extern struct WTreeNode *windowTreeFocus;
struct GWindow {
struct k3MObj *whole;
struct k3MLabel *title;
struct k3MObj *panel;
// k3Menu only supports one "focused" element per k3MScreen,
// but we want to save these when people Alt+Tab
struct k3MObj *focus;
};
struct GWindow *add_window(const char *title);
int add_window(struct GWindow *w);
int is_free_space();
void dirty(int x, int y, int w, int h);
void dirty_obj(struct GObj*);
void dirty_obj(struct k3MObj*);