Compare commits
No commits in common. "7e506265ce5a3825852f5d6dab2851d3f8d43ff3" and "93b885cb434c500aa1252071bb1cce6d7fadbdcd" have entirely different histories.
7e506265ce
...
93b885cb43
@ -1,73 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include"../vid/api.h"
|
||||
#include"../sys.h"
|
||||
|
||||
extern void *VidLink;
|
||||
|
||||
static inline void immdraw_font_draw(uint16_t x, uint16_t y, uint16_t w, size_t txtlen, const char *txt, uint8_t align) {
|
||||
LumaVidCommand *cmd = VidLink;
|
||||
|
||||
cmd->op = LUMA_VID_COMMAND_SET_COLOR_FLAT;
|
||||
cmd->colorFlat.r = 0x00;
|
||||
cmd->colorFlat.g = 0x00;
|
||||
cmd->colorFlat.b = 0x00;
|
||||
cmd = (LumaVidCommand*) ((uintptr_t) cmd + sizeof(cmd->colorFlat));
|
||||
|
||||
cmd->op = LUMA_VID_COMMAND_TEXT;
|
||||
cmd->text.x = x;
|
||||
cmd->text.y = y;
|
||||
cmd->text.wall = x + w;
|
||||
cmd->text.align = align;
|
||||
cmd->text.len = txtlen;
|
||||
std_copy(cmd->text.data, txt, txtlen);
|
||||
cmd = (LumaVidCommand*) ((uintptr_t) cmd + sizeof(cmd->text) + txtlen);
|
||||
|
||||
cmd->op = LUMA_VID_COMMAND_END;
|
||||
|
||||
memory_barrier();
|
||||
sys_signal_send(VidLink, -1);
|
||||
sys_signal_wait(VidLink, NULL);
|
||||
}
|
||||
|
||||
static inline void immdraw_fill_rect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint8_t r, uint8_t g, uint8_t b) {
|
||||
LumaVidCommand *cmd = VidLink;
|
||||
|
||||
cmd->op = LUMA_VID_COMMAND_SET_COLOR_FLAT;
|
||||
cmd->colorFlat.r = r;
|
||||
cmd->colorFlat.g = g;
|
||||
cmd->colorFlat.b = b;
|
||||
cmd = (LumaVidCommand*) ((uintptr_t) cmd + sizeof(cmd->colorFlat));
|
||||
|
||||
cmd->op = LUMA_VID_COMMAND_RECT;
|
||||
cmd->rect.x1 = x;
|
||||
cmd->rect.x2 = x + w - 1;
|
||||
cmd->rect.y1 = y;
|
||||
cmd->rect.y2 = y + h - 1;
|
||||
cmd = (LumaVidCommand*) ((uintptr_t) cmd + sizeof(cmd->rect));
|
||||
|
||||
cmd->op = LUMA_VID_COMMAND_END;
|
||||
|
||||
memory_barrier();
|
||||
sys_signal_send(VidLink, -1);
|
||||
sys_signal_wait(VidLink, NULL);
|
||||
}
|
||||
|
||||
static inline void immdraw_text_extent(size_t txtlen, const uint8_t *txt, size_t wall, uint16_t *w, uint16_t *h) {
|
||||
LumaVidCommand *cmd = VidLink;
|
||||
|
||||
cmd->op = LUMA_VID_COMMAND_TEXT_EXTENT;
|
||||
cmd->textExtent.wall = wall;
|
||||
cmd->textExtent.len = txtlen;
|
||||
std_copy(cmd->textExtent.data, txt, txtlen);
|
||||
cmd = (LumaVidCommand*) ((uintptr_t) cmd + sizeof(cmd->textExtent) + txtlen);
|
||||
|
||||
cmd->op = LUMA_VID_COMMAND_END;
|
||||
|
||||
memory_barrier();
|
||||
sys_signal_send(VidLink, -1);
|
||||
sys_signal_wait(VidLink, NULL);
|
||||
|
||||
*w = cmd->textExtent.w;
|
||||
*h = cmd->textExtent.h;
|
||||
}
|
373
luma/wm/k3menu.c
373
luma/wm/k3menu.c
@ -1,373 +0,0 @@
|
||||
#include"k3menu.h"
|
||||
|
||||
#include"immdraw.h"
|
||||
#include"../ps2/api.h"
|
||||
#include"tiny.h"
|
||||
#define memset __builtin_memset
|
||||
#define memcpy __builtin_memcpy
|
||||
|
||||
void k3MenuSetBounds_(struct k3MObj *this, int16_t x, int16_t y, int16_t w, int16_t h) {
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->w = w;
|
||||
this->h = h;
|
||||
}
|
||||
|
||||
static bool event_send_nonrecur(struct k3MEvent *ev) {
|
||||
bool handled = false;
|
||||
for(size_t i = 0; i < ev->target->handlerCount; i++) {
|
||||
struct k3MEventHandler *h = &ev->target->handlers[i];
|
||||
|
||||
if(h->code == ev->code || h->code == k3M_EVENT_ALL) {
|
||||
if(h->callback(ev, h->ud)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
int k3MRegisterEventHandler_(struct k3MObj *obj, uint16_t evcode, k3MEventHandlerFunc callback, uint8_t *ud, size_t udSize) {
|
||||
if(ud && udSize > k3M_USERDATA_SIZE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
obj->handlers = realloc(obj->handlers, sizeof(*obj->handlers) * ++obj->handlerCount);
|
||||
|
||||
obj->handlers[obj->handlerCount - 1].code = evcode;
|
||||
obj->handlers[obj->handlerCount - 1].callback = callback;
|
||||
if(ud) {
|
||||
memcpy(obj->handlers[obj->handlerCount - 1].ud, ud, udSize);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool k3MEventSend(struct k3MEvent *ev) {
|
||||
while(!event_send_nonrecur(ev)) {
|
||||
if(ev->kind == k3M_EVENTKIND_DIRECT) {
|
||||
return false;
|
||||
} else if(ev->kind == k3M_EVENTKIND_BUBBLE) {
|
||||
ev->target = ev->target->parent;
|
||||
|
||||
if(ev->target == ev->original || !ev->target) {
|
||||
return false;
|
||||
}
|
||||
} else if(ev->kind == k3M_EVENTKIND_CAPTURE) {
|
||||
struct k3MObj *parent = ev->target;
|
||||
|
||||
for(size_t i = 0; i < parent->childCount; i++) {
|
||||
if(!parent->children[i]->invisible) {
|
||||
ev->target = parent->children[i];
|
||||
|
||||
if(k3MEventSend(ev)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void obj_draw(struct k3MObj *this) {
|
||||
struct k3MProperty *borderRadiusProp = k3MFindProperty(this, k3M_PROP_BORDER_RADIUS, false);
|
||||
//float borderRadius = borderRadiusProp ? borderRadiusProp->si[0] : 0;
|
||||
|
||||
struct k3MProperty *bgColorProp = k3MFindProperty(this, k3M_PROP_BG_COLOR, false);
|
||||
|
||||
uint8_t r = 0, g = 0, b = 0, a = 0;
|
||||
if(bgColorProp) {
|
||||
r = bgColorProp->si[0];
|
||||
g = bgColorProp->si[1];
|
||||
b = bgColorProp->si[2];
|
||||
a = bgColorProp->si[3];
|
||||
}
|
||||
|
||||
if(a != 0) {
|
||||
immdraw_fill_rect(this->x, this->y, this->w, this->h, r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
static bool label_draw(struct k3MEvent *ev, uint8_t *ud) {
|
||||
struct k3MLabel *this = (void*) ev->target;
|
||||
|
||||
obj_draw((void*) this);
|
||||
|
||||
if(this->txt) {
|
||||
immdraw_font_draw(this->x, this->y, this->w, strlen(this->txt), this->txt, LUMA_VID_TEXT_ALIGN_CENTER);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
struct k3MLabel *k3MLabel(struct k3Font *font, uint32_t sz, const char *txt) {
|
||||
struct k3MLabel *ret = calloc(1, sizeof(*ret));
|
||||
ret->font = font;
|
||||
ret->sz = sz;
|
||||
ret->txt = txt;
|
||||
|
||||
k3MRegisterEventHandler(ret, k3M_EVENT_DRAW, label_draw, NULL, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int k3MRemoveChild(struct k3MObj *parent, struct k3MObj *child) {
|
||||
for(size_t i = 0; i < parent->childCount; i++) {
|
||||
if(parent->children[i] == child) {
|
||||
memcpy(&parent->children[i], &parent->children[i + 1], sizeof(*parent->children) * (parent->childCount - i - 1));
|
||||
|
||||
parent->childCount--;
|
||||
|
||||
child->parent = NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void k3MAddChild(struct k3MObj *parent, struct k3MObj *child) {
|
||||
if(child->parent) {
|
||||
k3MRemoveChild(child->parent, child);
|
||||
}
|
||||
|
||||
parent->children = realloc(parent->children, sizeof(*parent->children) * (++parent->childCount));
|
||||
parent->children[parent->childCount - 1] = child;
|
||||
|
||||
child->parent = parent;
|
||||
|
||||
if(parent->layout) {
|
||||
parent->layout(parent);
|
||||
}
|
||||
}
|
||||
|
||||
void k3MOverrideProperty(struct k3MObj *obj, struct k3MProperty n) {
|
||||
struct k3MProperty *o = k3MFindProperty(obj, n.type, true);
|
||||
|
||||
if(!o) {
|
||||
obj->properties = realloc(obj->properties, ++obj->propertyCount * sizeof(*obj->properties));
|
||||
o = &obj->properties[obj->propertyCount - 1];
|
||||
}
|
||||
|
||||
memcpy(o, &n, sizeof(n));
|
||||
}
|
||||
|
||||
struct k3MProperty *k3MFindProperty(struct k3MObj *obj, enum k3MPropertyType t, bool direct) {
|
||||
for(size_t i = 0; i < obj->propertyCount; i++) {
|
||||
if(obj->properties[i].type == t) {
|
||||
return &obj->properties[i];
|
||||
}
|
||||
}
|
||||
if(direct || !obj->parent) {
|
||||
return NULL;
|
||||
}
|
||||
return k3MFindProperty(obj->parent, t, direct);
|
||||
}
|
||||
|
||||
static bool screen_ev(struct k3MEvent *ev, uint8_t *ud) {
|
||||
struct k3MScreen *this = (void*) ev->target;
|
||||
|
||||
if(ev->code == k3M_EVENT_MOUSE_PRESS || ev->code == k3M_EVENT_MOUSE_RELEASE || ev->code == k3M_EVENT_MOUSE_MOTION) {
|
||||
struct k3MObj *innermost = (void*) this;
|
||||
|
||||
while(innermost->childCount != 0) {
|
||||
|
||||
bool foundInner = false;
|
||||
|
||||
for(intmax_t i = innermost->childCount - 1; i >= 0; i--) {
|
||||
|
||||
struct k3MObj *child = innermost->children[i];
|
||||
|
||||
if(!child->invisible && ev->mouse.x >= child->x && ev->mouse.x < child->x + child->w && ev->mouse.y >= child->y && ev->mouse.y < child->y + child->h) {
|
||||
|
||||
innermost = child;
|
||||
foundInner = true;
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(!foundInner) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(innermost != this->lastHover) {
|
||||
this->lastHover->hovered = false;
|
||||
innermost->hovered = true;
|
||||
this->lastHover = innermost;
|
||||
}
|
||||
|
||||
if(innermost != (void*) this) {
|
||||
|
||||
if(ev->code == k3M_EVENT_MOUSE_PRESS) {
|
||||
this->keyboardFocus = innermost;
|
||||
}
|
||||
|
||||
ev->kind = k3M_EVENTKIND_BUBBLE;
|
||||
ev->target = innermost;
|
||||
k3MEventSend(ev);
|
||||
|
||||
if(ev->code == k3M_EVENT_MOUSE_RELEASE) {
|
||||
ev->code = k3M_EVENT_MOUSE_CLICK;
|
||||
|
||||
ev->kind = k3M_EVENTKIND_DIRECT;
|
||||
ev->target = innermost;
|
||||
k3MEventSend(ev);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if(ev->code == k3M_EVENT_KEY_PRESS || ev->code == k3M_EVENT_KEY_RELEASE || ev->code == k3M_EVENT_INPUT) {
|
||||
if(this->keyboardFocus) {
|
||||
ev->kind = k3M_EVENTKIND_BUBBLE;
|
||||
ev->target = (void*) this->keyboardFocus;
|
||||
asm volatile("xchg %%bx, %%bx":::);
|
||||
k3MEventSend(ev);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
ev->kind = k3M_EVENTKIND_CAPTURE;
|
||||
for(intmax_t i = this->childCount; i --> 0;) {
|
||||
if(!this->children[i]->invisible) {
|
||||
ev->target = this->children[i];
|
||||
if(k3MEventSend(ev)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
struct k3MScreen *k3MScreen() {
|
||||
struct k3MScreen *ret = calloc(1, sizeof(*ret));
|
||||
|
||||
ret->lastHover = (void*) ret;
|
||||
|
||||
k3MRegisterEventHandler(ret, k3M_EVENT_ALL, screen_ev, NULL, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool textbutton_draw(struct k3MEvent *ev, uint8_t *ud) {
|
||||
struct k3MTextButton *this = (void*) ev->target;
|
||||
|
||||
obj_draw((void*) this);
|
||||
|
||||
if(this->txt) {
|
||||
//struct k3RectF txtsz;
|
||||
//k3FontSz(this->font, this->sz, this->txt, &txtsz);
|
||||
|
||||
//k3FontDraw(this->font, this->x + this->w / 2 - txtsz.w / 2, this->y, this->sz, this->txt, (vec4) {
|
||||
// 1 - 0.8 * this->disabled, 1 - 0.8 * this->disabled, 1 - 0.8 * this->disabled, 1});
|
||||
|
||||
int top = 1, right = 1, bottom = 1, left = 1;
|
||||
|
||||
struct k3MProperty *marginProp = k3MFindProperty(this, k3M_PROP_MARGIN, false);
|
||||
if(marginProp) {
|
||||
top = marginProp->si[0];
|
||||
right = marginProp->si[1];
|
||||
bottom = marginProp->si[2];
|
||||
left = marginProp->si[3];
|
||||
}
|
||||
|
||||
immdraw_font_draw(this->x + top, this->y + left, this->w - left - right, strlen(this->txt), this->txt, LUMA_VID_TEXT_ALIGN_CENTER);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
struct k3MTextButton *k3MTextButton(struct k3Font *font, uint32_t sz, const char *txt) {
|
||||
struct k3MTextButton *ret = calloc(1, sizeof(*ret));
|
||||
|
||||
ret->font = font;
|
||||
ret->sz = sz;
|
||||
ret->txt = txt;
|
||||
|
||||
k3MRegisterEventHandler(ret, k3M_EVENT_DRAW, textbutton_draw, NULL, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool textinput_draw(struct k3MEvent *ev, uint8_t *ud) {
|
||||
struct k3MTextInput *this = (void*) ev->target;
|
||||
|
||||
obj_draw((void*) this);
|
||||
|
||||
if(this->txt) {
|
||||
int isPlaceholder = strlen(this->txt) == 0;
|
||||
const char *txt = isPlaceholder ? this->placeholder : this->txt;
|
||||
|
||||
//struct k3RectF txtsz;
|
||||
//immdraw_font_getsize(this->font, this->sz, txt, &txtsz);
|
||||
|
||||
immdraw_font_draw(this->x + 2, this->y + 2, this->w, strlen(txt), txt, LUMA_VID_TEXT_ALIGN_LEFT);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
static bool textinput_key(struct k3MEvent *ev, uint8_t *ud) {
|
||||
struct k3MTextInput *this = (void*) ev->target;
|
||||
|
||||
if(ev->key.num == LK_BACKSPACE && ev->code != k3M_EVENT_KEY_RELEASE) {
|
||||
char *last = k3UTF8LastCodepointZ(this->txt);
|
||||
if(last) {
|
||||
*last = 0;
|
||||
}
|
||||
} else if(ev->key.num == LK_ENTER && ev->code == k3M_EVENT_KEY_PRESS) {
|
||||
struct k3MEvent newev = {
|
||||
.code = k3M_EVENT_COMPLETE,
|
||||
.kind = k3M_EVENTKIND_DIRECT,
|
||||
|
||||
.original = (void*) this,
|
||||
.target = (void*) this,
|
||||
};
|
||||
|
||||
k3MEventSend(&newev);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
static bool textinput_char(struct k3MEvent *ev, uint8_t *ud) {
|
||||
struct k3MTextInput *this = (void*) ev->target;
|
||||
|
||||
size_t len = strlen(this->txt);
|
||||
|
||||
this->txt = realloc(this->txt, len + 5);
|
||||
len += k3UTF8Encode(ev->input.code, this->txt + len);
|
||||
this->txt[len] = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
struct k3MTextInput *k3MTextInput(struct k3Font *font, uint32_t sz, const char *placeholder, const char *txt) {
|
||||
struct k3MTextInput *ret = calloc(1, sizeof(*ret));
|
||||
|
||||
ret->font = font;
|
||||
ret->sz = sz;
|
||||
ret->placeholder = placeholder ? placeholder : "";
|
||||
ret->txt = strdup(txt ? txt : "");
|
||||
|
||||
k3MRegisterEventHandler(ret, k3M_EVENT_DRAW, textinput_draw, NULL, 0);
|
||||
k3MRegisterEventHandler(ret, k3M_EVENT_KEY_PRESS, textinput_key, NULL, 0);
|
||||
k3MRegisterEventHandler(ret, k3M_EVENT_KEY_RELEASE, textinput_key, NULL, 0);
|
||||
k3MRegisterEventHandler(ret, k3M_EVENT_INPUT, textinput_char, NULL, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct k3MObj *k3MObj() {
|
||||
struct k3MObj *ret = calloc(1, sizeof(*ret));
|
||||
return ret;
|
||||
}
|
207
luma/wm/k3menu.h
207
luma/wm/k3menu.h
@ -1,207 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include<stdint.h>
|
||||
#include<stdbool.h>
|
||||
#include<stddef.h>
|
||||
#include"tiny.h"
|
||||
|
||||
struct k3Font;
|
||||
struct k3MObj;
|
||||
|
||||
#define k3M_EVENT_MOUSE_ENTER 0
|
||||
#define k3M_EVENT_MOUSE_MOTION 1
|
||||
#define k3M_EVENT_MOUSE_LEAVE 2
|
||||
#define k3M_EVENT_MOUSE_PRESS 3
|
||||
#define k3M_EVENT_MOUSE_RELEASE 4
|
||||
#define k3M_EVENT_MOUSE_CLICK 5
|
||||
#define k3M_EVENT_KEY_PRESS 6
|
||||
#define k3M_EVENT_KEY_RELEASE 7
|
||||
#define k3M_EVENT_INPUT 8
|
||||
#define k3M_EVENT_DRAW 9
|
||||
#define k3M_EVENT_COMPLETE 10
|
||||
#define k3M_EVENT_ALL 11
|
||||
|
||||
#define k3M_MOUSE_BUTTON_0 0
|
||||
#define k3M_MOUSE_BUTTON_1 1
|
||||
#define k3M_MOUSE_BUTTON_2 2
|
||||
|
||||
#define k3M_EVENTKIND_DIRECT 0
|
||||
#define k3M_EVENTKIND_CAPTURE 1
|
||||
#define k3M_EVENTKIND_BUBBLE 2
|
||||
|
||||
#define k3M_USERDATA_SIZE 16
|
||||
|
||||
#include"../std.h"
|
||||
|
||||
struct k3MEvent {
|
||||
uint16_t code;
|
||||
|
||||
uint8_t kind;
|
||||
|
||||
struct k3MObj *original;
|
||||
struct k3MObj *target;
|
||||
|
||||
union {
|
||||
struct {
|
||||
int button;
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
} mouse;
|
||||
struct {
|
||||
uint32_t num;
|
||||
} key;
|
||||
struct {
|
||||
uint32_t code;
|
||||
} input;
|
||||
};
|
||||
};
|
||||
|
||||
typedef bool(*k3MEventHandlerFunc)(struct k3MEvent*, uint8_t *ud);
|
||||
|
||||
typedef struct k3MEventHandler {
|
||||
uint8_t ud[k3M_USERDATA_SIZE];
|
||||
k3MEventHandlerFunc callback;
|
||||
uint16_t code;
|
||||
} k3MEventHandler;
|
||||
|
||||
enum k3MPropertyType {
|
||||
k3M_PROP_BG_COLOR,
|
||||
k3M_PROP_BORDER_RADIUS,
|
||||
k3M_PROP_MARGIN,
|
||||
};
|
||||
struct k3MProperty {
|
||||
enum k3MPropertyType type;
|
||||
union {
|
||||
intmax_t si[4];
|
||||
void *ptr;
|
||||
uint8_t buf[32];
|
||||
};
|
||||
};
|
||||
|
||||
typedef void(*k3MLayout)(struct k3MObj*);
|
||||
|
||||
struct k3MObj {
|
||||
struct k3MObj *parent;
|
||||
|
||||
k3MLayout layout;
|
||||
|
||||
size_t childCount;
|
||||
struct k3MObj **children;
|
||||
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
int16_t w;
|
||||
int16_t h;
|
||||
|
||||
bool invisible, hovered, disabled;
|
||||
|
||||
k3MEventHandler *handlers;
|
||||
size_t handlerCount;
|
||||
|
||||
struct k3MProperty *properties;
|
||||
size_t propertyCount;
|
||||
};
|
||||
struct k3MObj *k3MObj();
|
||||
|
||||
#define k3MenuSetBounds(a, x, y, w, h) k3MenuSetBounds_((struct k3MObj*) (a), (x), (y), (w), (h))
|
||||
void k3MenuSetBounds_(struct k3MObj *this, int16_t x, int16_t y, int16_t w, int16_t h);
|
||||
|
||||
#define k3MRegisterEventHandler(a, c, cb, ud, udsz) k3MRegisterEventHandler_((struct k3MObj*) (a), (c), (cb), (ud), (udsz))
|
||||
int k3MRegisterEventHandler_(struct k3MObj *obj, uint16_t evcode, k3MEventHandlerFunc callback, uint8_t *ud, size_t udSize);
|
||||
|
||||
bool k3MEventSend(struct k3MEvent *ev);
|
||||
|
||||
int k3MRemoveChild(struct k3MObj *parent, struct k3MObj *child);
|
||||
void k3MAddChild(struct k3MObj *parent, struct k3MObj *child);
|
||||
|
||||
void k3MOverrideProperty(struct k3MObj *obj, struct k3MProperty);
|
||||
struct k3MProperty *k3MFindProperty(struct k3MObj *obj, enum k3MPropertyType, bool direct);
|
||||
|
||||
struct k3MLabel {
|
||||
struct k3MObj;
|
||||
|
||||
struct k3Font *font;
|
||||
uint32_t sz;
|
||||
char *txt;
|
||||
};
|
||||
struct k3MLabel *k3MLabel(struct k3Font *font, uint32_t millipts, const char *txt);
|
||||
|
||||
struct k3MScreen {
|
||||
struct k3MObj;
|
||||
|
||||
struct k3MObj *keyboardFocus;
|
||||
struct k3MObj *lastHover;
|
||||
};
|
||||
struct k3MScreen *k3MScreen();
|
||||
|
||||
struct k3MTextButton {
|
||||
struct k3MObj;
|
||||
|
||||
struct k3Font *font;
|
||||
uint32_t sz;
|
||||
char *txt;
|
||||
};
|
||||
struct k3MTextButton *k3MTextButton(struct k3Font *font, uint32_t millipts, const char *txt);
|
||||
|
||||
struct k3MTextInput {
|
||||
struct k3MObj;
|
||||
|
||||
struct k3Font *font;
|
||||
uint32_t sz;
|
||||
|
||||
char *placeholder;
|
||||
|
||||
char *txt;
|
||||
};
|
||||
struct k3MTextInput *k3MTextInput(struct k3Font *font, uint32_t millipts, const char *placeholder, const char *txt);
|
||||
|
||||
static inline int k3UTF8Encode(uint32_t cp, uint8_t ret[static 4]) {
|
||||
if(cp < 0x80) {
|
||||
ret[0] = cp;
|
||||
return 1;
|
||||
} else if(cp < 0x800) {
|
||||
ret[0] = 192 | (cp >> 6);
|
||||
ret[1] = 128 | (cp & 63);
|
||||
return 2;
|
||||
} else if(cp < 0x10000) {
|
||||
ret[0] = 224 | (cp >> 12);
|
||||
ret[1] = 128 | ((cp >> 6) & 63);
|
||||
ret[2] = 128 | (cp & 63);
|
||||
return 3;
|
||||
} else if(cp < 0x110000) {
|
||||
ret[0] = 240 | (cp >> 18);
|
||||
ret[1] = 128 | ((cp >> 12) & 63);
|
||||
ret[2] = 128 | ((cp >> 6) & 63);
|
||||
ret[3] = 128 | (cp & 63);
|
||||
return 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline size_t strlen(const char *str) {
|
||||
size_t sz = 0;
|
||||
while(*str) {
|
||||
sz++;
|
||||
str++;
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
static inline const char *k3UTF8LastCodepointZ(const char *txt) {
|
||||
size_t len = strlen(txt);
|
||||
while(len--) {
|
||||
if((txt[len] & 0xC0) != 0x80) {
|
||||
return &txt[len];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline char *strdup(const char *s) {
|
||||
size_t len = strlen(s);
|
||||
char *d = tiny_malloc(len + 1);
|
||||
d[len] = '\0';
|
||||
__builtin_memcpy(d, s, len);
|
||||
return d;
|
||||
}
|
||||
|
@ -17,10 +17,4 @@
|
||||
#define PAGE_BIT_WRITABLE 2
|
||||
#define PAGE_BIT_USER 4
|
||||
|
||||
#define PAGE_PRESENT(p) ((p) & (PAGE_BIT_PRESENT))
|
||||
|
||||
#define PAGE_SIZE 4096
|
||||
|
||||
#define ROUND_UP_POT(i, n) (((i) + ((n) - 1)) & ~((n) - 1))
|
||||
|
||||
#endif
|
@ -21,7 +21,7 @@ uint32_t scheduler_Tick;
|
||||
void klogs(const char *str);
|
||||
void klogc(int c);
|
||||
|
||||
void klogp(void *p) {
|
||||
static void klogp(void *p) {
|
||||
static char hex[16]="0123456789ABCDEF";
|
||||
|
||||
uintptr_t i = (uintptr_t) p;
|
||||
|
@ -2,57 +2,49 @@
|
||||
|
||||
#include"ppm.h"
|
||||
#include"mem.h"
|
||||
#include"consts.h"
|
||||
|
||||
static void invlpg(uint32_t virtaddr) {
|
||||
asm volatile("invlpg %0" : : "m"(*(char*)virtaddr) : "memory");
|
||||
}
|
||||
extern void *_kernel_end;
|
||||
|
||||
static void set_temporary_mapping(uint32_t addr) {
|
||||
void set_temporary_mapping(uint32_t addr) {
|
||||
if((addr & 0xFFF) != 0) asm volatile("xchgw %bx, %bx");
|
||||
|
||||
*(volatile uint32_t*) 0xFFFFFFF8 = addr | 3;
|
||||
asm volatile("invlpg 0xFFFFE000" : : : "memory");
|
||||
}
|
||||
|
||||
static uint32_t spaceBoundaries[2] = {[VPM_KERNEL] = 4096, [VPM_USER] = 1 * 1024 * 1024 * 1024};
|
||||
static uint32_t nextAllocs[2] = {[VPM_KERNEL] = 0, [VPM_USER] = 1 * 1024 * 1024 * 1024};
|
||||
|
||||
void vpm_init(uint32_t kernelEnd) {
|
||||
//spaceBoundaries[VPM_KERNEL] = (kernelEnd + 4095) & ~4095;
|
||||
nextAllocs[VPM_KERNEL] = (kernelEnd + 4095) & ~4095;
|
||||
}
|
||||
|
||||
/* This is a linear search. Improve? */
|
||||
uint32_t vpm_find_free(uint32_t addrspace, AllocationOwner owner, size_t len) {
|
||||
len = ROUND_UP_POT(len, PAGE_SIZE);
|
||||
/* TODO: Make better. */
|
||||
uint32_t vpm_find_free(uint32_t addrspace, AllocationOwner owner, size_t lenBytes) {
|
||||
size_t len = (lenBytes + 4095) / 4096;
|
||||
|
||||
for(uint32_t attempt = spaceBoundaries[owner]; attempt != 0;) {
|
||||
for(size_t i = 0; i < len;) {
|
||||
uint32_t pdeid = (attempt + i) >> 22;
|
||||
uint32_t pteid = ((attempt + i) >> 12) & 1023;
|
||||
uint32_t ret = nextAllocs[owner];
|
||||
for(size_t i = 0; i < len;) {
|
||||
uint32_t pdeid = (ret + i * 4096) >> 22;
|
||||
uint32_t pteid = ((ret + i * 4096) >> 12) & 1023;
|
||||
|
||||
set_temporary_mapping(addrspace);
|
||||
set_temporary_mapping(addrspace);
|
||||
|
||||
volatile uint32_t *pde = &((volatile uint32_t*) 0xFFFFE000)[pdeid];
|
||||
if(!PAGE_PRESENT(*pde)) {
|
||||
i += PAGE_SIZE * 1024 * 1024; // 4MB
|
||||
volatile uint32_t *pde = &((volatile uint32_t*) 0xFFFFE000)[pdeid];
|
||||
if((*pde & 1) == 0) {
|
||||
i += 4096;
|
||||
} else {
|
||||
set_temporary_mapping(*pde & ~0xFFF);
|
||||
|
||||
if((((volatile uint32_t*) 0xFFFFE000)[pteid] & 1) == 0) {
|
||||
i++;
|
||||
} else {
|
||||
set_temporary_mapping((*pde) & ~0xFFF);
|
||||
|
||||
volatile uint32_t *pte = &((volatile uint32_t*) 0xFFFFE000)[pteid];
|
||||
|
||||
if(!PAGE_PRESENT(*pte)) {
|
||||
i += PAGE_SIZE;
|
||||
} else {
|
||||
attempt += i + PAGE_SIZE;
|
||||
goto try_next;
|
||||
}
|
||||
ret += (i + 1) * 4096;
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
return attempt;
|
||||
try_next:
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* If phys is -1, map to uncontiguous physical pages anywhere, else map contiguous span of physical memory. */
|
||||
@ -107,8 +99,8 @@ void *vpm_map(uint32_t addrspace, AllocationOwner owner, uint32_t virt, uint32_t
|
||||
*pte |= 3 | (owner == VPM_USER ? 4 : 0);
|
||||
|
||||
if(thisspace == addrspace) {
|
||||
invlpg(virt + i * 4096);
|
||||
//asm volatile("invlpg %0" : : "m"(*(char*) (virt + i * 4096)) : "memory");
|
||||
//~ asm volatile("xchg %bx, %bx");
|
||||
asm volatile("invlpg %0" : : "m"(*(char*) (virt + i * 4096)) : "memory");
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,8 +164,7 @@ int vpm_double_map(uint32_t cr3a, uint32_t cr3b, uint32_t *va, uint32_t *vb, uin
|
||||
*pte = backend | 3 | 4;
|
||||
|
||||
if(thisspace == cr3a) {
|
||||
invlpg(*va + i * 4096);
|
||||
//asm volatile("invlpg %0" : : "m"(*(char*) (*va + i * 4096)) : "memory");
|
||||
asm volatile("invlpg %0" : : "m"(*(char*) (*va + i * 4096)) : "memory");
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,8 +193,7 @@ int vpm_double_map(uint32_t cr3a, uint32_t cr3b, uint32_t *va, uint32_t *vb, uin
|
||||
*pte = backend | 3 | 4;
|
||||
|
||||
if(thisspace == cr3b) {
|
||||
invlpg(*vb + i * 4096);
|
||||
//asm volatile("invlpg %0" : : "m"(*(char*) (*vb + i * 4096)) : "memory");
|
||||
asm volatile("invlpg %0" : : "m"(*(char*) (*vb + i * 4096)) : "memory");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -272,8 +262,7 @@ void vpm_unmap(uint32_t cr3, uint32_t virt, size_t len) {
|
||||
((volatile uint32_t*) 0xFFFFE000)[pteid] = 0;
|
||||
|
||||
if(thisspace == cr3) {
|
||||
invlpg(virt + i * 4096);
|
||||
//asm volatile("invlpg %0" : : "m"(*(char*) (virt + i * 4096)) : "memory");
|
||||
asm volatile("invlpg %0" : : "m"(*(char*) (virt + i * 4096)) : "memory");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ typedef enum {
|
||||
VPM_KERNEL, VPM_USER
|
||||
} AllocationOwner;
|
||||
|
||||
void set_temporary_mapping(uint32_t addr);
|
||||
|
||||
uint32_t vpm_find_free(uint32_t addrspace, AllocationOwner owner, size_t len);
|
||||
void *vpm_map(uint32_t cr3, AllocationOwner owner, uint32_t virt, uint32_t phys, size_t len);
|
||||
uint32_t vpm_create_space();
|
||||
|
Loading…
Reference in New Issue
Block a user