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; 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. // 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 // 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) { 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_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;}) #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)}) //#define S16_ARG(str) ((Str16*) &(struct {uint16_t len; char content[sizeof(str) - 1]}) {sizeof(str) - 1, (str)})
#endif #endif

View File

@ -4,8 +4,13 @@
#include<stdint.h> #include<stdint.h>
typedef enum { 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_END = 0, LUMA_VID_COMMAND_CLEAR = 1,
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_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; } LumaVidCommandOp;
typedef enum { typedef enum {
@ -19,6 +24,12 @@ typedef enum {
LUMA_VID_ALIGN_BOTTOM_RIGHT = 3, LUMA_VID_ALIGN_BOTTOM_RIGHT = 3,
} LumaVidAlign; } LumaVidAlign;
typedef enum {
LUMA_VID_TEXT_ALIGN_LEFT = 0,
LUMA_VID_TEXT_ALIGN_CENTER = 1,
LUMA_VID_TEXT_ALIGN_RIGHT = 2,
} LumaVidTextAlign;
typedef union { typedef union {
uint8_t op; uint8_t op;
struct { struct {
@ -73,6 +84,7 @@ typedef union {
uint16_t x; uint16_t x;
uint16_t len; uint16_t len;
uint16_t wall; uint16_t wall;
uint8_t align;
uint8_t data[]; uint8_t data[];
} __attribute__((packed)) text; } __attribute__((packed)) text;
struct { struct {
@ -83,6 +95,14 @@ typedef union {
uint16_t len; uint16_t len;
uint8_t data[]; uint8_t data[];
} __attribute__((packed)) imageWrite; } __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; } __attribute__((packed)) LumaVidCommand;
#endif #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) { static const uint8_t font[] = {
if(wall <= x) wall = 320; 0x20, 0x31, 0x95, 0x00, 0x21, 0x17, 0x15, 0x5f, 0x22, 0x32, 0x15, 0x2d,
0x23, 0x47, 0x15, 0xaa, 0xaf, 0x5f, 0x05, 0x24, 0x48, 0x15, 0x5e, 0x65,
static const uint8_t font[] = { 0xcc, 0x47, 0x25, 0x57, 0x15, 0x6b, 0x1d, 0xc2, 0xb5, 0x06, 0x26, 0x57,
0x20, 0x31, 0x95, 0x00, 0x21, 0x17, 0x15, 0x5f, 0x22, 0x32, 0x15, 0x2d, 0x15, 0x44, 0x19, 0x9b, 0x92, 0x05, 0x27, 0x12, 0x15, 0x03, 0x28, 0x28,
0x23, 0x47, 0x15, 0xaa, 0xaf, 0x5f, 0x05, 0x24, 0x48, 0x15, 0x5e, 0x65, 0x15, 0x56, 0x95, 0x29, 0x28, 0x15, 0xa9, 0x6a, 0x2a, 0x34, 0x15, 0xfa,
0xcc, 0x47, 0x25, 0x57, 0x15, 0x6b, 0x1d, 0xc2, 0xb5, 0x06, 0x26, 0x57, 0x05, 0x2b, 0x55, 0x35, 0x84, 0x7c, 0x42, 0x00, 0x2c, 0x22, 0x75, 0x06,
0x15, 0x44, 0x19, 0x9b, 0x92, 0x05, 0x27, 0x12, 0x15, 0x03, 0x28, 0x28, 0x2d, 0x31, 0x55, 0x07, 0x2e, 0x11, 0x75, 0x01, 0x2f, 0x37, 0x15, 0xa4,
0x15, 0x56, 0x95, 0x29, 0x28, 0x15, 0xa9, 0x6a, 0x2a, 0x34, 0x15, 0xfa, 0xa4, 0x04, 0x30, 0x47, 0x15, 0x96, 0xb9, 0x99, 0x06, 0x31, 0x37, 0x15,
0x05, 0x2b, 0x55, 0x35, 0x84, 0x7c, 0x42, 0x00, 0x2c, 0x22, 0x75, 0x06, 0x93, 0x24, 0x1d, 0x32, 0x47, 0x15, 0x87, 0x48, 0x12, 0x0f, 0x33, 0x47,
0x2d, 0x31, 0x55, 0x07, 0x2e, 0x11, 0x75, 0x01, 0x2f, 0x37, 0x15, 0xa4, 0x15, 0x87, 0x68, 0x88, 0x07, 0x34, 0x57, 0x15, 0x8c, 0xa9, 0xf4, 0x11,
0xa4, 0x04, 0x30, 0x47, 0x15, 0x96, 0xb9, 0x99, 0x06, 0x31, 0x37, 0x15, 0x02, 0x35, 0x47, 0x15, 0x1f, 0x71, 0x88, 0x07, 0x36, 0x47, 0x15, 0x1e,
0x93, 0x24, 0x1d, 0x32, 0x47, 0x15, 0x87, 0x48, 0x12, 0x0f, 0x33, 0x47, 0x71, 0x99, 0x06, 0x37, 0x47, 0x15, 0x8f, 0x44, 0x22, 0x01, 0x38, 0x47,
0x15, 0x87, 0x68, 0x88, 0x07, 0x34, 0x57, 0x15, 0x8c, 0xa9, 0xf4, 0x11, 0x15, 0x96, 0x69, 0x99, 0x06, 0x39, 0x47, 0x15, 0x96, 0xe9, 0x88, 0x07,
0x02, 0x35, 0x47, 0x15, 0x1f, 0x71, 0x88, 0x07, 0x36, 0x47, 0x15, 0x1e, 0x3a, 0x15, 0x35, 0x11, 0x3b, 0x26, 0x35, 0x02, 0x06, 0x3c, 0x35, 0x25,
0x71, 0x99, 0x06, 0x37, 0x47, 0x15, 0x8f, 0x44, 0x22, 0x01, 0x38, 0x47, 0x54, 0x44, 0x3d, 0x43, 0x45, 0x0f, 0x0f, 0x3e, 0x35, 0x25, 0x11, 0x15,
0x15, 0x96, 0x69, 0x99, 0x06, 0x39, 0x47, 0x15, 0x96, 0xe9, 0x88, 0x07, 0x3f, 0x37, 0x15, 0x2a, 0x25, 0x08, 0x40, 0x57, 0x15, 0x2e, 0xf6, 0xde,
0x3a, 0x15, 0x35, 0x11, 0x3b, 0x26, 0x35, 0x02, 0x06, 0x3c, 0x35, 0x25, 0x82, 0x03, 0x41, 0x57, 0x15, 0x84, 0x28, 0xe5, 0x62, 0x04, 0x42, 0x47,
0x54, 0x44, 0x3d, 0x43, 0x45, 0x0f, 0x0f, 0x3e, 0x35, 0x25, 0x11, 0x15, 0x15, 0x97, 0x79, 0x99, 0x07, 0x43, 0x47, 0x15, 0x1e, 0x11, 0x11, 0x0e,
0x3f, 0x37, 0x15, 0x2a, 0x25, 0x08, 0x40, 0x57, 0x15, 0x2e, 0xf6, 0xde, 0x44, 0x47, 0x15, 0x97, 0x99, 0x99, 0x07, 0x45, 0x47, 0x15, 0x1f, 0xf1,
0x82, 0x03, 0x41, 0x57, 0x15, 0x84, 0x28, 0xe5, 0x62, 0x04, 0x42, 0x47, 0x11, 0x0f, 0x46, 0x47, 0x15, 0x1f, 0xf1, 0x11, 0x01, 0x47, 0x47, 0x15,
0x15, 0x97, 0x79, 0x99, 0x07, 0x43, 0x47, 0x15, 0x1e, 0x11, 0x11, 0x0e, 0x1e, 0x11, 0x9d, 0x0e, 0x48, 0x47, 0x15, 0x99, 0xf9, 0x99, 0x09, 0x49,
0x44, 0x47, 0x15, 0x97, 0x99, 0x99, 0x07, 0x45, 0x47, 0x15, 0x1f, 0xf1, 0x37, 0x15, 0x97, 0x24, 0x1d, 0x4a, 0x37, 0x15, 0x24, 0x49, 0x0e, 0x4b,
0x11, 0x0f, 0x46, 0x47, 0x15, 0x1f, 0xf1, 0x11, 0x01, 0x47, 0x47, 0x15, 0x57, 0x15, 0x31, 0x95, 0x93, 0x52, 0x04, 0x4c, 0x47, 0x15, 0x11, 0x11,
0x1e, 0x11, 0x9d, 0x0e, 0x48, 0x47, 0x15, 0x99, 0xf9, 0x99, 0x09, 0x49, 0x11, 0x0f, 0x4d, 0x47, 0x15, 0xb9, 0xbf, 0x99, 0x09, 0x4e, 0x47, 0x15,
0x37, 0x15, 0x97, 0x24, 0x1d, 0x4a, 0x37, 0x15, 0x24, 0x49, 0x0e, 0x4b, 0xb9, 0xbb, 0xdd, 0x09, 0x4f, 0x47, 0x15, 0x96, 0x99, 0x99, 0x06, 0x50,
0x57, 0x15, 0x31, 0x95, 0x93, 0x52, 0x04, 0x4c, 0x47, 0x15, 0x11, 0x11, 0x47, 0x15, 0x97, 0x79, 0x11, 0x01, 0x51, 0x48, 0x15, 0x96, 0x99, 0x99,
0x11, 0x0f, 0x4d, 0x47, 0x15, 0xb9, 0xbf, 0x99, 0x09, 0x4e, 0x47, 0x15, 0x86, 0x52, 0x57, 0x15, 0x27, 0xa5, 0x53, 0x52, 0x04, 0x53, 0x47, 0x15,
0xb9, 0xbb, 0xdd, 0x09, 0x4f, 0x47, 0x15, 0x96, 0x99, 0x99, 0x06, 0x50, 0x1e, 0x61, 0x88, 0x07, 0x54, 0x57, 0x15, 0x9f, 0x10, 0x42, 0x08, 0x01,
0x47, 0x15, 0x97, 0x79, 0x11, 0x01, 0x51, 0x48, 0x15, 0x96, 0x99, 0x99, 0x55, 0x47, 0x15, 0x99, 0x99, 0x99, 0x06, 0x56, 0x57, 0x15, 0x31, 0x2a,
0x86, 0x52, 0x57, 0x15, 0x27, 0xa5, 0x53, 0x52, 0x04, 0x53, 0x47, 0x15, 0xa5, 0x08, 0x01, 0x57, 0x57, 0x15, 0x31, 0xd6, 0xba, 0x94, 0x02, 0x58,
0x1e, 0x61, 0x88, 0x07, 0x54, 0x57, 0x15, 0x9f, 0x10, 0x42, 0x08, 0x01, 0x47, 0x15, 0x99, 0x66, 0x96, 0x09, 0x59, 0x57, 0x15, 0x51, 0x29, 0x42,
0x55, 0x47, 0x15, 0x99, 0x99, 0x99, 0x06, 0x56, 0x57, 0x15, 0x31, 0x2a, 0x08, 0x01, 0x5a, 0x47, 0x15, 0x8f, 0x24, 0x12, 0x0f, 0x5b, 0x28, 0x15,
0xa5, 0x08, 0x01, 0x57, 0x57, 0x15, 0x31, 0xd6, 0xba, 0x94, 0x02, 0x58, 0x57, 0xd5, 0x5c, 0x37, 0x15, 0x89, 0x24, 0x12, 0x5d, 0x28, 0x15, 0xab,
0x47, 0x15, 0x99, 0x66, 0x96, 0x09, 0x59, 0x57, 0x15, 0x51, 0x29, 0x42, 0xea, 0x5e, 0x53, 0x25, 0x44, 0x45, 0x5f, 0x51, 0x95, 0x1f, 0x60, 0x22,
0x08, 0x01, 0x5a, 0x47, 0x15, 0x8f, 0x24, 0x12, 0x0f, 0x5b, 0x28, 0x15, 0x15, 0x09, 0x61, 0x45, 0x35, 0x87, 0x9e, 0x0e, 0x62, 0x47, 0x15, 0x11,
0x57, 0xd5, 0x5c, 0x37, 0x15, 0x89, 0x24, 0x12, 0x5d, 0x28, 0x15, 0xab, 0x97, 0x99, 0x07, 0x63, 0x45, 0x35, 0x1e, 0x11, 0x0e, 0x64, 0x47, 0x15,
0xea, 0x5e, 0x53, 0x25, 0x44, 0x45, 0x5f, 0x51, 0x95, 0x1f, 0x60, 0x22, 0x88, 0x9e, 0x99, 0x0e, 0x65, 0x45, 0x35, 0x96, 0x1f, 0x0e, 0x66, 0x47,
0x15, 0x09, 0x61, 0x45, 0x35, 0x87, 0x9e, 0x0e, 0x62, 0x47, 0x15, 0x11, 0x15, 0x2c, 0x2f, 0x22, 0x02, 0x67, 0x47, 0x35, 0x5e, 0x12, 0x9f, 0x06,
0x97, 0x99, 0x07, 0x63, 0x45, 0x35, 0x1e, 0x11, 0x0e, 0x64, 0x47, 0x15, 0x68, 0x47, 0x15, 0x11, 0xb5, 0x99, 0x09, 0x69, 0x27, 0x15, 0xb2, 0x2a,
0x88, 0x9e, 0x99, 0x0e, 0x65, 0x45, 0x35, 0x96, 0x1f, 0x0e, 0x66, 0x47, 0x6a, 0x39, 0x15, 0x84, 0x49, 0x92, 0x03, 0x6b, 0x57, 0x15, 0x21, 0xa4,
0x15, 0x2c, 0x2f, 0x22, 0x02, 0x67, 0x47, 0x35, 0x5e, 0x12, 0x9f, 0x06, 0x72, 0x52, 0x04, 0x6c, 0x37, 0x15, 0x93, 0x24, 0x19, 0x6d, 0x55, 0x35,
0x68, 0x47, 0x15, 0x11, 0xb5, 0x99, 0x09, 0x69, 0x27, 0x15, 0xb2, 0x2a, 0xab, 0xd6, 0x5a, 0x01, 0x6e, 0x45, 0x35, 0xb5, 0x99, 0x09, 0x6f, 0x45,
0x6a, 0x39, 0x15, 0x84, 0x49, 0x92, 0x03, 0x6b, 0x57, 0x15, 0x21, 0xa4, 0x35, 0x96, 0x99, 0x06, 0x70, 0x47, 0x35, 0x97, 0x99, 0x17, 0x01, 0x71,
0x72, 0x52, 0x04, 0x6c, 0x37, 0x15, 0x93, 0x24, 0x19, 0x6d, 0x55, 0x35, 0x47, 0x35, 0x9e, 0x99, 0x8e, 0x08, 0x72, 0x35, 0x35, 0x4f, 0x12, 0x73,
0xab, 0xd6, 0x5a, 0x01, 0x6e, 0x45, 0x35, 0xb5, 0x99, 0x09, 0x6f, 0x45, 0x45, 0x35, 0x1f, 0x86, 0x07, 0x74, 0x46, 0x25, 0xf2, 0x22, 0xc2, 0x75,
0x35, 0x96, 0x99, 0x06, 0x70, 0x47, 0x35, 0x97, 0x99, 0x17, 0x01, 0x71, 0x45, 0x35, 0x99, 0x99, 0x0e, 0x76, 0x45, 0x35, 0xa9, 0x4a, 0x04, 0x77,
0x47, 0x35, 0x9e, 0x99, 0x8e, 0x08, 0x72, 0x35, 0x35, 0x4f, 0x12, 0x73, 0x55, 0x35, 0xb1, 0x56, 0xa5, 0x00, 0x78, 0x45, 0x35, 0x69, 0x66, 0x09,
0x45, 0x35, 0x1f, 0x86, 0x07, 0x74, 0x46, 0x25, 0xf2, 0x22, 0xc2, 0x75, 0x79, 0x47, 0x35, 0xa9, 0x4a, 0x44, 0x03, 0x7a, 0x45, 0x35, 0x4f, 0x12,
0x45, 0x35, 0x99, 0x99, 0x0e, 0x76, 0x45, 0x35, 0xa9, 0x4a, 0x04, 0x77, 0x0f, 0x7b, 0x39, 0x15, 0x94, 0x14, 0x49, 0x04, 0x7c, 0x18, 0x15, 0xff,
0x55, 0x35, 0xb1, 0x56, 0xa5, 0x00, 0x78, 0x45, 0x35, 0x69, 0x66, 0x09, 0x7d, 0x39, 0x15, 0x91, 0x44, 0x49, 0x01, 0x7e, 0x52, 0x45, 0x36, 0x01
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)) {
const uint8_t *find(char c) { if(*a == c) {
const uint8_t *a = font; return a;
while(a - font < sizeof(font)) { } else {
if(*a == c) { a += 3 + ((a[1] & 15) * (a[1] >> 4) + 7) / 8;
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; uint16_t startX = x;
int col = colorFunc(0, 0); int col = colorFunc(0, 0);
while(len--) { while(len--) {
if(*str == 10) { if(*str == 10) {
str++; return;
x = startX;
y += 13;
continue;
} }
const uint8_t *data = find(*(str++)); 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; uint8_t width = data[2] & 0x0F;
if(x + width >= wall) { if(x + width >= wall) {
x = startX;
y += 13; y += 13;
return;
} }
for(int ix = 0; ix < (data[1] >> 4); ix++) { 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) { static void compileCommandList(uint8_t *src, uint8_t *dst) {
size_t len = 0; size_t len = 0;
while(1) { while(1) {
@ -410,6 +486,9 @@ static void compileCommandList(uint8_t *src, uint8_t *dst) {
} else if(cmd->op == LUMA_VID_COMMAND_IMAGE_DEL) { } else if(cmd->op == LUMA_VID_COMMAND_IMAGE_DEL) {
src += sizeof(cmd->imageDel); src += sizeof(cmd->imageDel);
} else if(cmd->op == LUMA_VID_COMMAND_TEXT) { } else if(cmd->op == LUMA_VID_COMMAND_TEXT) {
dst[len++] = 0x68;
*((uint32_t*) &dst[len]) = cmd->text.align;
len += 4;
dst[len++] = 0x68; dst[len++] = 0x68;
*((uint32_t*) &dst[len]) = cmd->text.wall; *((uint32_t*) &dst[len]) = cmd->text.wall;
len += 4; len += 4;
@ -435,7 +514,7 @@ static void compileCommandList(uint8_t *src, uint8_t *dst) {
len += cmd->text.len; len += cmd->text.len;
dst[len++] = 0x83; /* add esp, imm8 */ dst[len++] = 0x83; /* add esp, imm8 */
dst[len++] = 0xC4; dst[len++] = 0xC4;
dst[len++] = 0x14; dst[len++] = 0x18;
src += sizeof(cmd->text) + cmd->text.len; src += sizeof(cmd->text) + cmd->text.len;
} else if(cmd->op == LUMA_VID_COMMAND_NEW_COLOR_FLAT) { } 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); 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(); q_reavg();
src += sizeof(cmd->colorGrad); 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 ../../build/wm/%.o: %.c
mkdir -p $(@D) 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}; 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)) #define I(x) ((uint64_t)(x))
static int read_varint(const uint8_t *data, size_t length, uint64_t *result) { static int read_varint(const uint8_t *data, size_t length, uint64_t *result) {
if(data[0] & 0x80) { 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)) #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; Str16 *cd;
size_t cdSize; size_t cdSize;
} ; } ;
@ -190,12 +190,12 @@ static int files_window_back_cmd(void *ud, const DynStr16 *cmdline) {
update_listing(w); update_listing(w);
return 1; return 1;
} }*/
void FilesWindowCreate() { void FilesWindowCreate() {
if(!is_free_space()) return; 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"; 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); 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"; static const char backcmd[] = "back";
gwindow_regcmd(w, g_str16_new(sizeof(backcmd) - 1, backcmd), w, files_window_back_cmd); 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"logserver.h"
#include"progdb.h" #include"progdb.h"
#include"io.h" #include"io.h"
#include"k3menu.h"
asm("modentry:\n" asm("modentry:\n"
"mov $stack + 2048, %esp\n" "mov $stack + 2048, %esp\n"
@ -24,37 +25,6 @@ char stack[2048];
void *VidLink; void *VidLink;
void *FSLink; 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) { void initvid(int col) {
static uint8_t logo[] = { static uint8_t logo[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 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); sys_signal_wait(VidLink, NULL);
} }
struct GContainer *ui; struct k3MScreen *ui;
struct k3MTextInput *cmdline;
struct GObj *windowTree; struct WindowTree {
struct WTreeNode *windowTreeRoot; bool split;
struct WTreeNode *windowTreeFocus; union {
struct GWindow gw;
struct GText *cmdline; struct {
struct WindowTree *a;
struct WindowTree *b;
} sub;
};
};
struct WindowTree *windowTree = NULL;
static void focus_next() { 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(dirtyX2 < x2) {
if(windowTreeFocus->parent->first == windowTreeFocus) { dirtyX2 = x2;
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(windowTreeFocus->window) { if(dirtyY1 > y1) {
windowTreeFocus->window->focus = 1; dirtyY1 = y1;
}
if(dirtyY2 < y2) {
dirtyY2 = y2;
} }
} }
static KeyReactFunc baseinputonkey; static struct WindowTree *find_free_space(struct WindowTree *wt) {
static void inputonkey(struct GObj *_, struct GKeyEvent ev) { if(wt->split) {
if(ev.scancode == LK_ENTER) { if(!wt->sub.a) {
struct GText *t = (void*) _; wt->sub.a = tiny_calloc(1, sizeof(*wt->sub.a));
return wt->sub.a;
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);
}
} else { } else {
if(node->first) { wt = find_free_space(wt->sub.a);
wtree_fitter_recur(node->first, x, y, w / 2, h); if(wt) return wt;
}
if(node->second) {
wtree_fitter_recur(node->second, x + w / 2, y, w / 2, h);
}
} }
if(!wt->sub.b) {
wt->sub.b = tiny_calloc(1, sizeof(*wt->sub.b));
return wt->sub.b;
} else {
wt = find_free_space(wt->sub.b);
if(wt) return wt;
}
} else if(wt->gw.whole == NULL) {
return wt;
} }
} return NULL;
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) { struct GWindow *add_window(const char *titleText) {
if(!windowTreeFocus) { struct WindowTree *wt = find_free_space(windowTree);
return 0;
}
if(windowTreeFocus && windowTreeFocus->window) { if(!wt) return NULL;
windowTreeFocus->window->focus = 0;
}
if(!windowTreeFocus->window) { std_w8(wt, 0, sizeof(*wt));
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
}
} else {
windowTreeRoot = top;
}
windowTreeFocus = second;
}
windowTreeFocus->window->focus = 1; struct GWindow *gw = &wt->gw;
windowTree->fitter(windowTree); gw->whole = k3MObj();
k3MenuSetBounds(gw->whole, 0, 0, 320, 224);
return 1; 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() { int is_free_space() {
return 1; return 1;
} }
static void destroy_window() { 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() { static void permute() {
// TODO. // TODO: Next lexicographical permutation of windows
} }
static size_t path_size(Str16 *p) { static size_t path_size(Str16 *p) {
@ -811,33 +646,63 @@ static void load_programs() {
tiny_free(png); tiny_free(png);
} }
static int dirtyX1 = INT32_MAX; void dirty_obj(struct k3MObj *o) {
static int dirtyX2 = INT32_MIN; dirty(o->x, o->y, o->w, o->h);
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 GObj *o) { bool input_enter(struct k3MEvent *ev, uint8_t *ud) {
dirty(o->x, o->y, o->w, o->h); 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() { void startc() {
@ -877,7 +742,14 @@ void startc() {
drawdesk(0, 0, 320, 240); 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) { while(1) {
KEvent kev; KEvent kev;
@ -919,7 +791,29 @@ void startc() {
focus_next(); focus_next();
} }
} else { } 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) { if(keyBuf[keyBufIndex].scancode == LK_LEFT_SHIFT) {
@ -943,8 +837,8 @@ void startc() {
alt &= ~ALT_LEFT; alt &= ~ALT_LEFT;
if(sysNothingElseWasPressed) { if(sysNothingElseWasPressed) {
cmdline->focus ^= 1; //cmdline->focus ^= 1;
windowTree->focus ^= 1; //windowTree->focus ^= 1;
} }
} }
} else if(keyBuf[keyBufIndex].scancode == LK_LEFT_SYS) { } else if(keyBuf[keyBufIndex].scancode == LK_LEFT_SYS) {
@ -968,7 +862,13 @@ void startc() {
dirtyY1 = INT32_MAX; dirtyY1 = INT32_MAX;
dirtyY2 = INT32_MIN; dirtyY2 = INT32_MIN;
} }
ui->onRender((struct GObj*) ui);
struct k3MEvent ev = {
.original = ui,
.target = ui,
.code = k3M_EVENT_DRAW,
};
k3MEventSend(&ev);
} }
memory_barrier(); memory_barrier();

View File

@ -9,37 +9,7 @@
#include"tiny.h" #include"tiny.h"
#include"io.h" #include"io.h"
#include"fileswindow.h" #include"fileswindow.h"
#include"k3menu.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++;
}
}
__attribute__((optimize("Ofast"))) static void b2hex(uint8_t b, char *ret) { __attribute__((optimize("Ofast"))) static void b2hex(uint8_t b, char *ret) {
uint8_t top = b >> 4; 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() { static void show_help_window() {
if(!is_free_space()) return; 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); 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"; 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); 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() { static void show_log_window() {
if(!is_free_space()) return; 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"; 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); 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) { static void e9(const char *buf, size_t len) {
@ -301,7 +279,7 @@ void perform(DynStr16 *cmd) {
show_log_window(); show_log_window();
} else if(cmd->len > 2 && cmd->data[0] == 'g' && cmd->data[1] == 'o' && cmd->data[2] == ' ') { } 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); 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, ' '); uint8_t *space = (uint8_t*) std_bytefind(cmd->len, (char*) cmd->data, ' ');
size_t end = space ? space - cmd->data : cmd->len; size_t end = space ? space - cmd->data : cmd->len;
@ -318,7 +296,7 @@ void perform(DynStr16 *cmd) {
break; break;
} }
} else { }*/ else {
// Failed. // Failed.
} }
} }

View File

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

View File

@ -2,11 +2,7 @@
#include"../std.h" #include"../std.h"
#include"../ps2/api.h" #include"../ps2/api.h"
#include"k3menu.h"
typedef uint16_t Coord;
struct GObj;
struct GContainer;
#define SHIFT_LEFT 1 #define SHIFT_LEFT 1
#define SHIFT_RIGHT 2 #define SHIFT_RIGHT 2
@ -14,58 +10,6 @@ struct GContainer;
#define ALT_RIGHT 2 #define ALT_RIGHT 2
#define SYS_LEFT 1 #define SYS_LEFT 1
#define SYS_RIGHT 2 #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); typedef int(*GCMDFunc)(void*, const DynStr16 *line);
struct Command { struct Command {
@ -78,44 +22,14 @@ struct CommandList {
struct Command *array; struct Command *array;
}; };
struct GWindow { /*struct GWindow {
struct GObj; struct k3MObj;
DynStr16 *name; DynStr16 *name;
struct GObj *child;
size_t owner; size_t owner;
struct CommandList cmds; 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);*/
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*);
DynStr16 *g_dynstr16_new(uint16_t cap, uint16_t len, const void *data); DynStr16 *g_dynstr16_new(uint16_t cap, uint16_t len, const void *data);
DynStr16 *g_dynstr16_append(DynStr16*, 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 *FSLink;
extern void *VidLink; extern void *VidLink;
struct WTreeNode { struct GWindow {
char vertical; struct k3MObj *whole;
struct GWindow *window; struct k3MLabel *title;
struct WTreeNode *parent; struct k3MObj *panel;
struct WTreeNode *first;
struct WTreeNode *second; // k3Menu only supports one "focused" element per k3MScreen,
// but we want to save these when people Alt+Tab
struct k3MObj *focus;
}; };
extern struct WTreeNode *windowTreeFocus; struct GWindow *add_window(const char *title);
int add_window(struct GWindow *w);
int is_free_space(); int is_free_space();
void dirty(int x, int y, int w, int h); void dirty(int x, int y, int w, int h);
void dirty_obj(struct GObj*); void dirty_obj(struct k3MObj*);