mirror of
https://git.checksum.fail/alec/saphir.git
synced 2026-05-01 18:09:42 +03:00
Refactor everything
We now hijack existing system functions to integrate with `WinMgr`, instead of `Spawn`ing our own `SaphirTask`. Also, you can now use `Saphir(Bool)` to toggle enable/disable the features. There is a global var `saphir` which values are set by `Defaults.HC` for colors and other behaviors; these values can be changed at any time.
This commit is contained in:
30
Saphir/Class.HC
Normal file
30
Saphir/Class.HC
Normal file
@@ -0,0 +1,30 @@
|
||||
class SaphirAttr {
|
||||
I64 fg;
|
||||
I64 bg;
|
||||
};
|
||||
|
||||
class SaphirBorder : SaphirAttr {
|
||||
I64 focus_fg;
|
||||
I64 focus_bg;
|
||||
Bool list;
|
||||
};
|
||||
|
||||
class SaphirCursor : SaphirAttr {
|
||||
// Bool blink;
|
||||
U64 stub;
|
||||
};
|
||||
|
||||
class SaphirKeyDev {
|
||||
U64 sys_cbs;
|
||||
U64 null_cbs;
|
||||
}
|
||||
|
||||
class SaphirGlbls {
|
||||
Bool enabled;
|
||||
Bool blink;
|
||||
SaphirBorder border;
|
||||
SaphirCursor cursor;
|
||||
SaphirKeyDev kd;
|
||||
I64 doc_cursor_state;
|
||||
} saphir;
|
||||
MemSet(&saphir, 0, sizeof(SaphirGlbls));
|
||||
93
Saphir/Cmd.HC
Normal file
93
Saphir/Cmd.HC
Normal file
@@ -0,0 +1,93 @@
|
||||
Bool saphir_task_is_windowed(CTask* task)
|
||||
{
|
||||
if (!task || task == ac.task) {
|
||||
return FALSE;
|
||||
}
|
||||
if ((task->display_flags & 1 << DISPLAYf_SHOW) && ((task->display_flags & 1 << DISPLAYf_NOT_RAW)))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
U0 saphir_split_row()
|
||||
{
|
||||
CTask* task1 = sys_focus_task;
|
||||
CTask* task2 = User;
|
||||
MemCpy(&task2->win_left, &task1->win_left, 32);
|
||||
task1->win_bottom = (task1->win_top + task1->win_bottom) / 2;
|
||||
task2->win_top = task1->win_bottom + 2;
|
||||
WinZBufUpdate;
|
||||
}
|
||||
|
||||
U0 saphir_split_col()
|
||||
{
|
||||
CTask* task1 = sys_focus_task;
|
||||
CTask* task2 = User;
|
||||
MemCpy(&task2->win_left, &task1->win_left, 32);
|
||||
task1->win_right = (task1->win_left + task1->win_right) / 2;
|
||||
task2->win_left = task1->win_right + 2;
|
||||
WinZBufUpdate;
|
||||
}
|
||||
|
||||
U0 saphir_win_select(I64 dir)
|
||||
{
|
||||
CTask* task = sys_focus_task;
|
||||
CTask* task1;
|
||||
I64 wt = task->win_top;
|
||||
I64 wl = task->win_left;
|
||||
I64 i;
|
||||
I64 j;
|
||||
|
||||
switch (dir) {
|
||||
case SC_CURSOR_UP:
|
||||
i = wt - 1;
|
||||
j = -1;
|
||||
break;
|
||||
case SC_CURSOR_DOWN:
|
||||
i = wt + 1;
|
||||
j = 1;
|
||||
break;
|
||||
case SC_CURSOR_LEFT:
|
||||
i = wl - 1;
|
||||
j = -1;
|
||||
break;
|
||||
case SC_CURSOR_RIGHT:
|
||||
i = wl + 1;
|
||||
j = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (dir) {
|
||||
case SC_CURSOR_UP:
|
||||
case SC_CURSOR_DOWN:
|
||||
for (i = i; i > 0 && i < TEXT_ROWS + 1; i += j) {
|
||||
task1 = adam_task->next_task;
|
||||
while (task1 != adam_task) {
|
||||
if (saphir_task_is_windowed(task1)) {
|
||||
if (task1->win_top == i && task1->win_left == wl) {
|
||||
WinFocus(task1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
task1 = task1->next_task;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SC_CURSOR_LEFT:
|
||||
case SC_CURSOR_RIGHT:
|
||||
for (i = i; i > 0 && i < TEXT_COLS + 1; i += j) {
|
||||
task1 = adam_task->next_task;
|
||||
while (task1 != adam_task) {
|
||||
if (saphir_task_is_windowed(task1)) {
|
||||
if (task1->win_left == i) {
|
||||
WinFocus(task1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
task1 = task1->next_task;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
71
Saphir/KeyDev.HC
Normal file
71
Saphir/KeyDev.HC
Normal file
@@ -0,0 +1,71 @@
|
||||
saphir.kd.sys_cbs = keydev.fp_ctrl_alt_cbs;
|
||||
saphir.kd.null_cbs = CAlloc(0xd0);
|
||||
|
||||
I64 saphir_get_char()
|
||||
{
|
||||
I64 sc = NULL;
|
||||
I64 ch = NULL;
|
||||
do {
|
||||
ch = GetKey(&sc, 0, 0);
|
||||
if (!ch) {
|
||||
switch (sc & 0xff) {
|
||||
case SC_CURSOR_UP:
|
||||
case SC_CURSOR_DOWN:
|
||||
case SC_CURSOR_LEFT:
|
||||
case SC_CURSOR_RIGHT:
|
||||
return ((sc & 0xff) << 8);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (!ch);
|
||||
return ch;
|
||||
}
|
||||
|
||||
U0 saphir_handle_prefix_cmd()
|
||||
{
|
||||
I64 ch = saphir_get_char;
|
||||
switch (ch >> 8) {
|
||||
case SC_CURSOR_UP:
|
||||
case SC_CURSOR_DOWN:
|
||||
case SC_CURSOR_LEFT:
|
||||
case SC_CURSOR_RIGHT:
|
||||
saphir_win_select(ch >> 8);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (ch & 0xff) {
|
||||
case '%':
|
||||
saphir_split_col;
|
||||
return;
|
||||
case '"':
|
||||
saphir_split_row;
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Bool saphir_MyPutKey(I64 ch, I64 sc)
|
||||
{
|
||||
switch (ch) {
|
||||
case CH_CTRLB:
|
||||
saphir_handle_prefix_cmd;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
U0 saphir_keydev(Bool enable)
|
||||
{
|
||||
fn_patch(&MyPutKey, &saphir_MyPutKey, enable);
|
||||
switch (enable) {
|
||||
case 0:
|
||||
keydev.fp_ctrl_alt_cbs = saphir.kd.sys_cbs;
|
||||
return;
|
||||
default:
|
||||
keydev.fp_ctrl_alt_cbs = saphir.kd.null_cbs;
|
||||
return;
|
||||
}
|
||||
}
|
||||
16
Saphir/Main.HC
Normal file
16
Saphir/Main.HC
Normal file
@@ -0,0 +1,16 @@
|
||||
I64 Saphir(Bool enable = TRUE)
|
||||
{
|
||||
if (enable == saphir.enabled) {
|
||||
return enable;
|
||||
}
|
||||
fn_patch(&Blink, &saphir_Blink, enable);
|
||||
fn_patch(&DocBorder, &saphir_DocBorder, enable);
|
||||
// fn_patch(&DocBorderLstDraw, &saphir_DocBorderLstDraw, enable);
|
||||
fn_patch(&DrvTextAttrGet, &saphir_DrvTextAttrGet, enable);
|
||||
saphir_cursor(enable);
|
||||
saphir_keydev(enable);
|
||||
if (!enable) {
|
||||
DCFill;
|
||||
}
|
||||
saphir.enabled = enable;
|
||||
}
|
||||
53
Saphir/Misc.HC
Normal file
53
Saphir/Misc.HC
Normal file
@@ -0,0 +1,53 @@
|
||||
#define FN_MAXNUM 32
|
||||
|
||||
class FunctionIndex {
|
||||
U64 addr;
|
||||
U64 prologue;
|
||||
} fn_index[FN_MAXNUM];
|
||||
MemSet(fn_index, 0, sizeof(FunctionIndex));
|
||||
|
||||
I64 fn_restore(U32 from)
|
||||
{
|
||||
if (!from) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
I64 i;
|
||||
for (i = 0; i < FN_MAXNUM; i++) {
|
||||
if (fn_index[i].addr == from) {
|
||||
MemCpy(fn_index[i].addr, &fn_index[i].prologue, 8);
|
||||
fn_index[i].addr = fn_index[i].prologue = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
I64 fn_patch(U32 from, U32 to, Bool patch = TRUE)
|
||||
{
|
||||
if (!from || !to) {
|
||||
return -1;
|
||||
}
|
||||
if (!patch) {
|
||||
return fn_restore(from);
|
||||
}
|
||||
|
||||
I64 i = 0;
|
||||
while (i < FN_MAXNUM && fn_index[i].addr) {
|
||||
if (fn_index[i].addr == from) {
|
||||
// Function already patched
|
||||
return -1;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
if (i >= FN_MAXNUM) {
|
||||
// Maximum entires reached
|
||||
return -1;
|
||||
}
|
||||
|
||||
fn_index[i].addr = from;
|
||||
MemCpy(&fn_index[i].prologue, from, 8);
|
||||
*(from(U8*)) = 0xE9;
|
||||
*((from + 1)(I32*)) = to - from - 5;
|
||||
return 0;
|
||||
}
|
||||
91
Saphir/WinMgr.HC
Normal file
91
Saphir/WinMgr.HC
Normal file
@@ -0,0 +1,91 @@
|
||||
#define SAPHIR_CURSOR_PATCH_ADDR &DocRecalc + 0x2c62
|
||||
|
||||
U0 saphir_update_cursor()
|
||||
{
|
||||
U16 res = 0xb4;
|
||||
res |= ((saphir.cursor.fg & 0xf) << 4 | (saphir.cursor.bg & 0xf)) << 8;
|
||||
MemCpy(SAPHIR_CURSOR_PATCH_ADDR, &res, 2);
|
||||
MemSet(SAPHIR_CURSOR_PATCH_ADDR + 0x02, 0x90, 3);
|
||||
}
|
||||
|
||||
CDoc* saphir_DocBorder(U64)
|
||||
{
|
||||
U64 addr = Caller;
|
||||
if (addr >= &DocEd && addr <= (&DocEd + sizeof(DocEd))) {
|
||||
asm {
|
||||
MOV RAX, &DocBorder
|
||||
ADD RAX, 6
|
||||
JMP RAX
|
||||
}
|
||||
}
|
||||
|
||||
CTask* task = sys_task_being_scrn_updated;
|
||||
if (saphir.doc_cursor_state) {
|
||||
task->display_doc->flags = saphir.doc_cursor_state;
|
||||
saphir.doc_cursor_state = 0;
|
||||
}
|
||||
task->win_bottom = MinI64(task->win_bottom, TEXT_ROWS - 3);
|
||||
if (task != sys_focus_task) {
|
||||
return NULL;
|
||||
}
|
||||
if (ac.task) {
|
||||
Kill(ac.task);
|
||||
ac.task = NULL;
|
||||
}
|
||||
saphir_update_cursor;
|
||||
gr.dc->color = BLACK;
|
||||
GrRect(gr.dc, 0, GR_HEIGHT - 8, GR_WIDTH, 8);
|
||||
gr.dc->color = LTGRAY;
|
||||
GrPrint(gr.dc, 0, GR_HEIGHT - 8, "[0x%08x] %s", task,
|
||||
task->task_title);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
U8 saphir_DrvTextAttrGet(U64)
|
||||
{
|
||||
U64 addr = Caller;
|
||||
if (addr >= &DrvRep && addr <= (&DrvRep + sizeof(DrvRep))) {
|
||||
asm {
|
||||
MOV RAX, &DrvTextAttrGet
|
||||
ADD RAX, 6
|
||||
POP R11
|
||||
JMP RAX
|
||||
}
|
||||
}
|
||||
if (addr >= &TaskInit && addr <= (&TaskInit + sizeof(TaskInit))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sys_focus_task == sys_task_being_scrn_updated) {
|
||||
return (saphir.border.focus_bg & 0xf) << 4 | (saphir.border.focus_fg & 0xf);
|
||||
}
|
||||
if (!saphir.doc_cursor_state) {
|
||||
saphir.doc_cursor_state = sys_task_being_scrn_updated->display_doc->flags;
|
||||
DocCursor(, sys_task_being_scrn_updated->display_doc);
|
||||
}
|
||||
return (saphir.border.bg & 0xf) << 4 | (saphir.border.fg & 0xf);
|
||||
}
|
||||
|
||||
U0 saphir_cursor(Bool enable)
|
||||
{
|
||||
switch (enable) {
|
||||
case 0:
|
||||
MemCpy(SAPHIR_CURSOR_PATCH_ADDR, &saphir.cursor.stub, 8);
|
||||
return;
|
||||
default:
|
||||
MemCpy(&saphir.cursor.stub, SAPHIR_CURSOR_PATCH_ADDR, 8);
|
||||
saphir_update_cursor;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Bool saphir_Blink(F64 Hz = 2.5)
|
||||
{
|
||||
if (!saphir.blink) {
|
||||
return 1;
|
||||
}
|
||||
if (!Hz)
|
||||
return 0;
|
||||
return ToI64(cnts.jiffies * 2 * Hz / JIFFY_FREQ) & 1;
|
||||
}
|
||||
Reference in New Issue
Block a user