Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d3c164e8af | ||
|
|
5e9d0004d7 |
+8
-22
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
# compile_lvgl.sh — Download LVGL v9.2 source and compile into lib/liblvgl.a
|
||||
# Clone & compile in /tmp (fast container-local fs).
|
||||
# Cache liblvgl.a on host mount (/code/lvgl/) to skip rebuild.
|
||||
# Copy source + objects to /lvgl (host mount) for debugging.
|
||||
set -e
|
||||
|
||||
LVGL_VERSION="v9.2.2"
|
||||
@@ -10,7 +10,6 @@ LVGL_DIR="/tmp/lvgl"
|
||||
OBJ_DIR="/tmp/lvgl_obj"
|
||||
CONF_DIR="$(pwd)/lvglh"
|
||||
OUT_DIR="$(pwd)/lib"
|
||||
CACHE_DIR="/code/lvgl"
|
||||
|
||||
CC="gcc"
|
||||
CFLAGS="-m32 -march=i686 -ffreestanding \
|
||||
@@ -27,17 +26,6 @@ echo " "
|
||||
echo "Compiling LVGL..."
|
||||
echo " "
|
||||
|
||||
# If cached liblvgl.a exists on host mount, just copy it and skip everything
|
||||
if [ -f "${CACHE_DIR}/liblvgl.a" ]; then
|
||||
echo "Found cached liblvgl.a in ${CACHE_DIR}, copying to ${OUT_DIR}..."
|
||||
cp "${CACHE_DIR}/liblvgl.a" "${OUT_DIR}/liblvgl.a"
|
||||
echo "(Delete lvgl/liblvgl.a to force a full rebuild.)"
|
||||
echo " "
|
||||
echo "LVGL compilation complete (cached)."
|
||||
echo " "
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Clone LVGL into /tmp (container-local)
|
||||
rm -rf "$LVGL_DIR"
|
||||
echo "Downloading LVGL ${LVGL_VERSION}..."
|
||||
@@ -117,16 +105,14 @@ else
|
||||
echo "No custom LVGL files in lvglh/."
|
||||
fi
|
||||
|
||||
# Cache liblvgl.a and source to host mount for next build
|
||||
echo "Caching LVGL to host mount..."
|
||||
mkdir -p "$CACHE_DIR"
|
||||
rm -rf ${CACHE_DIR}/* ${CACHE_DIR}/.[!.]* ${CACHE_DIR}/..?* 2>/dev/null || true
|
||||
cp "${OUT_DIR}/liblvgl.a" "${CACHE_DIR}/liblvgl.a"
|
||||
cp -a "$LVGL_DIR/src" "${CACHE_DIR}/src"
|
||||
cp -a "$LVGL_DIR"/*.h "${CACHE_DIR}/" 2>/dev/null || true
|
||||
cp -a "$OBJ_DIR" "${CACHE_DIR}/obj"
|
||||
# Copy source + objects to /lvgl host mount for debugging
|
||||
echo "Copying LVGL source and objects to host mount..."
|
||||
mkdir /code/lvgl 2>/dev/null || true
|
||||
rm -rf /code/lvgl/* /code/lvgl/.[!.]* /code/lvgl/..?* 2>/dev/null || true
|
||||
cp -a "$LVGL_DIR/src" /code/lvgl/src
|
||||
cp -a "$OBJ_DIR" /code/lvgl/obj
|
||||
echo "Done."
|
||||
|
||||
echo " "
|
||||
echo "LVGL compilation complete."
|
||||
echo " "
|
||||
echo " "
|
||||
|
||||
+1
-1
@@ -4,4 +4,4 @@ echo "======================="
|
||||
echo " "
|
||||
echo "Compiling FPC Sources..."
|
||||
echo " "
|
||||
fpc -Aelf -gw -g -gl -n -v0ew -O3 -OpPENTIUM3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ -Fusrc/* -Fusrc/include/* -Fusrc/driver/* -Fusrc/driver/net/* -Fusrc/driver/bus/* -Fusrc/driver/bus/usb/* -Fusrc/driver/hid/* src/kernel.pas
|
||||
fpc -Aelf -gw -g -gl -n -v0ew -O3 -OpPENTIUM3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ -Fusrc/* -Fusrc/driver/* -Fusrc/driver/net/* -Fusrc/driver/bus/* -Fusrc/driver/bus/usb/* -Fusrc/driver/hid/* src/kernel.pas
|
||||
+5
-111
@@ -12,121 +12,15 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
{
|
||||
ContextSwitcher - Custom IRQ0 handler for preemptive context switching.
|
||||
|
||||
Replaces the default ISR_32 with a naked assembly stub that saves the
|
||||
interrupted context (PUSHAD + segment regs), calls a Pascal helper to
|
||||
dispatch timer hooks, send EOI, and run the scheduler, then restores
|
||||
the next process context (or idles) via the returned ESP.
|
||||
|
||||
@author(Kieron Morris <[email protected]>)
|
||||
{
|
||||
ContextSwitcher - Switch Process Contexts when preempted.
|
||||
|
||||
@author(Kieron Morris <[email protected]>)
|
||||
}
|
||||
unit contextswitcher;
|
||||
|
||||
{$ASMMODE intel}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
idt, isrmanager, processmanager, proctypes, util, syslog, tracer;
|
||||
|
||||
{ Initialise: overwrite IDT gate 32 with our custom ISR. }
|
||||
procedure init;
|
||||
|
||||
{ No idle ESP variable needed — idle is now a formal process (PID 0)
|
||||
with its SavedESP managed like any other process. }
|
||||
|
||||
implementation
|
||||
|
||||
{ -----------------------------------------------------------------------
|
||||
do_context_switch_work
|
||||
Pascal helper called from the assembly ISR. Receives the current ESP
|
||||
(pointing to the GS..EFLAGS save area), dispatches timer hooks, sends
|
||||
EOI, runs the scheduler and returns the ESP for the next context.
|
||||
Uses register calling convention: saved_esp in EAX, result in EAX.
|
||||
----------------------------------------------------------------------- }
|
||||
function do_context_switch_work(saved_esp : uint32) : uint32;
|
||||
var
|
||||
next : PProcessContext;
|
||||
begin
|
||||
{ 1. Save ESP into the current process }
|
||||
processmanager.CurrentProcess^.SavedESP := saved_esp;
|
||||
|
||||
{ 2. Dispatch all hooks registered on interrupt 32 (timer hooks).
|
||||
This fires TMR_0_ISR.Main which in turn fires BDA tick,
|
||||
graphics refresh, USB hotplug, etc. }
|
||||
isrmanager.dispatchHooks(32);
|
||||
|
||||
{ 3. Send End-Of-Interrupt to the master PIC }
|
||||
outb($20, $20);
|
||||
|
||||
{ 4. Pick the next process to run (always returns non-nil; idle as fallback) }
|
||||
next := processmanager.scheduler_pick_next;
|
||||
processmanager.CurrentProcess := next;
|
||||
|
||||
{ 5. Return the selected process ESP }
|
||||
do_context_switch_work := next^.SavedESP;
|
||||
end;
|
||||
|
||||
{ -----------------------------------------------------------------------
|
||||
context_switch_isr
|
||||
Naked assembly ISR that replaces ISR_32 (IRQ0 / PIT timer).
|
||||
|
||||
Stack on entry (pushed by CPU):
|
||||
[ESP+8] EFLAGS
|
||||
[ESP+4] CS
|
||||
[ESP+0] EIP
|
||||
|
||||
We push general-purpose and segment registers, call the Pascal helper,
|
||||
switch ESP to the returned value, pop registers and IRETD.
|
||||
----------------------------------------------------------------------- }
|
||||
procedure context_switch_isr; assembler; nostackframe;
|
||||
asm
|
||||
{ Save all general-purpose registers (EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI) }
|
||||
pushad
|
||||
|
||||
{ Save segment registers }
|
||||
push ds
|
||||
push es
|
||||
push fs
|
||||
push gs
|
||||
|
||||
{ Load kernel data segments }
|
||||
mov ax, $10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
{ Call Pascal helper: EAX = current ESP (register calling convention).
|
||||
Returns new ESP in EAX. }
|
||||
mov eax, esp
|
||||
call do_context_switch_work
|
||||
mov esp, eax
|
||||
|
||||
{ Restore segment registers }
|
||||
pop gs
|
||||
pop fs
|
||||
pop es
|
||||
pop ds
|
||||
|
||||
{ Restore general-purpose registers }
|
||||
popad
|
||||
|
||||
{ Return from interrupt }
|
||||
iretd
|
||||
end;
|
||||
|
||||
{ -----------------------------------------------------------------------
|
||||
init
|
||||
Override IDT gate 32 with our custom ISR. Must be called AFTER
|
||||
isrmanager.init so that the default gate has been set up first.
|
||||
----------------------------------------------------------------------- }
|
||||
procedure init;
|
||||
begin
|
||||
idt.set_gate(32, uint32(@context_switch_isr), $08, ISR_RING_0);
|
||||
tracer.push_trace('contextswitcher.init');
|
||||
end;
|
||||
implementation;
|
||||
|
||||
end.
|
||||
+5
-2
@@ -22,7 +22,7 @@ unit cpu;
|
||||
interface
|
||||
|
||||
uses
|
||||
util, RTC, stdio;
|
||||
util, RTC;
|
||||
|
||||
type
|
||||
PCapabilities_Old = ^TCapabilities_Old;
|
||||
@@ -113,10 +113,12 @@ var
|
||||
CAP_OLD, CAP_NEW : uint32;
|
||||
|
||||
procedure init();
|
||||
procedure Terminal_Command_CPU(Params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
stdio;
|
||||
|
||||
procedure getCPUIdentifier;
|
||||
var
|
||||
id0, id1, id2 : uint32;
|
||||
@@ -323,6 +325,7 @@ end;
|
||||
|
||||
procedure init();
|
||||
begin
|
||||
stdio.registerCommand('CPU', @Terminal_Command_CPU, 'CPU Info.');
|
||||
CPUID.Capabilities0:= PCapabilities_Old(@CAP_OLD);
|
||||
CPUID.Capabilities1:= PCapabilities_New(@CAP_NEW);
|
||||
getCPUIdentifier;
|
||||
|
||||
@@ -158,9 +158,6 @@ procedure init;
|
||||
{ Unit Tests }
|
||||
procedure UnitTest;
|
||||
|
||||
{ Terminal command }
|
||||
procedure terminal_command_usb(params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
|
||||
implementation
|
||||
|
||||
{ ========================= Globals ========================= }
|
||||
@@ -1103,6 +1100,7 @@ begin
|
||||
CompletionHookCount := 0;
|
||||
for i := 0 to MAX_COMPLETION_HOOKS - 1 do
|
||||
CompletionHooks[i] := nil;
|
||||
stdio.registerCommand('USB', @terminal_command_usb, 'USB subsystem information.');
|
||||
syslog.logln('USB Core', 'INIT END.');
|
||||
pop_trace;
|
||||
end;
|
||||
|
||||
@@ -256,7 +256,6 @@ type
|
||||
OnReceive : TTCPReceiveCallback;
|
||||
OnEvent : TTCPEventCallback;
|
||||
UserData : void;
|
||||
OwnerPID : uint32; { PID of owning process, 0 if none }
|
||||
end;
|
||||
|
||||
TTCB = record
|
||||
|
||||
@@ -25,7 +25,7 @@ uses
|
||||
tracer, lmemorymanager,
|
||||
util, lists,
|
||||
net, nettypes, netutils,
|
||||
eth2, ipv4, stdio;
|
||||
eth2, ipv4;
|
||||
|
||||
type
|
||||
PARPCacheRecord = ^TARPCacheRecord;
|
||||
@@ -41,12 +41,11 @@ procedure sendGratuitous;
|
||||
procedure sendRequest(ip : puint8);
|
||||
procedure send(hType : uint16; pType : uint16; op : uint16; p_context : PPacketContext);
|
||||
function resolveIP(ip : puint8) : puint8;
|
||||
procedure terminal_command_arp(Params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
strings;
|
||||
stdio, strings;
|
||||
|
||||
var
|
||||
Registered : Boolean = false;
|
||||
@@ -310,6 +309,7 @@ begin
|
||||
writeToLogLn(' L3/ARP: register');
|
||||
Cache:= LL_New(sizeof(TARPCacheRecord));
|
||||
eth2.registerTypePromisc($0806, @recv);
|
||||
stdio.registerCommand('ARP', @terminal_command_arp, 'Get ARP Table.');
|
||||
Registered:= true;
|
||||
end;
|
||||
pop_trace;
|
||||
|
||||
@@ -26,18 +26,17 @@ uses
|
||||
util, strings,
|
||||
net, nettypes, netutils,
|
||||
lists,
|
||||
eth2, stdio;
|
||||
eth2;
|
||||
|
||||
procedure send(p_data : void; p_len : uint16; p_context : PPacketContext);
|
||||
procedure registerProtocol(Protocol_ID : uint8; recv_callback : TRecvCallback);
|
||||
function getIPv4Config : PIPv4Configuration;
|
||||
procedure register;
|
||||
procedure terminal_command_ifconfig(params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
arp;
|
||||
arp, stdio;
|
||||
|
||||
var
|
||||
Registered : Boolean = false;
|
||||
@@ -212,6 +211,7 @@ begin
|
||||
end;
|
||||
Config.UP:= false;
|
||||
eth2.registerType($0800, @recv);
|
||||
stdio.registerCommand('IFCONFIG', @terminal_command_ifconfig, 'Configure Network Settings.');
|
||||
Registered:= true;
|
||||
end;
|
||||
pop_trace;
|
||||
|
||||
+89
-13
File diff suppressed because it is too large
Load Diff
@@ -22,7 +22,7 @@ unit tcp;
|
||||
interface
|
||||
|
||||
uses
|
||||
tracer, stdio,
|
||||
tracer,
|
||||
nettypes, netutils,
|
||||
ipv4;
|
||||
|
||||
@@ -33,17 +33,13 @@ function accept(listener : PTCPSocket) : PTCPSocket;
|
||||
function send(socket : PTCPSocket; p_data : void; p_len : uint16) : TTCPError;
|
||||
function close(socket : PTCPSocket) : TTCPError;
|
||||
function abort_connection(socket : PTCPSocket) : TTCPError;
|
||||
procedure terminal_command_tcpconnect(params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
procedure terminal_command_tcplisten(params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
procedure terminal_command_tcphttp(params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
lmemorymanager, util, syslog, rand, lists,
|
||||
net, TMR_0_ISR, bios_data_area,
|
||||
strings, arp,
|
||||
processmanager, proctypes;
|
||||
stdio, strings, arp;
|
||||
|
||||
const
|
||||
TCP_PROTOCOL_ID = $06;
|
||||
@@ -229,7 +225,6 @@ begin
|
||||
sock^.OnReceive := onRecv;
|
||||
sock^.OnEvent := onEvt;
|
||||
sock^.UserData := userData;
|
||||
sock^.OwnerPID := 0;
|
||||
tcb^.Socket := sock;
|
||||
CreateSocket := sock;
|
||||
end;
|
||||
@@ -256,29 +251,10 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure socket_cleanup(handle : void);
|
||||
var
|
||||
sock : PTCPSocket;
|
||||
begin
|
||||
sock := PTCPSocket(handle);
|
||||
if sock = nil then exit;
|
||||
sock^.OwnerPID := 0; { Prevent DestroySocket from trying to unbind again }
|
||||
abort_connection(sock);
|
||||
end;
|
||||
|
||||
procedure DestroySocket(sock : PTCPSocket);
|
||||
var
|
||||
owner : PProcessContext;
|
||||
begin
|
||||
push_trace('tcp.DestroySocket');
|
||||
if sock <> nil then begin
|
||||
{ Remove resource binding from owning process }
|
||||
if sock^.OwnerPID <> 0 then begin
|
||||
owner := processmanager.findByID(sock^.OwnerPID);
|
||||
sock^.OwnerPID := 0;
|
||||
if owner <> nil then
|
||||
processmanager.unbindResourceNoCleanup(owner, void(sock));
|
||||
end;
|
||||
if sock^.TCB <> nil then begin
|
||||
sock^.TCB^.Socket := nil;
|
||||
DestroyTCB(sock^.TCB);
|
||||
@@ -1393,12 +1369,6 @@ begin
|
||||
|
||||
sock := CreateSocket(tcb, context^.OnReceive, context^.OnEvent, context^.UserData);
|
||||
|
||||
{ Auto-bind socket to calling process for cleanup on process death }
|
||||
if processmanager.CurrentProcess <> nil then begin
|
||||
sock^.OwnerPID := processmanager.CurrentProcess^.ProcessID;
|
||||
processmanager.bindResource(processmanager.CurrentProcess, rkSocket, void(sock), @socket_cleanup);
|
||||
end;
|
||||
|
||||
AddTCB(tcb);
|
||||
|
||||
{ Send SYN (includes MSS option via SendSegment) }
|
||||
@@ -1432,13 +1402,6 @@ begin
|
||||
if tcb^.BacklogMax = 0 then tcb^.BacklogMax := 5; { default backlog }
|
||||
|
||||
sock := CreateSocket(tcb, context^.OnReceive, context^.OnEvent, context^.UserData);
|
||||
|
||||
{ Auto-bind socket to calling process for cleanup on process death }
|
||||
if processmanager.CurrentProcess <> nil then begin
|
||||
sock^.OwnerPID := processmanager.CurrentProcess^.ProcessID;
|
||||
processmanager.bindResource(processmanager.CurrentProcess, rkSocket, void(sock), @socket_cleanup);
|
||||
end;
|
||||
|
||||
AddTCB(tcb);
|
||||
|
||||
listen := sock;
|
||||
@@ -1903,6 +1866,9 @@ begin
|
||||
Connections := DL_New(sizeof(uint32));
|
||||
ipv4.registerProtocol(TCP_PROTOCOL_ID, @ProcessPacket);
|
||||
TMR_0_ISR.hook(uint32(@TimerTick));
|
||||
stdio.registerCommand('TCPCONNECT', @terminal_command_tcpconnect, 'Connect to a TCP host and send Hello World.');
|
||||
stdio.registerCommand('TCPLISTEN', @terminal_command_tcplisten, 'Listen on a TCP port and log received data.');
|
||||
stdio.registerCommand('TCPHTTP', @terminal_command_tcphttp, 'Send HTTP GET to a host IP (port 80 default).');
|
||||
Registered := true;
|
||||
syslog.logln('TCP', 'TCP registered.');
|
||||
end;
|
||||
|
||||
@@ -112,7 +112,6 @@ function get_device_list() : PLinkedListBase;
|
||||
procedure register_filesystem(filesystem : PFilesystem);
|
||||
|
||||
procedure register_volume(device : PStorage_Device; volume : PStorage_Volume);
|
||||
procedure disk_command(params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
//function writeNewFile(fileName : pchar; extension : pchar; buffer : puint32; size : uint32) : uint32;
|
||||
//function readFile(fileName : pchar; extension : pchar; buffer : puint32; byteCount : puint32) : puint32;
|
||||
|
||||
@@ -232,6 +231,7 @@ begin
|
||||
setworkingdirectory('.');
|
||||
storageDevices:= ll_new(sizeof(TStorage_Device));
|
||||
fileSystems:= ll_New(sizeof(TFilesystem));
|
||||
stdio.registerCommand('DISK', @disk_command, 'Disk utility');
|
||||
|
||||
pop_trace();
|
||||
end;
|
||||
|
||||
@@ -104,10 +104,6 @@ function GetDirectories(Handle : uint32; Path : pchar) : PHashMap;
|
||||
function PathValid(Path : pchar) : TIsPathValid;
|
||||
function changeDirectory(Path : pchar) : TIsPathValid;
|
||||
function getWorkingDirectory : pchar;
|
||||
function makeAbsolutePathFrom(Path : pchar; BaseDir : pchar) : pchar;
|
||||
function resolvePathFrom(Path : pchar; BaseDir : pchar) : TIsPathValid;
|
||||
function GetDirectoryListingFrom(Path : pchar; BaseDir : pchar) : PHashMap;
|
||||
function changeDirectoryFrom(Path : pchar; BaseDir : pchar; var NewDir : pchar) : TIsPathValid;
|
||||
|
||||
//VFS Functions
|
||||
function newVirtualDirectory(Path : pchar) : TError;
|
||||
@@ -612,67 +608,6 @@ begin
|
||||
tracer.push_trace('vfs.getWorkingDirectory.exit');
|
||||
end;
|
||||
|
||||
function makeAbsolutePathFrom(Path : pchar; BaseDir : pchar) : pchar;
|
||||
var
|
||||
AbsPath : pchar;
|
||||
TempPath : pchar;
|
||||
begin
|
||||
if Path[0] = '/' then
|
||||
AbsPath := stringCopy(Path)
|
||||
else begin
|
||||
if BaseDir[StringSize(BaseDir)-1] <> '/' then
|
||||
TempPath := StringConcat(BaseDir, '/')
|
||||
else
|
||||
TempPath := stringCopy(BaseDir);
|
||||
AbsPath := StringConcat(TempPath, Path);
|
||||
kfree(void(TempPath));
|
||||
end;
|
||||
makeAbsolutePathFrom := AbsPath;
|
||||
end;
|
||||
|
||||
function resolvePathFrom(Path : pchar; BaseDir : pchar) : TIsPathValid;
|
||||
var
|
||||
TempPath : pchar;
|
||||
AbsPath : pchar;
|
||||
begin
|
||||
TempPath := makeAbsolutePathFrom(Path, BaseDir);
|
||||
AbsPath := evaluatePath(TempPath);
|
||||
kfree(void(TempPath));
|
||||
resolvePathFrom := PathValid(AbsPath);
|
||||
kfree(void(AbsPath));
|
||||
end;
|
||||
|
||||
function GetDirectoryListingFrom(Path : pchar; BaseDir : pchar) : PHashMap;
|
||||
var
|
||||
TempPath : pchar;
|
||||
AbsPath : pchar;
|
||||
begin
|
||||
TempPath := makeAbsolutePathFrom(Path, BaseDir);
|
||||
AbsPath := evaluatePath(TempPath);
|
||||
kfree(void(TempPath));
|
||||
GetDirectoryListingFrom := GetDirectoryListing(AbsPath);
|
||||
kfree(void(AbsPath));
|
||||
end;
|
||||
|
||||
function changeDirectoryFrom(Path : pchar; BaseDir : pchar; var NewDir : pchar) : TIsPathValid;
|
||||
var
|
||||
TempPath : pchar;
|
||||
AbsPath : pchar;
|
||||
Validity : TIsPathValid;
|
||||
begin
|
||||
TempPath := makeAbsolutePathFrom(Path, BaseDir);
|
||||
AbsPath := evaluatePath(TempPath);
|
||||
kfree(void(TempPath));
|
||||
Validity := PathValid(AbsPath);
|
||||
if Validity = pvDirectory then
|
||||
NewDir := AbsPath
|
||||
else begin
|
||||
NewDir := nil;
|
||||
kfree(void(AbsPath));
|
||||
end;
|
||||
changeDirectoryFrom := Validity;
|
||||
end;
|
||||
|
||||
{ Terminal Commands }
|
||||
|
||||
procedure VFS_COMMAND_PUSHD(params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
@@ -811,8 +746,11 @@ begin
|
||||
//outputln('VFS', makeRelative('/test/mydisk/mything', '/test/mydisk'));
|
||||
//while true do begin end;
|
||||
|
||||
{ LS, CD, PUSHD, POPD are now handled as per-terminal builtins
|
||||
in vterminal.pas so each terminal has its own working directory. }
|
||||
{ Register Terminal Commands }
|
||||
stdio.registerCommand('LS', @VFS_COMMAND_LS, 'List directory contents.');
|
||||
stdio.registerCommand('CD', @VFS_COMMAND_CD, 'Set working directory.');
|
||||
stdio.registerCommand('PUSHD', @VFS_COMMAND_PUSHD, 'Push the working directory.');
|
||||
stdio.registerCommand('POPD', @VFS_COMMAND_POPD, 'Pop the working directory.');
|
||||
|
||||
//ht:= PHashMap(Root^.Reference);
|
||||
//hashmap.add(ht, 'VDirectory', void(newDummyObject(otVDIRECTORY)));
|
||||
|
||||
@@ -21,7 +21,6 @@ uses
|
||||
uidebug,
|
||||
lvgl,
|
||||
video,
|
||||
windows,
|
||||
syslog;
|
||||
|
||||
const
|
||||
@@ -36,7 +35,6 @@ begin
|
||||
TickCounter := TickCounter + 1;
|
||||
if TickCounter >= TICKS_PER_FRAME then begin
|
||||
TickCounter := 0;
|
||||
windows.reapOrphanedWindows;
|
||||
desktop.update;
|
||||
uidebug.update;
|
||||
lvgl_handler;
|
||||
|
||||
@@ -467,7 +467,6 @@ const
|
||||
LV_KEY_PREV = 11;
|
||||
LV_KEY_HOME = 2;
|
||||
LV_KEY_END = 3;
|
||||
LV_KEY_CTRLC = 128; { Ctrl+C — terminal interrupt }
|
||||
|
||||
{ Arc mode }
|
||||
LV_ARC_MODE_NORMAL = 0;
|
||||
@@ -1862,16 +1861,6 @@ begin
|
||||
exit;
|
||||
end;
|
||||
|
||||
{ Ctrl+C — inject custom key code so focused terminal can handle it }
|
||||
if key_info.is_down_code and key_info.CTRL_DOWN and (key_info.key_code = ord('c')) then begin
|
||||
next_head := (kb_head + 1) mod KB_BUF_SIZE;
|
||||
if next_head <> kb_tail then begin
|
||||
kb_buf[kb_head] := LV_KEY_CTRLC;
|
||||
kb_head := next_head;
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
|
||||
{ Map Asuro key codes to LVGL key codes }
|
||||
case key_info.key_code of
|
||||
$1B: k := LV_KEY_ESC;
|
||||
|
||||
@@ -11,7 +11,7 @@ unit windows;
|
||||
interface
|
||||
|
||||
uses
|
||||
lvgl, mouse, serial, tracer, processmanager, proctypes;
|
||||
lvgl, mouse, serial, tracer;
|
||||
|
||||
const
|
||||
MAX_WINDOWS = 16;
|
||||
@@ -55,7 +55,6 @@ type
|
||||
on_close : TWinCloseCallback;
|
||||
on_resize : TWinResizeCallback;
|
||||
cursor_obj : Plv_obj; { cursor to keep on top }
|
||||
owner_pid : uint32; { owning process PID; 0 = unowned }
|
||||
end;
|
||||
|
||||
{ Create a new window. Returns window ID (0 = failure). }
|
||||
@@ -82,15 +81,6 @@ function getWindowCount: uint32;
|
||||
{ Set a callback to be notified when a window is resized. }
|
||||
procedure setWindowResizeCallback(win_id: uint32; cb: TWinResizeCallback);
|
||||
|
||||
{ Assign an owning process to a window.
|
||||
When reapOrphanedWindows detects the process has died, the window
|
||||
is automatically closed via its on_close callback. }
|
||||
procedure setWindowOwner(win_id: uint32; pid: uint32);
|
||||
|
||||
{ Check all windows for dead owner processes and close them.
|
||||
Called once per frame from graphicsrefresh. }
|
||||
procedure reapOrphanedWindows;
|
||||
|
||||
implementation
|
||||
|
||||
var
|
||||
@@ -651,7 +641,6 @@ begin
|
||||
wins[id].on_close := closeCB;
|
||||
wins[id].on_resize := nil;
|
||||
wins[id].cursor_obj := cursor;
|
||||
wins[id].owner_pid := 0;
|
||||
|
||||
{ Bring to front }
|
||||
bringToFront(id);
|
||||
@@ -709,7 +698,6 @@ begin
|
||||
wins[win_id].on_close := nil;
|
||||
wins[win_id].on_resize := nil;
|
||||
wins[win_id].cursor_obj := nil;
|
||||
wins[win_id].owner_pid := 0;
|
||||
|
||||
tracer.pop_trace;
|
||||
end;
|
||||
@@ -758,36 +746,4 @@ begin
|
||||
wins[win_id].on_resize := cb;
|
||||
end;
|
||||
|
||||
{ ============================================================
|
||||
Public: set window owner PID
|
||||
============================================================ }
|
||||
procedure setWindowOwner(win_id: uint32; pid: uint32);
|
||||
begin
|
||||
if (win_id < 1) or (win_id > MAX_WINDOWS) then exit;
|
||||
if wins[win_id].state = wsNone then exit;
|
||||
wins[win_id].owner_pid := pid;
|
||||
end;
|
||||
|
||||
{ ============================================================
|
||||
Public: reap windows whose owning process has died
|
||||
============================================================ }
|
||||
procedure reapOrphanedWindows;
|
||||
var
|
||||
i : uint32;
|
||||
ctx : PProcessContext;
|
||||
begin
|
||||
for i := 1 to MAX_WINDOWS do begin
|
||||
if wins[i].state = wsNone then continue;
|
||||
if wins[i].owner_pid = 0 then continue;
|
||||
ctx := processmanager.findByID(wins[i].owner_pid);
|
||||
if (ctx = nil) or (ctx^.State = psFinished) or (ctx^.State = psError) then begin
|
||||
{ Owner is dead — trigger close callback or destroy directly }
|
||||
if wins[i].on_close <> nil then
|
||||
wins[i].on_close(i)
|
||||
else
|
||||
destroyWindow(i);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
@@ -72,8 +72,6 @@ procedure register_driver(Driver_Name : PChar; DeviceID : PDeviceIdentifier; Loa
|
||||
procedure register_driver_ex(Driver_Name : PChar; DeviceID : PDeviceIdentifier; Load_Callback : TDriverLoadCallback; force_load : boolean);
|
||||
procedure register_device(Device_Name : PChar; DeviceID : PDeviceIdentifier; ptr : void);
|
||||
|
||||
procedure terminal_command_dev(Params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
|
||||
var
|
||||
Root : PDriverRegistration = nil;
|
||||
Dev : PDeviceRegistration = nil;
|
||||
@@ -330,6 +328,10 @@ end;
|
||||
procedure init;
|
||||
begin
|
||||
push_trace('driver_management.init');
|
||||
stdio.registerCommand('DEV', @terminal_command_dev, 'Driver Management Interface.');
|
||||
//stdio.registerCommand('DRIVERSEX', @terminal_command_driversex, 'List all available drivers.');
|
||||
//stdio.registerCommand('DRIVERS', @terminal_command_drivers, 'List loaded drivers.');
|
||||
//stdio.registerCommand('DEVICES', @terminal_command_devices, 'List devices.');
|
||||
pop_trace;
|
||||
end;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user