From c97456cfb20f8369cd552ca88596fbc3802e74d5 Mon Sep 17 00:00:00 2001 From: GutPuncher Date: Wed, 22 Mar 2023 22:38:17 -0400 Subject: [PATCH] Make raw-mouse mode task-based instead of global. --- src/Demo/Games/CastleFrankenstein.ZC | 45 +++++++---- src/Doc/ChangeLog.DD | 12 ++- src/Kernel/KGlobals.ZC | 2 +- src/Kernel/KMain.ZC | 2 + src/Kernel/KernelA.HH | 7 +- src/Kernel/KernelC.HH | 3 +- src/Kernel/SerialDev/Mouse.ZC | 113 +++++++++++++++++++++++++-- 7 files changed, 156 insertions(+), 28 deletions(-) diff --git a/src/Demo/Games/CastleFrankenstein.ZC b/src/Demo/Games/CastleFrankenstein.ZC index 306a912c..0ce47472 100755 --- a/src/Demo/Games/CastleFrankenstein.ZC +++ b/src/Demo/Games/CastleFrankenstein.ZC @@ -586,24 +586,31 @@ U0 MouseHandler() { Bool button; I64 x; - while (TRUE) + + while (MouseRawQueueFind(game_task)) { button = mouse_hard.raw_bttns[0]; x = mouse_hard.raw_data.x; - if (button || x!=0) + + if (button || x != 0) MouseRawReset; // Mark mouse data as consumed if (button) - MessagePostWait(game_task,MESSAGE_KEY_DOWN_UP,CH_SPACE,0); - if (x != 0) { - man_é += (x/mouse_scale)/MICRO_STEPS; - } + MessagePostWait(game_task, MESSAGE_KEY_DOWN_UP, CH_SPACE, 0); + if (x != 0) + man_é += (x / mouse_scale) / MICRO_STEPS; + Sleep(10); - } + } + mouse_task = NULL; } U0 CastleFrankenstein() { I64 sc; + Bool is_raw = TRUE; + + MouseRaw(is_raw); + mouse_task = Spawn(&MouseHandler, NULL, "MouseHandler"); MenuPush( "File {" @@ -617,6 +624,9 @@ U0 CastleFrankenstein() " Left(,,SC_CURSOR_LEFT);" " Right(,,SC_CURSOR_RIGHT);" " Fire(,CH_SPACE);" + " MouseMode(,'m');" + " MouseScaleUp(,'+');" + " MouseScaleDown(,'-');" "}" ); @@ -642,18 +652,22 @@ U0 CastleFrankenstein() break; case 'm': - if (!mouse_task) { - MouseRaw(TRUE); - mouse_task=Spawn(&MouseHandler,NULL); - } - else { + if (is_raw) + { + is_raw = FALSE; + MouseRaw(is_raw); Kill(mouse_task); - mouse_task=NULL; - MouseRaw(FALSE); + } + else + { + is_raw = TRUE; + MouseRaw(is_raw); + mouse_task = Spawn(&MouseHandler, NULL, "MouseHandler"); } break; case '+': + case '=': mouse_scale *= 0.9; break; @@ -706,10 +720,7 @@ fs_done: RegWrite("ZealOS/CastleFrankenstein", "F64 best_score=%5.4f;\n", best_score); } -MouseRaw(TRUE); -mouse_task=Spawn(&MouseHandler,NULL); CastleFrankenstein; -if (mouse_task) Kill(mouse_task); MouseRaw(FALSE); &   diff --git a/src/Doc/ChangeLog.DD b/src/Doc/ChangeLog.DD index dbcef2bd..f8afb550 100755 --- a/src/Doc/ChangeLog.DD +++ b/src/Doc/ChangeLog.DD @@ -1,9 +1,19 @@ $WW,1$$FG,5$$TX+CX,"ChangeLog"$$FG$ +$IV,1$----03/22/23 22:27:05----$IV,0$ +* Raised version number to 2.03. +* Created $LK+PU,"CMouseRawQueue",A="MN:CMouseRawQueue"$ to track tasks in raw-mouse mode, placed in $LK+PU,"CMouseHardStateGlobals mouse_hard.raw_queue",A="FF:::/Kernel/KernelA.HH,*raw_queue"$. +* Created $LK+PU,"MouseRawQueueFind",A="MN:MouseRawQueueFind"$ to check whether a given task is in raw-mouse mode, externed in $LK+PU,"KernelC.HH",A="FF:::/Kernel/KernelC.HH,MouseRawQueueFind("$. +* Created $LK+PU,"MouseRawWatcher",A="MN:MouseRawWatcher"$ and $LK+PU,"MouseRawWatcherInner",A="MN:MouseRawWatcherInner"$ to watch for killed tasks and remove them from raw_queue, spawned in $LK+PU,"KMain",A="FF:::/Kernel/KMain.ZC,&MouseRawWatcher:2"$. +* Added task parameter to $LK+PU,"MouseRaw",A="MN:MouseRaw"$, changed behaviour from a global toggle to a task-based queue of $LK+PU,"CMouseRawQueue",A="MN:CMouseRawQueue"$ entries. +* Changed $LK+PU,"MouseHardHandler",A="MN:MouseHardHandler"$ to use $LK+PU,"MouseRawQueueFind",A="MN:MouseRawQueueFind"$ with $LK+PU,"sys_focus_task",A="MN:sys_focus_task"$ to determine if currently in raw-mode or not, added $LK+PU,"clearing mouse.show, mouse.lb, mouse.rb",A="FF:::/Kernel/SerialDev/Mouse.ZC,mouse.lb = FALSE"$ to fix bug where clicking to refocus a mouse-raw application would register a repeated click on unfocus. +* Added raw_queue init to $LK+PU,"KbdMouseInit",A="FF:::/Kernel/SerialDev/Mouse.ZC,QueueInit(mouse_hard.raw_queue);"$. +* Changed $LK+PU,"CastleFrankenstein MouseHandler",A="FF:::/Demo/Games/CastleFrankenstein.ZC,MouseHandler"$ while loop condition to use $LK+PU,"MouseRawQueueFind",A="MN:MouseRawQueueFind"$ with game_task as parameter, added raw-mouse keybind descriptions to game's $LK+PU,"MenuPush",A="FF:::/Demo/Games/CastleFrankenstein.ZC,MouseMode"$. + $IV,1$----03/17/23 17:44:24----$IV,0$ * Rewrote $LK+PU,"MiniGrLib",A="FI:::/Demo/Lectures/MiniGrLib.ZC"$, replaced old VGA-specific code to work with 32-bit framebuffer. $IV,1$----03/14/23 03:23:46----$IV,0$ -* Created %o Bool $LK+PU,"StrPrint",A="FF:::/Kernel/StrPrint.ZC,'o':"$ format code, updated $LK+PU,"Print.DD",A="FI:::/Doc/Print.DD"$ with new %o code and previously undocumented format codes. +* Created %o Bool $LK+PU,"StrPrint",A="FF:::/Kernel/StrPrint.ZC,'o'"$ format code, updated $LK+PU,"Print.DD",A="FI:::/Doc/Print.DD"$ with new %o code and previously undocumented format codes. $IV,1$----03/13/23 18:06:09----$IV,0$ * Raised version number to 2.02. diff --git a/src/Kernel/KGlobals.ZC b/src/Kernel/KGlobals.ZC index d240802b..34cacbe8 100755 --- a/src/Kernel/KGlobals.ZC +++ b/src/Kernel/KGlobals.ZC @@ -13,7 +13,7 @@ CTask *sys_winmgr_task, U8 *rev_bits_table; //Table with U8 bits reversed CDate local_time_offset; F64 *pow10_I64, - sys_os_version = 2.02; + sys_os_version = 2.03; CAutoCompleteDictGlobals acd; CAutoCompleteGlobals ac; diff --git a/src/Kernel/KMain.ZC b/src/Kernel/KMain.ZC index 771ae09c..b1757765 100755 --- a/src/Kernel/KMain.ZC +++ b/src/Kernel/KMain.ZC @@ -211,6 +211,8 @@ U0 KMain() KbdInit; "Spawn(&MouseHardDriverInstall);\n\n"; Spawn(&MouseHardDriverInstall); + "Spawn(&MouseRawWatcher,, \"MouseRawWatcher\");\n"; + Spawn(&MouseRawWatcher,, "MouseRawWatcher"); "Load(\"Compiler\");\n"; Cd("/Compiler"); diff --git a/src/Kernel/KernelA.HH b/src/Kernel/KernelA.HH index 15bc09fb..3bf2f6aa 100755 --- a/src/Kernel/KernelA.HH +++ b/src/Kernel/KernelA.HH @@ -3715,6 +3715,11 @@ public class CKbdStateGlobals }; #help_index "Mouse" +class CMouseRawQueue:CQueue +{ + CTask *task; +}; + public class CMouseHardStateGlobals { CD3I64 pos, //Position in pixels @@ -3726,9 +3731,9 @@ public class CMouseHardStateGlobals install_attempts, //Private pkt_size; //Private CFifoU8 *fifo, *fifo2; //Private + CQueue *raw_queue; Bool bttns[5], raw_bttns[5], - raw_mode, has_wheel, has_ext_bttns, enabled, diff --git a/src/Kernel/KernelC.HH b/src/Kernel/KernelC.HH index 72a04628..7b0ddfb1 100755 --- a/src/Kernel/KernelC.HH +++ b/src/Kernel/KernelC.HH @@ -503,8 +503,9 @@ extern I64 KbdMessagesQueue(); public extern U0 KbdTypeMatic(U8 delay); extern Bool MouseHardDriverInstall(); public extern Bool MouseHardEnable(Bool val=TRUE); -public extern Bool MouseRaw(Bool val); +public extern Bool MouseRaw(Bool val, CTask *task=NULL); public extern U0 MouseRawReset(Bool val=TRUE); +extern CMouseRawQueue *MouseRawQueueFind(CTask *task); public extern I64 PressAKey(); public extern I64 CharScan(); public extern Bool KeyScan(I64 *_ch=NULL, I64 *_scan_code=NULL, Bool echo=FALSE); diff --git a/src/Kernel/SerialDev/Mouse.ZC b/src/Kernel/SerialDev/Mouse.ZC index be578c4c..244af422 100755 --- a/src/Kernel/SerialDev/Mouse.ZC +++ b/src/Kernel/SerialDev/Mouse.ZC @@ -56,12 +56,99 @@ public U0 MouseRawReset() mouse_hard.raw_bttns[4] = FALSE; } -public Bool MouseRaw(Bool val) -{ // Places mouse in "raw" mode, button presses will not go to windows manager when true - Bool old_val = mouse_hard.raw_mode; +CMouseRawQueue *MouseRawQueueFind(CTask *task) +{ + CMouseRawQueue *entry = mouse_hard.raw_queue->next; - mouse_hard.raw_mode = val; - mouse.show = !val; + while (entry != mouse_hard.raw_queue) + { + if (entry->task == task) + return entry; + entry = entry->next; + } + + return NULL; +} + +U0 MouseRawWatcherInner(CTask *task, CMouseRawQueue *entry, Bool *_found) +{ + CTask *task2; + + if (task == entry->task) + *_found = TRUE; + + task2 = task->next_child_task; + while (!*_found && task2 != (&task->next_child_task)(U8 *) - offset(CTask.next_sibling_task)) + { + MouseRawWatcherInner(task2, entry, _found); + task2 = task2->next_sibling_task; + } +} + +U0 MouseRawWatcher() +{ + CMouseRawQueue *entry, *next_entry; + I64 i; + CCPU *c; + Bool found; + + while (TRUE) + { + entry = mouse_hard.raw_queue->next; + while (entry != mouse_hard.raw_queue) + { + found = FALSE; + next_entry = entry->next; + PUSHFD + CLI + for (i = 0; i < mp_count; i++) + { + c = &cpu_structs[i]; + MouseRawWatcherInner(c->executive_task, entry, &found); + } + POPFD + + if (!found) + { + QueueRemove(entry); + Free(entry); + } + + entry = next_entry; + } + Sleep(1000); + } +} + +public Bool MouseRaw(Bool val, CTask *task=NULL) +{ // Places mouse in "raw" mode, button presses will not go to windows manager when true + CMouseRawQueue *entry; + Bool old_val; + + if (!task) + task = Fs; + + if (val) + { + old_val = TRUE; + if (!MouseRawQueueFind(task)) + { + entry = CAlloc(sizeof(CMouseRawQueue)); + entry->task = task; + QueueInsertRev(entry, mouse_hard.raw_queue); + old_val = FALSE; + } + } + else + { + old_val = FALSE; + if (entry = MouseRawQueueFind(task)) + { + QueueRemove(entry); + Free(entry); + old_val = TRUE; + } + } return old_val; } @@ -279,8 +366,14 @@ U0 MouseHardHandler() { I64 i, dx, dy, dz; U8 mouse_buf[4]; + Bool is_raw_mode; - if (!mouse_hard.raw_mode) + if (mouse_hard.raw_queue->next == mouse_hard.raw_queue) + is_raw_mode = FALSE; // queue check branch skips func call stack push/pop, small speedup + else + is_raw_mode = MouseRawQueueFind(sys_focus_task); + + if (!is_raw_mode) MouseHardSetPre; for (i = 0; i < 4; i++) @@ -302,7 +395,7 @@ U0 MouseHardHandler() else dz = mouse_buf[3] & 7; - if (mouse_hard.raw_mode) + if (is_raw_mode) { // buttons / position data need to by consumed by app // buttons stay down, positions keep accumulating until @@ -315,6 +408,9 @@ U0 MouseHardHandler() mouse_hard.raw_data.x += dx; mouse_hard.raw_data.y += dy; mouse_hard.raw_data.z += dz; + mouse.show = FALSE; + mouse.lb = FALSE; + mouse.rb = FALSE; } else { @@ -326,6 +422,7 @@ U0 MouseHardHandler() mouse_hard.prescale.x += dx; mouse_hard.prescale.y += dy; mouse_hard.prescale.z += dz; + mouse.show = TRUE; MouseHardSetPost; } } @@ -447,5 +544,7 @@ U0 KbdMouseInit() mouse_hard.prescale.z = 0 / mouse_hard.scale.z; mouse_hard.pos.x = sys_framebuffer_width >> 1; mouse_hard.pos.y = sys_framebuffer_height >> 1; + mouse_hard.raw_queue = CAlloc(sizeof(CQueue)); // head of CMouseRawQueue queue + QueueInit(mouse_hard.raw_queue); MemCopy(&mouse_hard_last, &mouse_hard, sizeof(CMouseHardStateGlobals)); }