// shellApp.h — DVX Shell application lifecycle types and API #ifndef SHELL_APP_H #define SHELL_APP_H #include "dvxApp.h" #include "dvxWidget.h" #include "taskswitch.h" #include #include // ============================================================ // App descriptor (exported by each DXE app) // ============================================================ #define SHELL_APP_NAME_MAX 64 #define SHELL_MAX_APPS 32 typedef struct { char name[SHELL_APP_NAME_MAX]; bool hasMainLoop; int32_t stackSize; // 0 = TS_DEFAULT_STACK_SIZE int32_t priority; // TS_PRIORITY_* or custom } AppDescriptorT; // ============================================================ // App context (passed to appMain) // ============================================================ typedef struct { AppContextT *shellCtx; // the shell's GUI context int32_t appId; // this app's ID } DxeAppContextT; // ============================================================ // Per-app state // ============================================================ typedef enum { AppStateFreeE, // slot available AppStateLoadedE, // DXE loaded, not yet started AppStateRunningE, // entry point called, active AppStateTerminatingE // shutdown in progress } AppStateE; typedef struct { int32_t appId; // unique ID = slot index (1-based; 0 = shell) char name[SHELL_APP_NAME_MAX]; char path[260]; void *dxeHandle; // dlopen() handle AppStateE state; bool hasMainLoop; uint32_t mainTaskId; // task ID if hasMainLoop, else 0 int32_t (*entryFn)(DxeAppContextT *); void (*shutdownFn)(void); // may be NULL DxeAppContextT dxeCtx; // context passed to appMain } ShellAppT; // ============================================================ // Shell global state // ============================================================ // Current app ID for resource tracking (0 = shell) extern int32_t sCurrentAppId; // ============================================================ // App lifecycle API // ============================================================ // Initialize the app slot table void shellAppInit(void); // Load and start an app from a DXE file. Returns app ID (>= 1) or -1 on error. int32_t shellLoadApp(AppContextT *ctx, const char *path); // Reap finished callback-only apps (call each frame from main loop) void shellReapApps(AppContextT *ctx); // Gracefully shut down a single app void shellReapApp(AppContextT *ctx, ShellAppT *app); // Forcibly kill an app (Task Manager "End Task") void shellForceKillApp(AppContextT *ctx, ShellAppT *app); // Terminate all running apps (shell shutdown) void shellTerminateAllApps(AppContextT *ctx); // Get app slot by ID (returns NULL if invalid/free) ShellAppT *shellGetApp(int32_t appId); // Count running apps (not counting the shell itself) int32_t shellRunningAppCount(void); // ============================================================ // Logging // ============================================================ // Write a printf-style message to SHELL.LOG void shellLog(const char *fmt, ...); // ============================================================ // DXE export table // ============================================================ // Register the DXE symbol export table (call before any dlopen) void shellExportInit(void); // ============================================================ // Desktop callback // ============================================================ // Default desktop app path #define SHELL_DESKTOP_APP "apps/progman.app" // Register a callback for app state changes (load, reap, crash). // The desktop app calls this during appMain to receive notifications. void shellRegisterDesktopUpdate(void (*updateFn)(void)); #endif // SHELL_APP_H