Add files to repository
This commit is contained in:
parent
8c4cc14d42
commit
dc9092e312
9 changed files with 369 additions and 1 deletions
48
KeyDev.HC
Normal file
48
KeyDev.HC
Normal file
|
@ -0,0 +1,48 @@
|
|||
U0 @saphir_key_nop() {}
|
||||
|
||||
Bool @saphir_put_key(I64 ch, I64 sc) {
|
||||
if (sc & SCF_ALT && !(sc & SCF_CTRL)) {
|
||||
switch (ch) {
|
||||
case 0:
|
||||
switch (sc.u8[0]) {
|
||||
case SC_CURSOR_UP:
|
||||
@saphir_win_select(SAPHIR_WIN_UP);
|
||||
return TRUE;
|
||||
case SC_CURSOR_DOWN:
|
||||
@saphir_win_select(SAPHIR_WIN_DOWN);
|
||||
return TRUE;
|
||||
case SC_CURSOR_LEFT:
|
||||
@saphir_win_select(SAPHIR_WIN_LEFT);
|
||||
return TRUE;
|
||||
case SC_CURSOR_RIGHT:
|
||||
@saphir_win_select(SAPHIR_WIN_RIGHT);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
@saphir_split_horz;
|
||||
return TRUE;
|
||||
break;
|
||||
case 'v':
|
||||
@saphir_split_vert;
|
||||
return TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
U64 @tos_fp_cbs_enabled =
|
||||
keydev.fp_ctrl_alt_cbs; // Save pointer to TempleOS system-wide (CTRL-ALT)
|
||||
// callbacks
|
||||
|
||||
U64 @tos_fp_cbs_disabled = CAlloc(0xD0);
|
||||
keydev.fp_ctrl_alt_cbs =
|
||||
@tos_fp_cbs_disabled; // Disable TempleOS system-wide (CTRL-ALT) callbacks
|
||||
|
||||
// FIXME: Ideally, we would add a new KeyDev here, but since we need to override
|
||||
// the HomeKeyPlugIns, we will need to patch MyKeyDev instead.
|
||||
|
||||
// KeyDevAdd(&@saphir_put_key, &MyPutS, 0x10000000,
|
||||
// TRUE); // Enable Saphir keyboard shortcuts
|
||||
@function_patch(&MyPutKey, &@saphir_put_key);
|
11
Load.HC
Normal file
11
Load.HC
Normal file
|
@ -0,0 +1,11 @@
|
|||
/* clang-format off */
|
||||
|
||||
#include "Patch";
|
||||
#include "Win";
|
||||
#include "KeyDev";
|
||||
#include "Status";
|
||||
#include "Saphir";
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
WinTileHorz;
|
88
Patch.HC
Normal file
88
Patch.HC
Normal file
|
@ -0,0 +1,88 @@
|
|||
U0 @function_patch(U32 from, U32 to) {
|
||||
*(from(U8 *)) = 0xE9;
|
||||
*((from + 1)(I32 *)) = to - from - 5;
|
||||
}
|
||||
|
||||
U0 @gr_update_text_bg2() {
|
||||
I64 reg RSI *dst = gr.dc2->body, reg R13 c, row, col, num_rows = TEXT_ROWS,
|
||||
num_cols = TEXT_COLS, i, j, cur_ch,
|
||||
reg R12 w1 = gr.dc2->width_internal, w2 = -7 * w1 + 8,
|
||||
w3 = 7 * w1, w4 = 0;
|
||||
U32 *src = gr.text_base;
|
||||
Bool blink_flag = Blink;
|
||||
U8 *dst2 = dst;
|
||||
|
||||
if (gr.pan_text_x || gr.hide_col) {
|
||||
gr.pan_text_x = ClampI64(gr.pan_text_x, -7, 7);
|
||||
j = AbsI64(gr.pan_text_x) / FONT_WIDTH + 1;
|
||||
num_cols -= j;
|
||||
if (gr.pan_text_x < 0) {
|
||||
src += j;
|
||||
i = FONT_WIDTH * j + gr.pan_text_x;
|
||||
} else
|
||||
i = gr.pan_text_x;
|
||||
dst2 = dst(U8 *) + i;
|
||||
w4 = j;
|
||||
w3 += j * FONT_WIDTH;
|
||||
|
||||
j *= FONT_WIDTH;
|
||||
dst(U8 *) = gr.dc2->body;
|
||||
for (row = num_rows * FONT_HEIGHT; row--;) {
|
||||
for (col = i; col--;)
|
||||
*dst(U8 *)++ = 0;
|
||||
dst(U8 *) += w1 - i - j;
|
||||
for (col = j; col--;)
|
||||
*dst(U8 *)++ = 0;
|
||||
}
|
||||
}
|
||||
dst = dst2;
|
||||
|
||||
if (gr.pan_text_y || gr.hide_row) {
|
||||
gr.pan_text_y = ClampI64(gr.pan_text_y, -7, 7);
|
||||
j = AbsI64(gr.pan_text_y) / FONT_HEIGHT + 1;
|
||||
num_rows -= j;
|
||||
if (gr.pan_text_y < 0) {
|
||||
src += w1 / FONT_WIDTH * j;
|
||||
i = w1 * (FONT_HEIGHT * j + gr.pan_text_y);
|
||||
} else
|
||||
i = w1 * gr.pan_text_y;
|
||||
dst2 = dst(U8 *) + i;
|
||||
|
||||
j *= w1 * FONT_HEIGHT;
|
||||
dst(U8 *) = gr.dc2->body;
|
||||
for (row = i; row--;)
|
||||
*dst(U8 *)++ = 0;
|
||||
dst(U8 *) =
|
||||
gr.dc2->body + TEXT_ROWS * TEXT_COLS * FONT_HEIGHT * FONT_WIDTH - j;
|
||||
for (row = j; row--;)
|
||||
*dst(U8 *)++ = 0;
|
||||
}
|
||||
dst = dst2;
|
||||
|
||||
for (row = num_rows; row--;) {
|
||||
for (col = num_cols; col--;) {
|
||||
cur_ch = *src++;
|
||||
if (cur_ch & (ATTRF_SEL | ATTRF_INVERT | ATTRF_BLINK)) {
|
||||
if (cur_ch & ATTRF_SEL)
|
||||
cur_ch.u8[1] = cur_ch.u8[1] ^ 0xFF;
|
||||
if (cur_ch & ATTRF_INVERT)
|
||||
cur_ch.u8[1] = cur_ch.u8[1] << 4 + cur_ch.u8[1] >> 4;
|
||||
if (cur_ch & ATTRF_BLINK && blink_flag)
|
||||
cur_ch.u8[1] = 0x30;
|
||||
else
|
||||
cur_ch.u8[1] = 0xFF;
|
||||
}
|
||||
c = gr.to_8_colors[cur_ch.u8[1] >> 4];
|
||||
MOV U64[RSI], R13 ADD RSI, R12 MOV U64[RSI], R13 ADD RSI,
|
||||
R12 MOV U64[RSI], R13 ADD RSI, R12 MOV U64[RSI], R13 ADD RSI,
|
||||
R12 MOV U64[RSI], R13 ADD RSI, R12 MOV U64[RSI], R13 ADD RSI,
|
||||
R12 MOV U64[RSI], R13 ADD RSI, R12 MOV U64[RSI], R13 dst(U8 *) += w2;
|
||||
}
|
||||
src += w4;
|
||||
dst(U8 *) += w3;
|
||||
}
|
||||
}
|
||||
|
||||
@function_patch(&GrUpdateTextBG,
|
||||
&@gr_update_text_bg2); // Patch GrUpdateTextBG to make cursor
|
||||
// blinking less irritating
|
19
README.md
19
README.md
|
@ -1,3 +1,20 @@
|
|||
# saphir
|
||||
|
||||
Tiling window extensions for TempleOS WinMgr
|
||||
Tiling window extensions for TempleOS WinMgr
|
||||
|
||||

|
||||
|
||||
# Info
|
||||
|
||||
Saphir extends the existing TempleOS WinMgr to provide tiling window functionality, as well as provide some sane defaults to those who prefer a less "blinky" interface. Saphir does not require you to recompile your Kernel; any changes to existing functions are live-patched and not persistent.
|
||||
|
||||
# Usage
|
||||
|
||||
`#include "Run";`
|
||||
|
||||
# Keyboard shortcuts
|
||||
|
||||
`ALT` + arrow keys : navigate windows
|
||||
`ALT` + `h` : split window horizontal
|
||||
`ALT` + `v` : split window vertical
|
||||
|
||||
|
|
3
Run.HC
Normal file
3
Run.HC
Normal file
|
@ -0,0 +1,3 @@
|
|||
Adam("StrPrint(Fs->cur_dir, \"/\");\n");
|
||||
Adam("Fs->cur_dv = Let2Drv('T');\n");
|
||||
AdamFile("Load");
|
19
Saphir.HC
Normal file
19
Saphir.HC
Normal file
|
@ -0,0 +1,19 @@
|
|||
U0 SaphirTask() {
|
||||
I64 count;
|
||||
I64 i;
|
||||
CTask *task;
|
||||
while (1) {
|
||||
count = @windowed_task_count;
|
||||
for (i = 0; i < count; i++) {
|
||||
task = @windowed_task_index(i);
|
||||
@set_border_doc_for_win(task);
|
||||
@set_cursor_for_focused_win(task);
|
||||
@draw_saphir_border_for_win(task);
|
||||
@ensure_win_no_overlap_status_bar(task);
|
||||
}
|
||||
@update_status_bar;
|
||||
Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
Spawn(&SaphirTask, , "Saphir");
|
7
Status.HC
Normal file
7
Status.HC
Normal file
|
@ -0,0 +1,7 @@
|
|||
U0 @update_status_bar() {
|
||||
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", sys_focus_task,
|
||||
sys_focus_task->task_title);
|
||||
}
|
175
Win.HC
Normal file
175
Win.HC
Normal file
|
@ -0,0 +1,175 @@
|
|||
#define SAPHIR_WIN_UP 0
|
||||
#define SAPHIR_WIN_DOWN 1
|
||||
#define SAPHIR_WIN_LEFT 2
|
||||
#define SAPHIR_WIN_RIGHT 3
|
||||
|
||||
CDoc *SAPHIR_BORDER_DOC = DocNew;
|
||||
|
||||
CTask *@is_task_windowed(CTask *task) {
|
||||
if ((task->display_flags & 1 << DISPLAYf_SHOW) &&
|
||||
((task->display_flags & 1 << DISPLAYf_NOT_RAW)))
|
||||
return task;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
I64 @windowed_task_count() {
|
||||
CTask *task;
|
||||
I64 count = 0;
|
||||
task = adam_task->next_task;
|
||||
while (task != adam_task) {
|
||||
if (@is_task_windowed(task))
|
||||
count++;
|
||||
task = task->next_task;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
CTask *@windowed_task_index(I64 index) {
|
||||
CTask *task;
|
||||
I64 count = 0;
|
||||
task = adam_task->next_task;
|
||||
while (task != adam_task) {
|
||||
if (@is_task_windowed(task)) {
|
||||
if (count == index)
|
||||
return task;
|
||||
count++;
|
||||
}
|
||||
task = task->next_task;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
U0 @set_border_doc_for_win(CTask *task) {
|
||||
task->border_doc = SAPHIR_BORDER_DOC;
|
||||
}
|
||||
|
||||
U0 @draw_saphir_border_for_win(CTask *task) {
|
||||
I64 color = LTGRAY;
|
||||
if (task == sys_focus_task)
|
||||
color = LTRED;
|
||||
I64 x;
|
||||
I64 y;
|
||||
I64 wl = task->win_left - 1;
|
||||
I64 wr = task->win_right + 1;
|
||||
I64 wt = task->win_top - 1;
|
||||
I64 wb = task->win_bottom + 1;
|
||||
for (x = wl; x < wr + 1; x++) {
|
||||
gr.text_base[(wt * TEXT_COLS) + x].u8[1] = color;
|
||||
gr.text_base[(wb * TEXT_COLS) + x].u8[1] = color;
|
||||
}
|
||||
for (y = wt; y < wb + 1; y++) {
|
||||
gr.text_base[(y * TEXT_COLS) + wl].u8[1] = color;
|
||||
gr.text_base[(y * TEXT_COLS) + wr].u8[1] = color;
|
||||
}
|
||||
}
|
||||
|
||||
U0 @ensure_win_no_overlap_status_bar(CTask *task) {
|
||||
task->win_bottom = MinI64(task->win_bottom, TEXT_ROWS - 3);
|
||||
}
|
||||
|
||||
U0 @set_cursor_for_focused_win(CTask *task) {
|
||||
if (task == sys_focus_task) {
|
||||
task->put_doc->flags &= ~(1 << DOCf_HIDE_CURSOR);
|
||||
} else {
|
||||
task->put_doc->flags |= (1 << DOCf_HIDE_CURSOR);
|
||||
}
|
||||
}
|
||||
|
||||
U0 @saphir_win_select(I64 dir) {
|
||||
CTask *task = sys_focus_task;
|
||||
I64 wt = task->win_top;
|
||||
I64 wl = task->win_left;
|
||||
I64 i;
|
||||
I64 j;
|
||||
|
||||
switch (dir) {
|
||||
case SAPHIR_WIN_UP:
|
||||
i = wt - 1;
|
||||
j = -1;
|
||||
break;
|
||||
case SAPHIR_WIN_DOWN:
|
||||
i = wt + 1;
|
||||
j = 1;
|
||||
break;
|
||||
case SAPHIR_WIN_LEFT:
|
||||
i = wl - 1;
|
||||
j = -1;
|
||||
break;
|
||||
case SAPHIR_WIN_RIGHT:
|
||||
i = wl + 1;
|
||||
j = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
CTask *task1;
|
||||
|
||||
switch (dir) {
|
||||
case SAPHIR_WIN_UP:
|
||||
case SAPHIR_WIN_DOWN:
|
||||
for (i = i; i > 0 && i < TEXT_ROWS + 1; i += j) {
|
||||
task1 = adam_task->next_task;
|
||||
while (task1 != adam_task) {
|
||||
if (@is_task_windowed(task1)) {
|
||||
if (task1->win_top == i && task1->win_left == wl) {
|
||||
WinFocus(task1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
task1 = task1->next_task;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SAPHIR_WIN_LEFT:
|
||||
case SAPHIR_WIN_RIGHT:
|
||||
for (i = i; i > 0 && i < TEXT_COLS + 1; i += j) {
|
||||
task1 = adam_task->next_task;
|
||||
while (task1 != adam_task) {
|
||||
if (@is_task_windowed(task1)) {
|
||||
if (task1->win_left == i) {
|
||||
WinFocus(task1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
task1 = task1->next_task;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
U0 @saphir_split_horz() {
|
||||
CTask *task1 = sys_focus_task;
|
||||
I64 wt = task1->win_top;
|
||||
I64 wl = task1->win_left;
|
||||
I64 wb = task1->win_bottom;
|
||||
I64 wr = task1->win_right;
|
||||
|
||||
task1->win_bottom = wb / 2;
|
||||
|
||||
CTask *task2 = User;
|
||||
task2->win_top = (wb / 2) + 2;
|
||||
task2->win_bottom = wb;
|
||||
task2->win_left = wl;
|
||||
task2->win_right = wr;
|
||||
|
||||
WinZBufUpdate;
|
||||
}
|
||||
|
||||
U0 @saphir_split_vert() {
|
||||
CTask *task1 = sys_focus_task;
|
||||
I64 wt = task1->win_top;
|
||||
I64 wb = task1->win_bottom;
|
||||
I64 wr = task1->win_right;
|
||||
|
||||
task1->win_right = wr / 2;
|
||||
|
||||
CTask *task2 = User;
|
||||
task2->win_top = wt;
|
||||
task2->win_bottom = wb;
|
||||
task2->win_left = (wr / 2) + 2;
|
||||
task2->win_right = wr;
|
||||
|
||||
WinZBufUpdate;
|
||||
}
|
BIN
screenshot.png
Normal file
BIN
screenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
Loading…
Add table
Add a link
Reference in a new issue