Compare commits

..

3 Commits

Author SHA1 Message Date
Alec Murphy 918e591d86 Misc: Zero fn_index[] 2026-05-02 17:53:08 -04:00
Alec Murphy 1a38c95dc3 Cmd: Disable Saphir on task end cleanup if we are the last Win 2026-05-02 17:29:39 -04:00
Alec Murphy 8b784fae0a Everywhere: Use SaphirNode 2026-05-02 17:03:32 -04:00
5 changed files with 360 additions and 56 deletions
+23 -1
View File
@@ -1,3 +1,5 @@
#define SAPHIR_NODE_SIG 0x9999baca
class SaphirAttr { class SaphirAttr {
I64 fg; I64 fg;
I64 bg; I64 bg;
@@ -17,15 +19,35 @@ class SaphirCursor : SaphirAttr {
class SaphirKeyDev { class SaphirKeyDev {
U64 sys_cbs; U64 sys_cbs;
U64 null_cbs; U64 null_cbs;
} };
class SaphirRect {
I32 x1;
I32 y1;
I32 x2;
I32 y2;
};
class SaphirNode {
U32 sig;
Bool mode;
SaphirRect rect;
I64 count;
I64 index;
U64** child;
SaphirNode* parent_node;
};
class SaphirGlbls { class SaphirGlbls {
Bool debug;
Bool enabled; Bool enabled;
Bool blink; Bool blink;
SaphirBorder border; SaphirBorder border;
SaphirCursor cursor; SaphirCursor cursor;
SaphirAttr status; SaphirAttr status;
SaphirKeyDev kd; SaphirKeyDev kd;
SaphirNode* root_node;
SaphirNode* current_node;
I64 doc_cursor_state; I64 doc_cursor_state;
} saphir; } saphir;
MemSet(&saphir, 0, sizeof(SaphirGlbls)); MemSet(&saphir, 0, sizeof(SaphirGlbls));
+332 -54
View File
@@ -1,6 +1,30 @@
extern I64 Saphir(Bool enable = TRUE);
U0 saphir_debug_info(SaphirRect* rect)
{
DCFill;
gr.dc->color = LTPURPLE;
GrRect(gr.dc, 0, 0, 640, 8);
gr.dc->color = WHITE;
GrPrint(gr.dc, 0, 0, "node: 0x%08x, index: %d", saphir.current_node, saphir.current_node->index);
gr.dc->color = CYAN;
GrLine(gr.dc, 8 * rect->x1, 8 * rect->y1, 8 * rect->x2, 8 * rect->y2);
GrLine(gr.dc, 8 * rect->x1, 8 * rect->y2, 8 * rect->x2, 8 * rect->y1);
}
Bool saphir_node_validate(SaphirNode* node)
{
if (!node) {
return FALSE;
}
return node->sig == SAPHIR_NODE_SIG;
}
Bool saphir_task_is_windowed(CTask* task) Bool saphir_task_is_windowed(CTask* task)
{ {
if (!task || task == ac.task) { if (!task || task == ac.task || task == adam_task) {
return FALSE; return FALSE;
} }
if ((task->display_flags & 1 << DISPLAYf_SHOW) && ((task->display_flags & 1 << DISPLAYf_NOT_RAW))) if ((task->display_flags & 1 << DISPLAYf_SHOW) && ((task->display_flags & 1 << DISPLAYf_NOT_RAW)))
@@ -8,75 +32,329 @@ Bool saphir_task_is_windowed(CTask* task)
return FALSE; return FALSE;
} }
U0 saphir_split_row() I64 saphir_reflow_step(SaphirNode* node)
{ {
CTask* task1 = sys_focus_task; switch (node->mode) {
CTask* task2 = User; case 0:
MemCpy(&task2->win_left, &task1->win_left, 32); return ((node->rect.y2 - node->rect.y1) / node->count);
task1->win_bottom = (task1->win_top + task1->win_bottom) / 2; case 1:
task2->win_top = task1->win_bottom + 2; return ((node->rect.x2 - node->rect.x1) / node->count);
default:
return 0;
}
}
U0 saphir_reflow_win(CTask* task, SaphirRect* rect)
{
if (!task || !rect) {
return;
}
task->win_top = rect->y1;
task->win_left = rect->x1;
task->win_bottom = rect->y2;
task->win_right = rect->x2;
WinZBufUpdate; WinZBufUpdate;
} }
U0 saphir_split_col() U0 saphir_remove_child(SaphirNode* node, I64 i)
{ {
CTask* task1 = sys_focus_task; I64 j;
CTask* task2 = User; for (j = i; j < 16; j++) {
MemCpy(&task2->win_left, &task1->win_left, 32); node->child[j] = node->child[j + 1];
task1->win_right = (task1->win_left + task1->win_right) / 2;
task2->win_left = task1->win_right + 2;
WinZBufUpdate;
}
I64 saphir_win_select_CR(I64 dir)
{
if (dir & 1) {
return TEXT_COLS + 1;
} }
return TEXT_ROWS + 1; --node->count;
} if (node->index == i) {
--node->index;
I64 saphir_win_select_XY(I64 wt, I64 wl, I64 dir) node->index = MaxI64(0, node->index);
{
if (dir & 1) {
return wl;
} }
return wt;
} }
I64 saphir_win_select_pos(I64 dir) U0 saphir_destroy_node(SaphirNode* node)
{ {
return 1 - (2 * (dir < SC_CURSOR_RIGHT)); if (!node) {
} return;
Bool saphir_task_should_focus(CTask* task1, I64 i, I64 wl, I64 dir)
{
if (dir & 1) {
return task1->win_left == i;
} }
return task1->win_top == i && task1->win_left == wl; // FIXME: do this cleanly
if (node->child) {
Free(node->child);
}
Free(node);
} }
U0 saphir_win_select(I64 dir) Bool saphir_reflow(SaphirNode* node = NULL)
{ {
CTask* task = sys_focus_task; if (!node) {
CTask* task1; node = saphir.root_node;
I64 wt = task->win_top; }
I64 wl = task->win_left;
I64 i, j, k;
i = j = saphir_win_select_pos(dir); SaphirNode* tmp_node;
i += saphir_win_select_XY(wt, wl, dir); SaphirRect rect;
k = saphir_win_select_CR(dir); SaphirRect debug_rect;
MemCpy(&rect, &node->rect, sizeof(SaphirRect));
for (i = i; i > 0 && i < k; i += j) { // orig_x1, orig_y1
task1 = adam_task->next_task; debug_rect.x1 = rect.x1;
while (task1 != adam_task) { debug_rect.y1 = rect.y1;
if (saphir_task_is_windowed(task1) && saphir_task_should_focus(task1, i, wl, dir)) {
WinFocus(task1); I64 i;
return; I64 step = saphir_reflow_step(node);
for (i = 0; i < node->count; i++) {
switch (node->mode) {
case 0:
rect.y2 = rect.y1 + step;
break;
case 1:
rect.x2 = rect.x1 + step;
break;
default:
PopUpOk("error1 : node->mode invalid");
"mode: %d\n", node->mode;
Break;
}
if (saphir_node_validate(node->child[i])) {
tmp_node = node->child[i];
if (tmp_node->count < 2) {
node->child[i] = tmp_node->child[0];
saphir_destroy_node(tmp_node);
if (saphir.current_node == tmp_node) {
saphir.current_node = node;
node->index = i;
}
return FALSE;
} }
task1 = task1->next_task; MemCpy(&node->child[i](SaphirNode*)->rect, &rect, sizeof(SaphirRect));
if (saphir.current_node == node && saphir.current_node->index == i) {
saphir.current_node = node->child[i];
}
if (!saphir_reflow(node->child[i])) {
return FALSE;
}
} else {
if (TaskValidate(node->child[i])) {
saphir_reflow_win(node->child[i], &rect);
if (saphir.current_node == node && saphir.current_node->index == i) {
WinFocus(node->child[i]);
}
WinZBufUpdate;
} else {
saphir_remove_child(node, i);
return FALSE;
}
}
switch (node->mode) {
case 0:
rect.y1 = rect.y2 + 2;
break;
case 1:
rect.x1 = rect.x2 + 2;
break;
default:
PopUpOk("error2 : node->mode invalid");
Break;
} }
} }
}
if (node == saphir.current_node && saphir.debug) {
debug_rect.x2 = rect.x2;
debug_rect.y2 = rect.y2;
saphir_debug_info(&debug_rect);
}
return TRUE;
}
U0 saphir_reflow_task_end()
{
if (saphir.current_node == saphir.root_node && saphir.current_node->count == 1) {
Saphir(0);
return;
}
while (!saphir_reflow)
;
}
U0 saphir_reflow_task_end_cb()
{
Spawn(&saphir_reflow_task_end);
Exit;
}
U0 saphir_rect_set_defaults(SaphirRect* rect)
{
rect->x1 = 1;
rect->x2 = TEXT_COLS - 2;
rect->y1 = 2;
rect->y2 = TEXT_ROWS - 3;
}
SaphirNode* saphir_node_alloc(I64 mode = 0)
{
SaphirNode* node = CAlloc(sizeof(SaphirNode));
node->child = CAlloc(sizeof(U64*) * 16);
node->mode = mode;
node->sig = SAPHIR_NODE_SIG;
return node;
}
U0 saphir_node_append_task(SaphirNode* node, CTask* task)
{
if (!node || !task) {
return;
}
if (node->count && !(node->count % 16)) {
PopUpOk("FIXME: realloc node->child");
Break;
}
node->child[node->count++] = task;
task->task_end_cb = &saphir_reflow_task_end_cb;
}
U0 saphir_node_init_root()
{
saphir.root_node = saphir_node_alloc(1);
saphir_rect_set_defaults(&saphir.root_node->rect);
SaphirNode* node = saphir.root_node;
CTask* task1 = adam_task->next_task;
while (task1 != adam_task) {
if (saphir_task_is_windowed(task1)) {
saphir_node_append_task(node, task1);
}
task1 = task1->next_task;
}
}
U0 saphir_split_pane(I64 dir)
{
SaphirNode* node = saphir_node_alloc(dir);
CTask* new_task = User;
saphir_node_append_task(node, saphir.current_node->child[saphir.current_node->index]);
saphir_node_append_task(node, new_task);
node->parent_node = saphir.current_node;
saphir.current_node->child[saphir.current_node->index] = node;
saphir.current_node = node;
saphir.current_node->index = 1; // 1= focus the new User task created by splitting
while (!saphir_reflow)
;
}
U0 saphir_split_row()
{
saphir_split_pane(0);
}
U0 saphir_split_col()
{
saphir_split_pane(1);
}
U0 saphir_win_select_up()
{
SaphirNode* node = saphir.current_node;
if (!node->mode && node->index) {
--node->index;
return;
}
node = node->parent_node;
while (node && node->mode) {
node = node->parent_node;
}
if (node && node->index) {
--node->index;
}
if (node) {
saphir.current_node = node;
}
}
U0 saphir_win_select_down()
{
SaphirNode* node = saphir.current_node;
if (!node->mode && node->index < node->count - 1) {
++node->index;
return;
}
node = node->parent_node;
while (node && node->mode) {
node = node->parent_node;
}
if (node && node->index < node->count - 1) {
++node->index;
}
if (node) {
saphir.current_node = node;
}
}
U0 saphir_win_select_left()
{
SaphirNode* node = saphir.current_node;
if (node->mode && node->index) {
--node->index;
return;
}
node = node->parent_node;
while (node && !node->mode) {
node = node->parent_node;
}
if (node && node->index) {
--node->index;
}
if (node) {
saphir.current_node = node;
}
}
U0 saphir_win_select_right()
{
SaphirNode* node = saphir.current_node;
if (node->mode && node->index < node->count - 1) {
++node->index;
return;
}
node = node->parent_node;
while (node && !node->mode) {
node = node->parent_node;
}
if (node && node->index < node->count - 1) {
++node->index;
}
if (node) {
saphir.current_node = node;
}
}
U0 saphir_win_select(I64 dir)
{
switch (dir) {
case SC_CURSOR_UP:
saphir_win_select_up;
break;
case SC_CURSOR_DOWN:
saphir_win_select_down;
break;
case SC_CURSOR_LEFT:
saphir_win_select_left;
break;
case SC_CURSOR_RIGHT:
saphir_win_select_right;
break;
default:
break;
}
while (!saphir_reflow)
;
}
U0 saphir_enable()
{
saphir_node_init_root;
saphir.current_node = saphir.root_node;
saphir.current_node->index = 0;
while (!saphir_reflow)
;
}
+3
View File
@@ -3,6 +3,9 @@ I64 Saphir(Bool enable = TRUE)
if (enable == saphir.enabled) { if (enable == saphir.enabled) {
return enable; return enable;
} }
if (enable) {
saphir_enable;
}
fn_patch(&Blink, &saphir_Blink, enable); fn_patch(&Blink, &saphir_Blink, enable);
fn_patch(&DocBorder, &saphir_DocBorder, enable); fn_patch(&DocBorder, &saphir_DocBorder, enable);
// fn_patch(&DocBorderLstDraw, &saphir_DocBorderLstDraw, enable); // fn_patch(&DocBorderLstDraw, &saphir_DocBorderLstDraw, enable);
+1 -1
View File
@@ -4,7 +4,7 @@ class FunctionIndex {
U64 addr; U64 addr;
U64 prologue; U64 prologue;
} fn_index[FN_MAXNUM]; } fn_index[FN_MAXNUM];
MemSet(fn_index, 0, sizeof(FunctionIndex)); MemSet(fn_index, 0, sizeof(FunctionIndex) * FN_MAXNUM);
I64 fn_restore(U32 from) I64 fn_restore(U32 from)
{ {
+1
View File
@@ -25,6 +25,7 @@ CDoc* saphir_DocBorder(U64)
saphir.doc_cursor_state = 0; saphir.doc_cursor_state = 0;
} }
task->win_bottom = MinI64(task->win_bottom, TEXT_ROWS - 3); task->win_bottom = MinI64(task->win_bottom, TEXT_ROWS - 3);
task->win_right = MinI64(task->win_right, TEXT_COLS - 2);
if (task != sys_focus_task) { if (task != sys_focus_task) {
return NULL; return NULL;
} }