701 lines
21 KiB
C
701 lines
21 KiB
C
// shellExport.c — DXE export table and wrapper functions for DVX Shell
|
|
//
|
|
// Exports all dvx*/wgt*/ts* symbols that DXE apps need. A few functions
|
|
// are wrapped for resource tracking (window ownership via appId).
|
|
//
|
|
// DXE3 is DJGPP's dynamic linking mechanism. Unlike ELF shared libraries,
|
|
// DXE modules have no implicit access to the host's symbol table. Every
|
|
// function or variable the DXE needs must be explicitly listed in an
|
|
// export table registered via dlregsym() BEFORE any dlopen() call. If a
|
|
// symbol is missing, dlopen() returns NULL with a "symbol not found" error.
|
|
//
|
|
// This file is essentially the ABI contract between the shell and apps.
|
|
// Three categories of exports:
|
|
//
|
|
// 1. Wrapped functions: dvxCreateWindow, dvxCreateWindowCentered,
|
|
// dvxDestroyWindow. These are intercepted to stamp win->appId for
|
|
// resource ownership tracking. The DXE sees them under their original
|
|
// names — the app code calls dvxCreateWindow() normally and gets our
|
|
// wrapper transparently.
|
|
//
|
|
// 2. Direct exports: all other dvx/wgt/wm/ts functions. These are safe
|
|
// to call without shell-side interception.
|
|
//
|
|
// 3. libc functions: DXE modules are statically linked against DJGPP's
|
|
// libc, but DJGPP's DXE3 loader requires explicit re-export of any
|
|
// libc symbols the module references. Without these entries, the DXE
|
|
// would fail to load with unresolved symbol errors. This is a DXE3
|
|
// design limitation — there's no automatic fallback to the host's libc.
|
|
|
|
#include "shellApp.h"
|
|
#include "shellInfo.h"
|
|
#include "shellTaskMgr.h"
|
|
#include "dvxApp.h"
|
|
#include "dvxDialog.h"
|
|
#include "dvxWidget.h"
|
|
#include "dvxDraw.h"
|
|
#include "dvxPrefs.h"
|
|
#include "platform/dvxPlatform.h"
|
|
#include "dvxVideo.h"
|
|
#include "dvxWm.h"
|
|
#include "taskswitch.h"
|
|
|
|
#include <sys/dxe.h>
|
|
#include <sys/stat.h>
|
|
#include <ctype.h>
|
|
#include <dirent.h>
|
|
#include <math.h>
|
|
#include <setjmp.h>
|
|
#include <signal.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <strings.h>
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
|
|
// stb headers (no IMPLEMENTATION — symbols are in libdvx.a / libtasks.a)
|
|
#include "thirdparty/stb_image.h"
|
|
#include "thirdparty/stb_image_write.h"
|
|
#include "thirdparty/stb_ds.h"
|
|
|
|
// DJGPP stdio internals — the stdin/stdout/stderr macros dereference
|
|
// these pointers. Without exporting them, any DXE that uses printf
|
|
// or fprintf gets an unresolved symbol.
|
|
extern FILE __dj_stdin;
|
|
extern FILE __dj_stdout;
|
|
extern FILE __dj_stderr;
|
|
|
|
// ============================================================
|
|
// Prototypes
|
|
// ============================================================
|
|
|
|
static void shellRegisterExports(void);
|
|
static WindowT *shellWrapCreateWindow(AppContextT *ctx, const char *title, int32_t x, int32_t y, int32_t w, int32_t h, bool resizable);
|
|
static WindowT *shellWrapCreateWindowCentered(AppContextT *ctx, const char *title, int32_t w, int32_t h, bool resizable);
|
|
static void shellWrapDestroyWindow(AppContextT *ctx, WindowT *win);
|
|
|
|
// ============================================================
|
|
// Wrapper: dvxCreateWindow — stamps win->appId
|
|
// ============================================================
|
|
|
|
// The wrapper calls the real dvxCreateWindow, then tags the result with
|
|
// sCurrentAppId. This is how the shell knows which app owns which window,
|
|
// enabling per-app window cleanup on crash/termination. The app never
|
|
// sees the difference — the wrapper has the same signature and is
|
|
// exported under the same name as the original function.
|
|
static WindowT *shellWrapCreateWindow(AppContextT *ctx, const char *title, int32_t x, int32_t y, int32_t w, int32_t h, bool resizable) {
|
|
WindowT *win = dvxCreateWindow(ctx, title, x, y, w, h, resizable);
|
|
|
|
if (win) {
|
|
win->appId = sCurrentAppId;
|
|
}
|
|
|
|
return win;
|
|
}
|
|
|
|
|
|
// ============================================================
|
|
// Wrapper: dvxCreateWindowCentered — stamps win->appId
|
|
// ============================================================
|
|
|
|
static WindowT *shellWrapCreateWindowCentered(AppContextT *ctx, const char *title, int32_t w, int32_t h, bool resizable) {
|
|
WindowT *win = dvxCreateWindowCentered(ctx, title, w, h, resizable);
|
|
|
|
if (win) {
|
|
win->appId = sCurrentAppId;
|
|
}
|
|
|
|
return win;
|
|
}
|
|
|
|
|
|
// ============================================================
|
|
// Wrapper: dvxDestroyWindow — checks for last-window reap
|
|
// ============================================================
|
|
|
|
// Beyond just destroying the window, this wrapper implements the lifecycle
|
|
// rule for callback-only apps: when their last window closes, they're done.
|
|
// Main-loop apps manage their own lifetime (their task returns from
|
|
// appMain), so this check only applies to callback-only apps.
|
|
// The appId is captured before destruction because the window struct is
|
|
// freed by dvxDestroyWindow.
|
|
static void shellWrapDestroyWindow(AppContextT *ctx, WindowT *win) {
|
|
int32_t appId = win->appId;
|
|
|
|
dvxDestroyWindow(ctx, win);
|
|
|
|
// If this was a callback-only app's last window, mark for reaping
|
|
if (appId > 0) {
|
|
ShellAppT *app = shellGetApp(appId);
|
|
|
|
if (app && !app->hasMainLoop && app->state == AppStateRunningE) {
|
|
// Check if app still has any windows
|
|
bool hasWindows = false;
|
|
|
|
for (int32_t i = 0; i < ctx->stack.count; i++) {
|
|
if (ctx->stack.windows[i]->appId == appId) {
|
|
hasWindows = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!hasWindows) {
|
|
app->state = AppStateTerminatingE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// ============================================================
|
|
// Export table
|
|
// ============================================================
|
|
|
|
// DXE_EXPORT_TABLE generates a DXE symbol table array. DXE_EXPORT(fn)
|
|
// expands to { "_fn", (void *)fn } — the underscore prefix matches COFF
|
|
// symbol naming. For wrapped functions we use raw entries with explicit
|
|
// names so the DXE sees "_dvxCreateWindow" but gets our wrapper's address.
|
|
|
|
DXE_EXPORT_TABLE(shellExportTable)
|
|
// Wrapped functions (exported under original names, but pointing to
|
|
// our wrappers that add resource tracking)
|
|
{ "_dvxCreateWindow", (void *)shellWrapCreateWindow },
|
|
{ "_dvxDestroyWindow", (void *)shellWrapDestroyWindow },
|
|
|
|
// dvxPlatform.h — platform abstraction
|
|
DXE_EXPORT(platformLineEnding)
|
|
DXE_EXPORT(platformChdir)
|
|
DXE_EXPORT(platformGetMemoryInfo)
|
|
DXE_EXPORT(platformMouseSetAccel)
|
|
DXE_EXPORT(platformMouseWarp)
|
|
DXE_EXPORT(platformPathDirEnd)
|
|
DXE_EXPORT(platformStripLineEndings)
|
|
DXE_EXPORT(platformValidateFilename)
|
|
DXE_EXPORT(platformVideoEnumModes)
|
|
|
|
// dvxPrefs.h — preferences
|
|
DXE_EXPORT(prefsGetBool)
|
|
DXE_EXPORT(prefsGetInt)
|
|
DXE_EXPORT(prefsGetString)
|
|
DXE_EXPORT(prefsLoad)
|
|
DXE_EXPORT(prefsRemove)
|
|
DXE_EXPORT(prefsSave)
|
|
DXE_EXPORT(prefsSaveAs)
|
|
DXE_EXPORT(prefsSetBool)
|
|
DXE_EXPORT(prefsSetInt)
|
|
DXE_EXPORT(prefsSetString)
|
|
|
|
// dvxApp.h — direct exports
|
|
DXE_EXPORT(dvxApplyColorScheme)
|
|
DXE_EXPORT(dvxChangeVideoMode)
|
|
DXE_EXPORT(dvxColorName)
|
|
DXE_EXPORT(dvxGetColor)
|
|
DXE_EXPORT(dvxInit)
|
|
DXE_EXPORT(dvxLoadTheme)
|
|
DXE_EXPORT(dvxResetColorScheme)
|
|
DXE_EXPORT(dvxSaveTheme)
|
|
DXE_EXPORT(dvxSetColor)
|
|
DXE_EXPORT(dvxSetMouseConfig)
|
|
DXE_EXPORT(dvxSetWallpaper)
|
|
DXE_EXPORT(dvxShutdown)
|
|
DXE_EXPORT(dvxUpdate)
|
|
{ "_dvxCreateWindowCentered", (void *)shellWrapCreateWindowCentered },
|
|
DXE_EXPORT(dvxFitWindow)
|
|
DXE_EXPORT(dvxInvalidateRect)
|
|
DXE_EXPORT(dvxInvalidateWindow)
|
|
DXE_EXPORT(dvxMinimizeWindow)
|
|
DXE_EXPORT(dvxMaximizeWindow)
|
|
DXE_EXPORT(dvxQuit)
|
|
DXE_EXPORT(dvxSetTitle)
|
|
DXE_EXPORT(dvxGetFont)
|
|
DXE_EXPORT(dvxGetColors)
|
|
DXE_EXPORT(dvxGetDisplay)
|
|
DXE_EXPORT(dvxGetBlitOps)
|
|
DXE_EXPORT(dvxSetWindowIcon)
|
|
DXE_EXPORT(dvxLoadImage)
|
|
DXE_EXPORT(dvxFreeImage)
|
|
DXE_EXPORT(dvxSaveImage)
|
|
DXE_EXPORT(dvxScreenshot)
|
|
DXE_EXPORT(dvxWindowScreenshot)
|
|
DXE_EXPORT(dvxCreateAccelTable)
|
|
DXE_EXPORT(dvxFreeAccelTable)
|
|
DXE_EXPORT(dvxAddAccel)
|
|
DXE_EXPORT(dvxCascadeWindows)
|
|
DXE_EXPORT(dvxTileWindows)
|
|
DXE_EXPORT(dvxTileWindowsH)
|
|
DXE_EXPORT(dvxTileWindowsV)
|
|
DXE_EXPORT(dvxClipboardCopy)
|
|
DXE_EXPORT(dvxClipboardGet)
|
|
|
|
// dvxDialog.h
|
|
DXE_EXPORT(dvxMessageBox)
|
|
DXE_EXPORT(dvxFileDialog)
|
|
|
|
// dvxDraw.h
|
|
DXE_EXPORT(rectFill)
|
|
DXE_EXPORT(rectCopy)
|
|
DXE_EXPORT(drawBevel)
|
|
DXE_EXPORT(drawChar)
|
|
DXE_EXPORT(drawText)
|
|
DXE_EXPORT(drawTextN)
|
|
DXE_EXPORT(textWidth)
|
|
DXE_EXPORT(drawTextAccel)
|
|
DXE_EXPORT(textWidthAccel)
|
|
DXE_EXPORT(drawFocusRect)
|
|
DXE_EXPORT(drawHLine)
|
|
DXE_EXPORT(drawVLine)
|
|
|
|
// dvxVideo.h
|
|
DXE_EXPORT(packColor)
|
|
DXE_EXPORT(resetClipRect)
|
|
DXE_EXPORT(setClipRect)
|
|
|
|
// dvxWm.h
|
|
DXE_EXPORT(wmAddMenuBar)
|
|
DXE_EXPORT(wmAddMenu)
|
|
DXE_EXPORT(wmAddMenuItem)
|
|
DXE_EXPORT(wmAddMenuCheckItem)
|
|
DXE_EXPORT(wmAddMenuRadioItem)
|
|
DXE_EXPORT(wmAddMenuSeparator)
|
|
DXE_EXPORT(wmAddSubMenu)
|
|
DXE_EXPORT(wmAddVScrollbar)
|
|
DXE_EXPORT(wmAddHScrollbar)
|
|
DXE_EXPORT(wmMinimizedIconPos)
|
|
DXE_EXPORT(wmMinimizedIconRect)
|
|
DXE_EXPORT(wmSetTitle)
|
|
DXE_EXPORT(wmSetIcon)
|
|
DXE_EXPORT(wmCreateMenu)
|
|
DXE_EXPORT(wmFreeMenu)
|
|
DXE_EXPORT(wmUpdateContentRect)
|
|
DXE_EXPORT(wmReallocContentBuf)
|
|
|
|
// dvxWidget.h — window integration
|
|
DXE_EXPORT(wgtInitWindow)
|
|
|
|
// dvxWidget.h — containers
|
|
DXE_EXPORT(wgtVBox)
|
|
DXE_EXPORT(wgtHBox)
|
|
DXE_EXPORT(wgtFrame)
|
|
|
|
// dvxWidget.h — basic widgets
|
|
DXE_EXPORT(wgtLabel)
|
|
DXE_EXPORT(wgtButton)
|
|
DXE_EXPORT(wgtCheckbox)
|
|
DXE_EXPORT(wgtTextInput)
|
|
DXE_EXPORT(wgtPasswordInput)
|
|
DXE_EXPORT(wgtMaskedInput)
|
|
|
|
// dvxWidget.h — radio buttons
|
|
DXE_EXPORT(wgtRadioGroup)
|
|
DXE_EXPORT(wgtRadio)
|
|
|
|
// dvxWidget.h — spacing
|
|
DXE_EXPORT(wgtSpacer)
|
|
DXE_EXPORT(wgtHSeparator)
|
|
DXE_EXPORT(wgtVSeparator)
|
|
|
|
// dvxWidget.h — complex widgets
|
|
DXE_EXPORT(wgtListBox)
|
|
DXE_EXPORT(wgtTextArea)
|
|
|
|
// dvxWidget.h — dropdown/combo
|
|
DXE_EXPORT(wgtDropdown)
|
|
DXE_EXPORT(wgtDropdownSetItems)
|
|
DXE_EXPORT(wgtDropdownGetSelected)
|
|
DXE_EXPORT(wgtDropdownSetSelected)
|
|
DXE_EXPORT(wgtComboBox)
|
|
DXE_EXPORT(wgtComboBoxSetItems)
|
|
DXE_EXPORT(wgtComboBoxGetSelected)
|
|
DXE_EXPORT(wgtComboBoxSetSelected)
|
|
|
|
// dvxWidget.h — progress bar
|
|
DXE_EXPORT(wgtProgressBar)
|
|
DXE_EXPORT(wgtProgressBarV)
|
|
DXE_EXPORT(wgtProgressBarSetValue)
|
|
DXE_EXPORT(wgtProgressBarGetValue)
|
|
|
|
// dvxWidget.h — slider
|
|
DXE_EXPORT(wgtSlider)
|
|
DXE_EXPORT(wgtSliderSetValue)
|
|
DXE_EXPORT(wgtSliderGetValue)
|
|
|
|
// dvxWidget.h — spinner
|
|
DXE_EXPORT(wgtSpinner)
|
|
DXE_EXPORT(wgtSpinnerSetValue)
|
|
DXE_EXPORT(wgtSpinnerGetValue)
|
|
DXE_EXPORT(wgtSpinnerSetRange)
|
|
DXE_EXPORT(wgtSpinnerSetStep)
|
|
|
|
// dvxWidget.h — tab control
|
|
DXE_EXPORT(wgtTabControl)
|
|
DXE_EXPORT(wgtTabPage)
|
|
DXE_EXPORT(wgtTabControlSetActive)
|
|
DXE_EXPORT(wgtTabControlGetActive)
|
|
|
|
// dvxWidget.h — status bar / toolbar
|
|
DXE_EXPORT(wgtStatusBar)
|
|
DXE_EXPORT(wgtToolbar)
|
|
|
|
// dvxWidget.h — tree view
|
|
DXE_EXPORT(wgtTreeView)
|
|
DXE_EXPORT(wgtTreeViewGetSelected)
|
|
DXE_EXPORT(wgtTreeViewSetSelected)
|
|
DXE_EXPORT(wgtTreeViewSetMultiSelect)
|
|
DXE_EXPORT(wgtTreeViewSetReorderable)
|
|
DXE_EXPORT(wgtTreeItem)
|
|
DXE_EXPORT(wgtTreeItemSetExpanded)
|
|
DXE_EXPORT(wgtTreeItemIsExpanded)
|
|
DXE_EXPORT(wgtTreeItemIsSelected)
|
|
DXE_EXPORT(wgtTreeItemSetSelected)
|
|
|
|
// dvxWidget.h — list view
|
|
DXE_EXPORT(wgtListView)
|
|
DXE_EXPORT(wgtListViewSetColumns)
|
|
DXE_EXPORT(wgtListViewSetData)
|
|
DXE_EXPORT(wgtListViewGetSelected)
|
|
DXE_EXPORT(wgtListViewSetSelected)
|
|
DXE_EXPORT(wgtListViewSetSort)
|
|
DXE_EXPORT(wgtListViewSetHeaderClickCallback)
|
|
DXE_EXPORT(wgtListViewSetMultiSelect)
|
|
DXE_EXPORT(wgtListViewIsItemSelected)
|
|
DXE_EXPORT(wgtListViewSetItemSelected)
|
|
DXE_EXPORT(wgtListViewSelectAll)
|
|
DXE_EXPORT(wgtListViewClearSelection)
|
|
DXE_EXPORT(wgtListViewSetReorderable)
|
|
|
|
// dvxWidget.h — scroll pane / splitter
|
|
DXE_EXPORT(wgtScrollPane)
|
|
DXE_EXPORT(wgtSplitter)
|
|
DXE_EXPORT(wgtSplitterSetPos)
|
|
DXE_EXPORT(wgtSplitterGetPos)
|
|
|
|
// dvxWidget.h — image / image button
|
|
DXE_EXPORT(wgtImageButton)
|
|
DXE_EXPORT(wgtImageButtonFromFile)
|
|
DXE_EXPORT(wgtImageButtonSetData)
|
|
DXE_EXPORT(wgtImage)
|
|
DXE_EXPORT(wgtImageFromFile)
|
|
DXE_EXPORT(wgtImageSetData)
|
|
|
|
// dvxWidget.h — canvas
|
|
DXE_EXPORT(wgtCanvas)
|
|
DXE_EXPORT(wgtCanvasClear)
|
|
DXE_EXPORT(wgtCanvasSetMouseCallback)
|
|
DXE_EXPORT(wgtCanvasSetPenColor)
|
|
DXE_EXPORT(wgtCanvasSetPenSize)
|
|
DXE_EXPORT(wgtCanvasSave)
|
|
DXE_EXPORT(wgtCanvasLoad)
|
|
DXE_EXPORT(wgtCanvasDrawLine)
|
|
DXE_EXPORT(wgtCanvasDrawRect)
|
|
DXE_EXPORT(wgtCanvasFillRect)
|
|
DXE_EXPORT(wgtCanvasFillCircle)
|
|
DXE_EXPORT(wgtCanvasSetPixel)
|
|
DXE_EXPORT(wgtCanvasGetPixel)
|
|
|
|
// dvxWidget.h — ANSI terminal
|
|
DXE_EXPORT(wgtAnsiTerm)
|
|
DXE_EXPORT(wgtAnsiTermWrite)
|
|
DXE_EXPORT(wgtAnsiTermClear)
|
|
DXE_EXPORT(wgtAnsiTermSetComm)
|
|
DXE_EXPORT(wgtAnsiTermSetScrollback)
|
|
DXE_EXPORT(wgtAnsiTermPoll)
|
|
DXE_EXPORT(wgtAnsiTermRepaint)
|
|
|
|
// dvxWidget.h — operations
|
|
DXE_EXPORT(wgtInvalidate)
|
|
DXE_EXPORT(wgtInvalidatePaint)
|
|
DXE_EXPORT(wgtSetDebugLayout)
|
|
DXE_EXPORT(wgtSetText)
|
|
DXE_EXPORT(wgtSetTooltip)
|
|
DXE_EXPORT(wgtGetText)
|
|
DXE_EXPORT(wgtGetFocused)
|
|
DXE_EXPORT(wgtSetEnabled)
|
|
DXE_EXPORT(wgtSetFocused)
|
|
DXE_EXPORT(wgtSetReadOnly)
|
|
DXE_EXPORT(wgtSetVisible)
|
|
DXE_EXPORT(wgtGetContext)
|
|
DXE_EXPORT(wgtSetName)
|
|
DXE_EXPORT(wgtFind)
|
|
DXE_EXPORT(wgtDestroy)
|
|
|
|
// dvxWidget.h — list box ops
|
|
DXE_EXPORT(wgtListBoxSetItems)
|
|
DXE_EXPORT(wgtListBoxGetSelected)
|
|
DXE_EXPORT(wgtListBoxSetSelected)
|
|
DXE_EXPORT(wgtListBoxSetMultiSelect)
|
|
DXE_EXPORT(wgtListBoxIsItemSelected)
|
|
DXE_EXPORT(wgtListBoxSetItemSelected)
|
|
DXE_EXPORT(wgtListBoxSelectAll)
|
|
DXE_EXPORT(wgtListBoxClearSelection)
|
|
DXE_EXPORT(wgtListBoxSetReorderable)
|
|
|
|
// dvxWidget.h — layout
|
|
DXE_EXPORT(wgtResolveSize)
|
|
DXE_EXPORT(wgtLayout)
|
|
DXE_EXPORT(wgtPaint)
|
|
|
|
// taskswitch.h — only yield and query functions are exported.
|
|
// tsCreate/tsKill/etc. are NOT exported because apps should not
|
|
// manipulate the task system directly — the shell manages task
|
|
// lifecycle through shellLoadApp/shellForceKillApp.
|
|
DXE_EXPORT(tsActiveCount)
|
|
DXE_EXPORT(tsCreate)
|
|
DXE_EXPORT(tsCurrentId)
|
|
DXE_EXPORT(tsGetName)
|
|
DXE_EXPORT(tsGetPriority)
|
|
DXE_EXPORT(tsGetState)
|
|
DXE_EXPORT(tsKill)
|
|
DXE_EXPORT(tsPause)
|
|
DXE_EXPORT(tsResume)
|
|
DXE_EXPORT(tsSetPriority)
|
|
DXE_EXPORT(tsYield)
|
|
|
|
// dvxWm.h — direct window management
|
|
DXE_EXPORT(wmRaiseWindow)
|
|
DXE_EXPORT(wmSetFocus)
|
|
DXE_EXPORT(wmRestoreMinimized)
|
|
|
|
// Shell API
|
|
DXE_EXPORT(shellLog)
|
|
DXE_EXPORT(shellLoadApp)
|
|
DXE_EXPORT(shellGetApp)
|
|
DXE_EXPORT(shellTaskMgrOpen)
|
|
DXE_EXPORT(shellForceKillApp)
|
|
DXE_EXPORT(shellRunningAppCount)
|
|
DXE_EXPORT(shellRegisterDesktopUpdate)
|
|
DXE_EXPORT(shellUnregisterDesktopUpdate)
|
|
DXE_EXPORT(shellGetSystemInfo)
|
|
|
|
// ================================================================
|
|
// libc / libm exports. DXE3 modules are relocatable objects, not
|
|
// fully linked executables. Every C library function a DXE calls
|
|
// must appear here so the loader can resolve it at dlopen time.
|
|
// This is intentionally comprehensive to avoid "unresolved symbol"
|
|
// surprises when apps use standard functions.
|
|
// ================================================================
|
|
|
|
// --- memory ---
|
|
DXE_EXPORT(calloc)
|
|
DXE_EXPORT(free)
|
|
DXE_EXPORT(malloc)
|
|
DXE_EXPORT(realloc)
|
|
|
|
// --- string / memory ops ---
|
|
DXE_EXPORT(memchr)
|
|
DXE_EXPORT(memcmp)
|
|
DXE_EXPORT(memcpy)
|
|
DXE_EXPORT(memmove)
|
|
DXE_EXPORT(memset)
|
|
DXE_EXPORT(strcasecmp)
|
|
DXE_EXPORT(strcat)
|
|
DXE_EXPORT(strchr)
|
|
DXE_EXPORT(strcmp)
|
|
DXE_EXPORT(strcpy)
|
|
DXE_EXPORT(strcspn)
|
|
DXE_EXPORT(strdup)
|
|
DXE_EXPORT(strerror)
|
|
DXE_EXPORT(strlen)
|
|
DXE_EXPORT(strncasecmp)
|
|
DXE_EXPORT(strncat)
|
|
DXE_EXPORT(strncmp)
|
|
DXE_EXPORT(strncpy)
|
|
DXE_EXPORT(strpbrk)
|
|
DXE_EXPORT(strrchr)
|
|
DXE_EXPORT(strspn)
|
|
DXE_EXPORT(strstr)
|
|
DXE_EXPORT(strtok)
|
|
|
|
// --- ctype ---
|
|
DXE_EXPORT(isalnum)
|
|
DXE_EXPORT(isalpha)
|
|
DXE_EXPORT(isdigit)
|
|
DXE_EXPORT(islower)
|
|
DXE_EXPORT(isprint)
|
|
DXE_EXPORT(ispunct)
|
|
DXE_EXPORT(isspace)
|
|
DXE_EXPORT(isupper)
|
|
DXE_EXPORT(isxdigit)
|
|
DXE_EXPORT(tolower)
|
|
DXE_EXPORT(toupper)
|
|
|
|
// --- conversion ---
|
|
DXE_EXPORT(abs)
|
|
DXE_EXPORT(atof)
|
|
DXE_EXPORT(atoi)
|
|
DXE_EXPORT(atol)
|
|
DXE_EXPORT(labs)
|
|
DXE_EXPORT(strtod)
|
|
DXE_EXPORT(strtol)
|
|
DXE_EXPORT(strtoul)
|
|
|
|
// --- formatted I/O ---
|
|
DXE_EXPORT(fprintf)
|
|
DXE_EXPORT(fputs)
|
|
DXE_EXPORT(fscanf)
|
|
DXE_EXPORT(printf)
|
|
DXE_EXPORT(puts)
|
|
DXE_EXPORT(snprintf)
|
|
DXE_EXPORT(sprintf)
|
|
DXE_EXPORT(sscanf)
|
|
DXE_EXPORT(vfprintf)
|
|
DXE_EXPORT(vprintf)
|
|
DXE_EXPORT(vsnprintf)
|
|
DXE_EXPORT(vsprintf)
|
|
|
|
// --- character I/O ---
|
|
DXE_EXPORT(fgetc)
|
|
DXE_EXPORT(fgets)
|
|
DXE_EXPORT(fputc)
|
|
DXE_EXPORT(getc)
|
|
DXE_EXPORT(putc)
|
|
DXE_EXPORT(putchar)
|
|
DXE_EXPORT(ungetc)
|
|
|
|
// --- file I/O ---
|
|
DXE_EXPORT(fclose)
|
|
DXE_EXPORT(feof)
|
|
DXE_EXPORT(ferror)
|
|
DXE_EXPORT(fflush)
|
|
DXE_EXPORT(fopen)
|
|
DXE_EXPORT(fread)
|
|
DXE_EXPORT(freopen)
|
|
DXE_EXPORT(fseek)
|
|
DXE_EXPORT(ftell)
|
|
DXE_EXPORT(fwrite)
|
|
DXE_EXPORT(remove)
|
|
DXE_EXPORT(rename)
|
|
DXE_EXPORT(rewind)
|
|
DXE_EXPORT(tmpfile)
|
|
DXE_EXPORT(tmpnam)
|
|
|
|
// --- directory ---
|
|
DXE_EXPORT(closedir)
|
|
DXE_EXPORT(mkdir)
|
|
DXE_EXPORT(opendir)
|
|
DXE_EXPORT(readdir)
|
|
DXE_EXPORT(rmdir)
|
|
|
|
// --- filesystem ---
|
|
DXE_EXPORT(access)
|
|
DXE_EXPORT(chdir)
|
|
DXE_EXPORT(getcwd)
|
|
DXE_EXPORT(stat)
|
|
DXE_EXPORT(unlink)
|
|
|
|
// --- time ---
|
|
DXE_EXPORT(clock)
|
|
DXE_EXPORT(difftime)
|
|
DXE_EXPORT(gmtime)
|
|
DXE_EXPORT(localtime)
|
|
DXE_EXPORT(mktime)
|
|
DXE_EXPORT(strftime)
|
|
DXE_EXPORT(time)
|
|
|
|
// --- process / environment ---
|
|
DXE_EXPORT(abort)
|
|
DXE_EXPORT(atexit)
|
|
DXE_EXPORT(exit)
|
|
DXE_EXPORT(getenv)
|
|
DXE_EXPORT(system)
|
|
|
|
// --- sorting / searching ---
|
|
DXE_EXPORT(bsearch)
|
|
DXE_EXPORT(qsort)
|
|
|
|
// --- random ---
|
|
DXE_EXPORT(rand)
|
|
DXE_EXPORT(srand)
|
|
|
|
// --- setjmp / signal ---
|
|
DXE_EXPORT(longjmp)
|
|
DXE_EXPORT(setjmp)
|
|
DXE_EXPORT(signal)
|
|
|
|
// --- libm ---
|
|
DXE_EXPORT(acos)
|
|
DXE_EXPORT(asin)
|
|
DXE_EXPORT(atan)
|
|
DXE_EXPORT(atan2)
|
|
DXE_EXPORT(ceil)
|
|
DXE_EXPORT(cos)
|
|
DXE_EXPORT(exp)
|
|
DXE_EXPORT(fabs)
|
|
DXE_EXPORT(floor)
|
|
DXE_EXPORT(fmod)
|
|
DXE_EXPORT(frexp)
|
|
DXE_EXPORT(ldexp)
|
|
DXE_EXPORT(log)
|
|
DXE_EXPORT(log10)
|
|
DXE_EXPORT(modf)
|
|
DXE_EXPORT(pow)
|
|
DXE_EXPORT(sin)
|
|
DXE_EXPORT(sqrt)
|
|
DXE_EXPORT(tan)
|
|
|
|
// --- errno ---
|
|
DXE_EXPORT(errno)
|
|
|
|
// --- DJGPP stdio internals ---
|
|
// The stdin/stdout/stderr macros in DJGPP expand to pointers to
|
|
// these FILE structs. Without them, any DXE that does printf()
|
|
// or fprintf(stderr, ...) gets an unresolved symbol at load time.
|
|
DXE_EXPORT(__dj_stdin)
|
|
DXE_EXPORT(__dj_stdout)
|
|
DXE_EXPORT(__dj_stderr)
|
|
|
|
// --- stb_ds (dynamic arrays / hashmaps) ---
|
|
// Internal functions called by the arrput/arrfree/hm* macros.
|
|
// Implementation lives in libtasks.a.
|
|
DXE_EXPORT(stbds_arrfreef)
|
|
DXE_EXPORT(stbds_arrgrowf)
|
|
DXE_EXPORT(stbds_hash_bytes)
|
|
DXE_EXPORT(stbds_hash_string)
|
|
DXE_EXPORT(stbds_hmdel_key)
|
|
DXE_EXPORT(stbds_hmfree_func)
|
|
DXE_EXPORT(stbds_hmget_key)
|
|
DXE_EXPORT(stbds_hmget_key_ts)
|
|
DXE_EXPORT(stbds_hmput_default)
|
|
DXE_EXPORT(stbds_hmput_key)
|
|
DXE_EXPORT(stbds_rand_seed)
|
|
DXE_EXPORT(stbds_shmode_func)
|
|
DXE_EXPORT(stbds_stralloc)
|
|
DXE_EXPORT(stbds_strreset)
|
|
|
|
// --- stb_image (image loading) ---
|
|
DXE_EXPORT(stbi_failure_reason)
|
|
DXE_EXPORT(stbi_image_free)
|
|
DXE_EXPORT(stbi_info)
|
|
DXE_EXPORT(stbi_info_from_memory)
|
|
DXE_EXPORT(stbi_load)
|
|
DXE_EXPORT(stbi_load_from_memory)
|
|
DXE_EXPORT(stbi_set_flip_vertically_on_load)
|
|
|
|
// --- stb_image_write ---
|
|
DXE_EXPORT(stbi_write_bmp)
|
|
DXE_EXPORT(stbi_write_png)
|
|
DXE_EXPORT(stbi_write_jpg)
|
|
DXE_EXPORT(stbi_write_tga)
|
|
DXE_EXPORT_END
|
|
|
|
|
|
// ============================================================
|
|
// shellRegisterExports
|
|
// ============================================================
|
|
|
|
// dlregsym registers our export table with DJGPP's DXE3 runtime.
|
|
// Must be called once before any dlopen — subsequent dlopen calls
|
|
// will search this table to resolve DXE symbol references.
|
|
static void shellRegisterExports(void) {
|
|
dlregsym(shellExportTable);
|
|
}
|
|
|
|
|
|
// ============================================================
|
|
// Public init function
|
|
// ============================================================
|
|
|
|
void shellExportInit(void) {
|
|
shellRegisterExports();
|
|
}
|