remove named shared regions

This commit is contained in:
nakst 2021-11-19 17:25:22 +00:00
parent d1aa62b26d
commit 259da06df8
13 changed files with 117 additions and 194 deletions

View File

@ -411,6 +411,7 @@ void _start() {
} else if (message->type == ES_MSG_INSTANCE_DESTROY) { } else if (message->type == ES_MSG_INSTANCE_DESTROY) {
SaveSettings(message->instanceDestroy.instance); SaveSettings(message->instanceDestroy.instance);
EsHeapFree(message->instanceDestroy.instance->previewText); EsHeapFree(message->instanceDestroy.instance->previewText);
message->instanceDestroy.instance->fonts.Free();
// TODO Remove the font added to the font database. // TODO Remove the font added to the font database.
} }
} }

View File

@ -114,6 +114,13 @@ struct EsBundle {
ptrdiff_t bytes; ptrdiff_t bytes;
}; };
struct SystemStartupDataHeader {
// TODO Make mount points and devices equal, somehow?
size_t initialMountPointCount;
size_t initialDeviceCount;
EsHandle themeCursorData;
};
const EsBundle bundleDefault = { const EsBundle bundleDefault = {
.base = (const BundleHeader *) BUNDLE_FILE_MAP_ADDRESS, .base = (const BundleHeader *) BUNDLE_FILE_MAP_ADDRESS,
.bytes = -1, .bytes = -1,
@ -1505,7 +1512,7 @@ extern "C" void _start(EsProcessStartupInformation *_startupInformation) {
ThreadInitialise(&api.firstThreadLocalStorage); ThreadInitialise(&api.firstThreadLocalStorage);
EsMessageMutexAcquire(); EsMessageMutexAcquire();
api.global = (GlobalData *) EsObjectMap(EsMemoryOpen(sizeof(GlobalData), EsLiteral("Desktop.Global"), ES_FLAGS_DEFAULT), api.global = (GlobalData *) EsObjectMap(api.startupInformation->globalDataRegion,
0, sizeof(GlobalData), desktop ? ES_MAP_OBJECT_READ_WRITE : ES_MAP_OBJECT_READ_ONLY); 0, sizeof(GlobalData), desktop ? ES_MAP_OBJECT_READ_WRITE : ES_MAP_OBJECT_READ_ONLY);
} }
@ -1539,35 +1546,28 @@ extern "C" void _start(EsProcessStartupInformation *_startupInformation) {
SettingsUpdateGlobalAndWindowManager(); SettingsUpdateGlobalAndWindowManager();
SettingsWindowColorUpdated(); SettingsWindowColorUpdated();
} else { } else {
EsHandle initialMountPointsBuffer = api.startupInformation->data.initialMountPoints; EsBuffer buffer = {};
EsHandle initialDevicesBuffer = api.startupInformation->data.initialDevices; buffer.bytes = EsConstantBufferGetSize(api.startupInformation->data.systemData);
void *_data = EsHeapAllocate(buffer.bytes, false);
EsConstantBufferRead(api.startupInformation->data.systemData, _data);
EsHandleClose(api.startupInformation->data.systemData);
buffer.in = (const uint8_t *) _data;
if (initialMountPointsBuffer) { const SystemStartupDataHeader *header = (const SystemStartupDataHeader *) EsBufferRead(&buffer, sizeof(SystemStartupDataHeader));
size_t initialMountPointCount = EsConstantBufferGetSize(initialMountPointsBuffer) / sizeof(EsMountPoint); theming.cursorData = header->themeCursorData;
EsMountPoint *initialMountPoints = (EsMountPoint *) EsHeapAllocate(initialMountPointCount * sizeof(EsMountPoint), false);
EsConstantBufferRead(initialMountPointsBuffer, initialMountPoints);
for (uintptr_t i = 0; i < initialMountPointCount; i++) { for (uintptr_t i = 0; i < header->initialMountPointCount; i++) {
NodeAddMountPoint(initialMountPoints[i].prefix, initialMountPoints[i].prefixBytes, initialMountPoints[i].base, true); const EsMountPoint *mountPoint = (const EsMountPoint *) EsBufferRead(&buffer, sizeof(EsMountPoint));
} NodeAddMountPoint(mountPoint->prefix, mountPoint->prefixBytes, mountPoint->base, true);
EsHeapFree(initialMountPoints);
EsHandleClose(initialMountPointsBuffer);
} }
if (initialDevicesBuffer) { for (uintptr_t i = 0; i < header->initialDeviceCount; i++) {
size_t initialDevicesCount = EsConstantBufferGetSize(initialDevicesBuffer) / sizeof(EsMessageDevice); const EsMessageDevice *device = (const EsMessageDevice *) EsBufferRead(&buffer, sizeof(EsMessageDevice));
EsMessageDevice *initialDevices = (EsMessageDevice *) EsHeapAllocate(initialDevicesCount * sizeof(EsMessageDevice), false); api.connectedDevices.Add(*device);
EsConstantBufferRead(initialDevicesBuffer, initialDevices);
for (uintptr_t i = 0; i < initialDevicesCount; i++) {
api.connectedDevices.Add(initialDevices[i]);
}
EsHeapFree(initialDevices);
EsHandleClose(initialDevicesBuffer);
} }
EsHeapFree(_data);
uint8_t m = DESKTOP_MSG_SYSTEM_CONFIGURATION_GET; uint8_t m = DESKTOP_MSG_SYSTEM_CONFIGURATION_GET;
EsBuffer responseBuffer = { .canGrow = true }; EsBuffer responseBuffer = { .canGrow = true };
MessageDesktop(&m, 1, ES_INVALID_HANDLE, &responseBuffer); MessageDesktop(&m, 1, ES_INVALID_HANDLE, &responseBuffer);
@ -1689,29 +1689,6 @@ EsCommand *EsCommandByID(EsInstance *_instance, uint32_t id) {
return command; return command;
} }
void EsPerformanceTimerPush() {
EsSpinlockAcquire(&api.performanceTimerStackLock);
if (api.performanceTimerStackCount < PERFORMANCE_TIMER_STACK_SIZE) {
api.performanceTimerStack[api.performanceTimerStackCount++] = EsTimeStampMs();
}
EsSpinlockRelease(&api.performanceTimerStackLock);
}
double EsPerformanceTimerPop() {
double result = 0;
EsSpinlockAcquire(&api.performanceTimerStackLock);
if (api.performanceTimerStackCount) {
double start = api.performanceTimerStack[--api.performanceTimerStackCount];
result = (EsTimeStampMs() - start) / 1000.0 /* ms to seconds */;
}
EsSpinlockRelease(&api.performanceTimerStackLock);
return result;
}
uint32_t EsIconIDFromDriveType(uint8_t driveType) { uint32_t EsIconIDFromDriveType(uint8_t driveType) {
if (driveType == ES_DRIVE_TYPE_HDD ) return ES_ICON_DRIVE_HARDDISK; if (driveType == ES_DRIVE_TYPE_HDD ) return ES_ICON_DRIVE_HARDDISK;
if (driveType == ES_DRIVE_TYPE_SSD ) return ES_ICON_DRIVE_HARDDISK_SOLIDSTATE; if (driveType == ES_DRIVE_TYPE_SSD ) return ES_ICON_DRIVE_HARDDISK_SOLIDSTATE;

View File

@ -218,9 +218,9 @@ struct {
EsWindow *wallpaperWindow; EsWindow *wallpaperWindow;
EsButton *tasksButton; EsButton *tasksButton;
bool shutdownWindowOpen;
bool setupDesktopUIComplete; bool setupDesktopUIComplete;
uint8_t installationState; uint8_t installationState;
bool desktopInspectorOpen;
EsHandle nextClipboardFile; EsHandle nextClipboardFile;
EsObjectID nextClipboardProcessID; EsObjectID nextClipboardProcessID;
@ -233,12 +233,11 @@ struct {
double totalUserTaskProgress; double totalUserTaskProgress;
#define SHUTDOWN_TIMEOUT (3000) // Maximum time to wait for applications to exit. #define SHUTDOWN_TIMEOUT (3000) // Maximum time to wait for applications to exit.
EsHandle shutdownReady; // Set when all applications have exited. EsHandle shutdownReadyEvent; // Set when all applications have exited.
bool inShutdown; bool inShutdown;
bool shutdownWindowOpen;
bool inspectorOpen; EsHandle clockReadyEvent;
EsHandle clockReady;
} desktop; } desktop;
int TaskBarButtonMessage(EsElement *element, EsMessage *message); int TaskBarButtonMessage(EsElement *element, EsMessage *message);
@ -678,8 +677,8 @@ int ProcessGlobalKeyboardShortcuts(EsElement *, EsMessage *message) {
if (ctrlOnly && scancode == ES_SCANCODE_N && !message->keyboard.repeat && !desktop.installationState) { if (ctrlOnly && scancode == ES_SCANCODE_N && !message->keyboard.repeat && !desktop.installationState) {
ApplicationInstanceCreate(APPLICATION_ID_DESKTOP_BLANK_TAB, nullptr, nullptr); ApplicationInstanceCreate(APPLICATION_ID_DESKTOP_BLANK_TAB, nullptr, nullptr);
} else if (message->keyboard.modifiers == (ES_MODIFIER_CTRL | ES_MODIFIER_FLAG) && scancode == ES_SCANCODE_D) { } else if (message->keyboard.modifiers == (ES_MODIFIER_CTRL | ES_MODIFIER_FLAG) && scancode == ES_SCANCODE_D) {
if (!desktop.inspectorOpen) { if (!desktop.desktopInspectorOpen) {
desktop.inspectorOpen = true; desktop.desktopInspectorOpen = true;
EsThreadCreate(DesktopInspectorThread, nullptr, 0); EsThreadCreate(DesktopInspectorThread, nullptr, 0);
} else { } else {
// TODO Close the inspector. // TODO Close the inspector.
@ -1322,7 +1321,7 @@ int TaskBarTasksButtonMessage(EsElement *element, EsMessage *message) {
} }
void TaskBarClockUpdateThread(EsGeneric _clock) { void TaskBarClockUpdateThread(EsGeneric _clock) {
EsWaitSingle(desktop.clockReady); EsWaitSingle(desktop.clockReadyEvent);
EsButton *clock = (EsButton *) _clock.p; EsButton *clock = (EsButton *) _clock.p;
static EsDateComponents previousTime = {}; static EsDateComponents previousTime = {};
@ -1368,7 +1367,7 @@ void Shutdown(uintptr_t action) {
} }
desktop.inShutdown = true; desktop.inShutdown = true;
desktop.shutdownReady = EsEventCreate(true); desktop.shutdownReadyEvent = EsEventCreate(true);
for (uintptr_t i = 0; i < desktop.allApplicationInstances.Length(); i++) { for (uintptr_t i = 0; i < desktop.allApplicationInstances.Length(); i++) {
// Tell all applications to close. // Tell all applications to close.
@ -1377,7 +1376,7 @@ void Shutdown(uintptr_t action) {
EsThreadCreate([] (EsGeneric action) { EsThreadCreate([] (EsGeneric action) {
// Shut down either when all applications exit, or after the timeout. // Shut down either when all applications exit, or after the timeout.
EsWait(&desktop.shutdownReady, 1, SHUTDOWN_TIMEOUT); EsWait(&desktop.shutdownReadyEvent, 1, SHUTDOWN_TIMEOUT);
EsSyscall(ES_SYSCALL_SHUTDOWN, action.u, 0, 0, 0); EsSyscall(ES_SYSCALL_SHUTDOWN, action.u, 0, 0, 0);
}, nullptr, action); }, nullptr, action);
} }
@ -1722,6 +1721,7 @@ bool ApplicationInstanceStart(int64_t applicationID, _EsApplicationStartupInform
arguments.executable = executableNode.handle; arguments.executable = executableNode.handle;
arguments.permissions = ES_PERMISSION_WINDOW_MANAGER; arguments.permissions = ES_PERMISSION_WINDOW_MANAGER;
SystemStartupDataHeader header = {};
Array<EsMountPoint> initialMountPoints = {}; Array<EsMountPoint> initialMountPoints = {};
Array<EsMessageDevice> initialDevices = {}; Array<EsMessageDevice> initialDevices = {};
Array<EsHandle> handleDuplicateList = {}; Array<EsHandle> handleDuplicateList = {};
@ -1790,13 +1790,19 @@ bool ApplicationInstanceStart(int64_t applicationID, _EsApplicationStartupInform
} }
} }
arguments.data.initialMountPoints = EsConstantBufferCreate(initialMountPoints.array, initialMountPoints.Length() * sizeof(EsMountPoint), ES_CURRENT_PROCESS); EsBuffer buffer = { .canGrow = true };
handleDuplicateList.Add(arguments.data.initialMountPoints); header.initialMountPointCount = initialMountPoints.Length();
header.initialDeviceCount = initialDevices.Length();
header.themeCursorData = theming.cursorData;
EsBufferWrite(&buffer, &header, sizeof(header));
EsBufferWrite(&buffer, initialMountPoints.array, sizeof(EsMountPoint) * header.initialMountPointCount);
EsBufferWrite(&buffer, initialDevices.array, sizeof(EsMessageDevice) * header.initialDeviceCount);
arguments.data.systemData = EsConstantBufferCreate(buffer.out, buffer.position, ES_CURRENT_PROCESS);
handleDuplicateList.Add(arguments.data.systemData);
handleModeDuplicateList.Add(0); handleModeDuplicateList.Add(0);
handleDuplicateList.Add(header.themeCursorData);
arguments.data.initialDevices = EsConstantBufferCreate(initialDevices.array, initialDevices.Length() * sizeof(EsMessageDevice), ES_CURRENT_PROCESS);
handleDuplicateList.Add(arguments.data.initialDevices);
handleModeDuplicateList.Add(0); handleModeDuplicateList.Add(0);
EsHeapFree(buffer.out);
arguments.handles = handleDuplicateList.array; arguments.handles = handleDuplicateList.array;
arguments.handleModes = handleModeDuplicateList.array; arguments.handleModes = handleModeDuplicateList.array;
@ -1806,22 +1812,8 @@ bool ApplicationInstanceStart(int64_t applicationID, _EsApplicationStartupInform
error = EsProcessCreate(&arguments, &information); error = EsProcessCreate(&arguments, &information);
EsHandleClose(arguments.executable); EsHandleClose(arguments.executable);
initialMountPoints.Free(); if (settingsNode.handle) EsHandleClose(settingsNode.handle);
initialDevices.Free(); if (arguments.data.systemData) EsHandleClose(arguments.data.systemData);
handleDuplicateList.Free();
handleModeDuplicateList.Free();
if (settingsNode.handle) {
EsHandleClose(settingsNode.handle);
}
if (arguments.data.initialMountPoints) {
EsHandleClose(arguments.data.initialMountPoints);
}
if (arguments.data.initialDevices) {
EsHandleClose(arguments.data.initialDevices);
}
if (!ES_CHECK_ERROR(error)) { if (!ES_CHECK_ERROR(error)) {
EsHandleClose(information.mainThread.handle); EsHandleClose(information.mainThread.handle);
@ -2038,7 +2030,7 @@ void ApplicationProcessTerminated(EsObjectID pid) {
} }
if (!desktop.allApplicationProcesses.Length() && desktop.inShutdown) { if (!desktop.allApplicationProcesses.Length() && desktop.inShutdown) {
EsEventSet(desktop.shutdownReady); EsEventSet(desktop.shutdownReadyEvent);
} }
} }
@ -2582,18 +2574,6 @@ void DesktopSetup() {
desktop.installationState = EsSystemConfigurationReadInteger(EsLiteral("general"), EsLiteral("installation_state")); desktop.installationState = EsSystemConfigurationReadInteger(EsLiteral("general"), EsLiteral("installation_state"));
} }
// Load the theme bitmap.
if (!desktop.setupDesktopUIComplete) {
size_t cursorsBitmapBytes;
const void *cursorsBitmap = EsBundleFind(&bundleDesktop, EsLiteral("Cursors.png"), &cursorsBitmapBytes);
EsHandle handle = EsMemoryOpen(ES_THEME_CURSORS_WIDTH * ES_THEME_CURSORS_HEIGHT * 4, EsLiteral(ES_THEME_CURSORS_NAME), ES_FLAGS_DEFAULT);
void *destination = EsObjectMap(handle, 0, ES_THEME_CURSORS_WIDTH * ES_THEME_CURSORS_HEIGHT * 4, ES_MAP_OBJECT_READ_WRITE);
LoadImage(cursorsBitmap, cursorsBitmapBytes, destination, ES_THEME_CURSORS_WIDTH, ES_THEME_CURSORS_HEIGHT, true);
EsObjectUnmap(destination);
EsHandleClose(handle);
}
// Create the wallpaper window. // Create the wallpaper window.
{ {
@ -3069,8 +3049,8 @@ void EmbeddedWindowDestroyed(EsObjectID id) {
} }
void DesktopSendMessage(EsMessage *message) { void DesktopSendMessage(EsMessage *message) {
if (!desktop.clockReady) { if (!desktop.clockReadyEvent) {
desktop.clockReady = EsEventCreate(false); desktop.clockReadyEvent = EsEventCreate(false);
} }
if (message->type == ES_MSG_EMBEDDED_WINDOW_DESTROYED) { if (message->type == ES_MSG_EMBEDDED_WINDOW_DESTROYED) {
@ -3125,7 +3105,7 @@ void DesktopSendMessage(EsMessage *message) {
api.global->schedulerTimeOffset = (linear ?: DateToLinear(&reading)) api.global->schedulerTimeOffset = (linear ?: DateToLinear(&reading))
- api.global->schedulerTimeMs - api.global->schedulerTimeMs
+ EsSystemConfigurationReadInteger(EsLiteral("general"), EsLiteral("clock_offset_ms"), 0); + EsSystemConfigurationReadInteger(EsLiteral("general"), EsLiteral("clock_offset_ms"), 0);
EsEventSet(desktop.clockReady); EsEventSet(desktop.clockReadyEvent);
} }
} }
} else if (message->type == ES_MSG_UNREGISTER_FILE_SYSTEM || message->type == ES_MSG_DEVICE_DISCONNECTED) { } else if (message->type == ES_MSG_UNREGISTER_FILE_SYSTEM || message->type == ES_MSG_DEVICE_DISCONNECTED) {

View File

@ -1444,7 +1444,7 @@ void EsElement::InternalPaint(EsPainter *painter, int paintFlags) {
} }
} }
if (state & UI_STATE_INSPECTING) EsPerformanceTimerPush(); EsPerformanceTimerPush();
// Get the interpolated style. // Get the interpolated style.
@ -2485,7 +2485,7 @@ void EsElement::InternalMove(int _width, int _height, int _offsetX, int _offsetY
} else { } else {
// Tell the element to layout its contents. // Tell the element to layout its contents.
if (state & UI_STATE_INSPECTING) EsPerformanceTimerPush(); EsPerformanceTimerPush();
EsMessage m = { ES_MSG_LAYOUT }; EsMessage m = { ES_MSG_LAYOUT };
m.layout.sizeChanged = hasSizeChanged; m.layout.sizeChanged = hasSizeChanged;
EsMessageSend(this, &m); EsMessageSend(this, &m);

View File

@ -360,7 +360,6 @@ define ES_REJECTED (-2)
define ES_LIST_VIEW_COLUMN_SORT_ASCENDING (1) define ES_LIST_VIEW_COLUMN_SORT_ASCENDING (1)
define ES_LIST_VIEW_COLUMN_SORT_DESCENDING (2) define ES_LIST_VIEW_COLUMN_SORT_DESCENDING (2)
define ES_SHARED_MEMORY_NAME_MAX_LENGTH (32)
define ES_MAP_OBJECT_ALL (0) define ES_MAP_OBJECT_ALL (0)
define ES_TEXT_H_LEFT (1 << 0) define ES_TEXT_H_LEFT (1 << 0)
@ -408,9 +407,6 @@ define _ES_NODE_NO_WRITE_BASE (0x080000)
define ES_DIRECTORY_CHILDREN_UNKNOWN ((EsFileOffsetDifference) (-1)) define ES_DIRECTORY_CHILDREN_UNKNOWN ((EsFileOffsetDifference) (-1))
define ES_MEMORY_OPEN_FAIL_IF_FOUND (0x1000)
define ES_MEMORY_OPEN_FAIL_IF_NOT_FOUND (0x2000)
define ES_MAP_OBJECT_READ_WRITE (0) define ES_MAP_OBJECT_READ_WRITE (0)
define ES_MAP_OBJECT_READ_ONLY (1) define ES_MAP_OBJECT_READ_ONLY (1)
define ES_MAP_OBJECT_COPY_ON_WRITE (2) define ES_MAP_OBJECT_COPY_ON_WRITE (2)
@ -639,10 +635,6 @@ define ES_WINDOW_SOLID_TRUE (1 << 0)
define ES_WINDOW_SOLID_NO_ACTIVATE (1 << 1) define ES_WINDOW_SOLID_NO_ACTIVATE (1 << 1)
define ES_WINDOW_SOLID_NO_BRING_TO_FRONT (1 << 2) define ES_WINDOW_SOLID_NO_BRING_TO_FRONT (1 << 2)
define ES_THEME_CURSORS_WIDTH (264)
define ES_THEME_CURSORS_HEIGHT (128)
define ES_THEME_CURSORS_NAME "Desktop.ThemeCursors"
define ES_TEXTBOX_MOVE_CARET_SINGLE (2) define ES_TEXTBOX_MOVE_CARET_SINGLE (2)
define ES_TEXTBOX_MOVE_CARET_WORD (3) define ES_TEXTBOX_MOVE_CARET_WORD (3)
define ES_TEXTBOX_MOVE_CARET_LINE (4) define ES_TEXTBOX_MOVE_CARET_LINE (4)
@ -771,7 +763,6 @@ private enum EsSyscallType {
ES_SYSCALL_MEMORY_ALLOCATE ES_SYSCALL_MEMORY_ALLOCATE
ES_SYSCALL_MEMORY_FREE ES_SYSCALL_MEMORY_FREE
ES_SYSCALL_MEMORY_MAP_OBJECT ES_SYSCALL_MEMORY_MAP_OBJECT
ES_SYSCALL_MEMORY_OPEN
ES_SYSCALL_MEMORY_COMMIT ES_SYSCALL_MEMORY_COMMIT
ES_SYSCALL_MEMORY_FAULT_RANGE ES_SYSCALL_MEMORY_FAULT_RANGE
ES_SYSCALL_MEMORY_GET_AVAILABLE ES_SYSCALL_MEMORY_GET_AVAILABLE
@ -1286,7 +1277,10 @@ struct EsMountPoint {
}; };
struct EsProcessCreateData { struct EsProcessCreateData {
EsHandle environment, initialMountPoints, initialDevices; EsHandle systemData;
EsHandle subsystemData;
EsGeneric userData;
uint8_t subsystemID;
}; };
struct EsProcessStartupInformation { struct EsProcessStartupInformation {
@ -1296,6 +1290,7 @@ struct EsProcessStartupInformation {
uintptr_t tlsImageBytes; uintptr_t tlsImageBytes;
uintptr_t tlsBytes; // All bytes after the image are to be zeroed. uintptr_t tlsBytes; // All bytes after the image are to be zeroed.
uintptr_t timeStampTicksPerMs; uintptr_t timeStampTicksPerMs;
EsHandle globalDataRegion;
EsProcessCreateData data; EsProcessCreateData data;
}; };
@ -2091,6 +2086,7 @@ function_not_in_kernel void *EsHeapReallocate(void *oldAddress, size_t newAlloca
function void EsHeapValidate(); function void EsHeapValidate();
function EsHandle EsMemoryCreateShareableRegion(size_t bytes);
function bool EsMemoryCommit(void *pointer, size_t bytes); function bool EsMemoryCommit(void *pointer, size_t bytes);
function int EsMemoryCompare(const void *a, const void *b, size_t bytes); function int EsMemoryCompare(const void *a, const void *b, size_t bytes);
function void EsMemoryCopy(void *destination, const void *source, size_t bytes); function void EsMemoryCopy(void *destination, const void *source, size_t bytes);
@ -2099,7 +2095,6 @@ function bool EsMemoryDecommit(void *pointer, size_t bytes); // May fail in low-
function void EsMemoryFaultRange(const void *pointer, size_t bytes, uint32_t flags = ES_FLAGS_DEFAULT); // Simulate a page fault in each page in the range. function void EsMemoryFaultRange(const void *pointer, size_t bytes, uint32_t flags = ES_FLAGS_DEFAULT); // Simulate a page fault in each page in the range.
function void EsMemoryFill(void *from, void *to, uint8_t byte); function void EsMemoryFill(void *from, void *to, uint8_t byte);
function void EsMemoryMove(void *_start, void *_end, intptr_t amount, bool zeroEmptySpace); function void EsMemoryMove(void *_start, void *_end, intptr_t amount, bool zeroEmptySpace);
function EsHandle EsMemoryOpen(size_t size, STRING name, unsigned flags);
function void *EsMemoryReserve(size_t size, EsMemoryProtection protection = ES_MEMORY_PROTECTION_READ_WRITE, uint32_t flags = ES_MEMORY_RESERVE_COMMIT_ALL); function void *EsMemoryReserve(size_t size, EsMemoryProtection protection = ES_MEMORY_PROTECTION_READ_WRITE, uint32_t flags = ES_MEMORY_RESERVE_COMMIT_ALL);
function EsHandle EsMemoryShare(EsHandle sharedMemoryRegion, EsHandle targetProcess, bool readOnly); function EsHandle EsMemoryShare(EsHandle sharedMemoryRegion, EsHandle targetProcess, bool readOnly);
function uint8_t EsMemorySumBytes(uint8_t *data, size_t bytes); function uint8_t EsMemorySumBytes(uint8_t *data, size_t bytes);
@ -2246,8 +2241,6 @@ function void EsTimerCancel(EsTimer id);
function void EsSleep(uint64_t milliseconds); function void EsSleep(uint64_t milliseconds);
function uintptr_t EsWait(EsHandle *objects, size_t objectCount, uintptr_t timeoutMs); function uintptr_t EsWait(EsHandle *objects, size_t objectCount, uintptr_t timeoutMs);
function void EsPerformanceTimerPush(); // Stack size should not exceed 100 values.
function double EsPerformanceTimerPop(); // Returns value in seconds.
function double EsTimeStampMs(); // Current value of the performance timer, in ms. function double EsTimeStampMs(); // Current value of the performance timer, in ms.
function void EsDateNowUTC(EsDateComponents *date); // Don't rely on the accuracy of the millisecond field. function void EsDateNowUTC(EsDateComponents *date); // Don't rely on the accuracy of the millisecond field.

View File

@ -188,6 +188,9 @@ ES_EXTERN_C uintptr_t _APISyscall(uintptr_t argument0, uintptr_t argument1, uint
#define ES_PTR64_LS32(x) ((uint32_t) (x)) #define ES_PTR64_LS32(x) ((uint32_t) (x))
#endif #endif
#define EsPerformanceTimerPush() double _performanceTimerStart = EsTimeStampMs()
#define EsPerformanceTimerPop() ((EsTimeStampMs() - _performanceTimerStart) / 1000.0)
// --------- Algorithms: // --------- Algorithms:
#define ES_MACRO_SORT(_name, _type, _compar, _contextType) void _name(_type *base, size_t nmemb, _contextType context) { \ #define ES_MACRO_SORT(_name, _type, _compar, _contextType) void _name(_type *base, size_t nmemb, _contextType context) { \
@ -374,6 +377,9 @@ extern "C" void *EsBufferWrite(EsBuffer *buffer, const void *source, size_t writ
#define DESKTOP_MESSAGE_SIZE_LIMIT (0x4000) #define DESKTOP_MESSAGE_SIZE_LIMIT (0x4000)
#define ES_THEME_CURSORS_WIDTH (264)
#define ES_THEME_CURSORS_HEIGHT (128)
#endif #endif
// --------- CRT function macros: // --------- CRT function macros:

View File

@ -29,6 +29,10 @@ void *EsMemoryReserve(size_t size, EsMemoryProtection protection, uint32_t flags
} }
} }
EsHandle EsMemoryCreateShareableRegion(size_t bytes) {
return EsSyscall(ES_SYSCALL_MEMORY_ALLOCATE, bytes, 0, 0, 1);
}
void EsMemoryUnreserve(void *address, size_t size) { void EsMemoryUnreserve(void *address, size_t size) {
EsSyscall(ES_SYSCALL_MEMORY_FREE, (uintptr_t) address, size, 0, 0); EsSyscall(ES_SYSCALL_MEMORY_FREE, (uintptr_t) address, size, 0, 0);
} }
@ -291,11 +295,6 @@ EsError EsFileCopy(const char *source, ptrdiff_t sourceBytes, const char *destin
return error; return error;
} }
EsHandle EsMemoryOpen(size_t size, const char *name, ptrdiff_t nameLength, unsigned flags) {
if (nameLength == -1) nameLength = EsCStringLength(name);
return EsSyscall(ES_SYSCALL_MEMORY_OPEN, size, (uintptr_t) name, nameLength, flags);
}
EsHandle EsMemoryShare(EsHandle sharedMemoryRegion, EsHandle targetProcess, bool readOnly) { EsHandle EsMemoryShare(EsHandle sharedMemoryRegion, EsHandle targetProcess, bool readOnly) {
return EsSyscall(ES_SYSCALL_HANDLE_SHARE, sharedMemoryRegion, targetProcess, readOnly, 0); return EsSyscall(ES_SYSCALL_HANDLE_SHARE, sharedMemoryRegion, targetProcess, readOnly, 0);
} }

View File

@ -357,6 +357,7 @@ struct {
EsBuffer system; EsBuffer system;
const ThemeHeader *header; const ThemeHeader *header;
EsPaintTarget cursors; EsPaintTarget cursors;
EsHandle cursorData;
float scale; float scale;
HashStore<UIStyleKey, struct UIStyle *> loadedStyles; HashStore<UIStyleKey, struct UIStyle *> loadedStyles;
uint32_t windowColors[6]; uint32_t windowColors[6];
@ -1307,11 +1308,19 @@ bool ThemeInitialise() {
theming.scale = api.global->uiScale; theming.scale = api.global->uiScale;
if (!theming.cursorData) {
size_t cursorsBitmapBytes;
const void *cursorsBitmap = EsBundleFind(&bundleDesktop, EsLiteral("Cursors.png"), &cursorsBitmapBytes);
theming.cursorData = EsMemoryCreateShareableRegion(ES_THEME_CURSORS_WIDTH * ES_THEME_CURSORS_HEIGHT * 4);
void *destination = EsObjectMap(theming.cursorData, 0, ES_THEME_CURSORS_WIDTH * ES_THEME_CURSORS_HEIGHT * 4, ES_MAP_OBJECT_READ_WRITE);
LoadImage(cursorsBitmap, cursorsBitmapBytes, destination, ES_THEME_CURSORS_WIDTH, ES_THEME_CURSORS_HEIGHT, true);
EsObjectUnmap(destination);
}
theming.cursors.width = ES_THEME_CURSORS_WIDTH; theming.cursors.width = ES_THEME_CURSORS_WIDTH;
theming.cursors.height = ES_THEME_CURSORS_HEIGHT; theming.cursors.height = ES_THEME_CURSORS_HEIGHT;
theming.cursors.stride = ES_THEME_CURSORS_WIDTH * 4; theming.cursors.stride = ES_THEME_CURSORS_WIDTH * 4;
theming.cursors.bits = EsObjectMap(EsMemoryOpen(theming.cursors.height * theming.cursors.stride, EsLiteral(ES_THEME_CURSORS_NAME), 0), theming.cursors.bits = EsObjectMap(theming.cursorData, 0, ES_MAP_OBJECT_ALL, ES_MAP_OBJECT_READ_ONLY);
0, ES_MAP_OBJECT_ALL, ES_MAP_OBJECT_READ_ONLY);
theming.cursors.fullAlpha = true; theming.cursors.fullAlpha = true;
theming.cursors.readOnly = true; theming.cursors.readOnly = true;

View File

@ -4,7 +4,8 @@
#ifndef IMPLEMENTATION #ifndef IMPLEMENTATION
#define CURSOR_SHADOW_OFFSET (1) #define CURSOR_SHADOW_OFFSET_X (0)
#define CURSOR_SHADOW_OFFSET_Y (1)
struct Surface : EsPaintTarget { struct Surface : EsPaintTarget {
bool Resize(size_t newResX, size_t newResY, uint32_t clearColor = 0, bool copyOldBits = false); bool Resize(size_t newResX, size_t newResY, uint32_t clearColor = 0, bool copyOldBits = false);
@ -502,8 +503,8 @@ void Surface::CreateCursorShadow(Surface *temporary) {
} }
} }
for (int32_t i = 0; i < (int32_t) height - CURSOR_SHADOW_OFFSET; i++) { for (int32_t i = 0; i < (int32_t) height - CURSOR_SHADOW_OFFSET_Y; i++) {
for (int32_t j = 0; j < (int32_t) width - CURSOR_SHADOW_OFFSET; j++) { for (int32_t j = 0; j < (int32_t) width - CURSOR_SHADOW_OFFSET_X; j++) {
uint32_t s = 0; uint32_t s = 0;
for (int32_t k = 0; k < 5; k++) { for (int32_t k = 0; k < 5; k++) {
@ -514,7 +515,7 @@ void Surface::CreateCursorShadow(Surface *temporary) {
} }
} }
uint32_t *out = &bits1[(i + CURSOR_SHADOW_OFFSET) * stride / 4 + (j + CURSOR_SHADOW_OFFSET)]; uint32_t *out = &bits1[(i + CURSOR_SHADOW_OFFSET_Y) * stride / 4 + (j + CURSOR_SHADOW_OFFSET_X)];
*out = EsColorBlend((s >> 16) << 24, *out, true); *out = EsColorBlend((s >> 16) << 24, *out, true);
} }
} }

View File

@ -137,8 +137,6 @@ struct MMSharedRegion {
size_t sizeBytes; size_t sizeBytes;
volatile size_t handles; volatile size_t handles;
KMutex mutex; KMutex mutex;
LinkedItem<MMSharedRegion> namedItem;
char cName[ES_SHARED_MEMORY_NAME_MAX_LENGTH + 1];
void *data; void *data;
}; };
@ -274,8 +272,6 @@ bool MMDecommitRange(MMSpace *space, MMRegion *region, uintptr_t offset, size_t
uintptr_t MMPhysicalAllocate(unsigned flags, uintptr_t count, uintptr_t align, uintptr_t below); uintptr_t MMPhysicalAllocate(unsigned flags, uintptr_t count, uintptr_t align, uintptr_t below);
void MMInitialise(); void MMInitialise();
MMSharedRegion *MMSharedCreateRegion(size_t sizeBytes, bool fixed, uintptr_t below); MMSharedRegion *MMSharedCreateRegion(size_t sizeBytes, bool fixed, uintptr_t below);
MMSharedRegion *MMSharedOpenRegion(const char *name, size_t nameBytes,
size_t fallbackSizeBytes /* If the region doesn't exist, the size it should be created with. If 0, it'll fail. */, uint64_t flags);
MMRegion *MMFindAndPinRegion(MMSpace *space, uintptr_t address, uintptr_t size); MMRegion *MMFindAndPinRegion(MMSpace *space, uintptr_t address, uintptr_t size);
void MMUnpinRegion(MMSpace *space, MMRegion *region); void MMUnpinRegion(MMSpace *space, MMRegion *region);
void MMSpaceDestroy(MMSpace *space); void MMSpaceDestroy(MMSpace *space);
@ -306,10 +302,8 @@ PMM pmm;
MMRegion *mmCoreRegions = (MMRegion *) MM_CORE_REGIONS_START; MMRegion *mmCoreRegions = (MMRegion *) MM_CORE_REGIONS_START;
size_t mmCoreRegionCount, mmCoreRegionArrayCommit; size_t mmCoreRegionCount, mmCoreRegionArrayCommit;
LinkedList<MMSharedRegion> mmNamedSharedRegions; MMSharedRegion *mmGlobalDataRegion, *mmAPITableRegion;
KMutex mmNamedSharedRegionsMutex; GlobalData *mmGlobalData; // Shared with all processes.
GlobalData *globalData; // Shared with all processes.
// Code! // Code!
@ -1401,38 +1395,6 @@ bool MMSharedResizeRegion(MMSharedRegion *region, size_t sizeBytes) {
return true; return true;
} }
MMSharedRegion *MMSharedOpenRegion(const char *name, size_t nameBytes, size_t fallbackSizeBytes, uint64_t flags) {
if (nameBytes > ES_SHARED_MEMORY_NAME_MAX_LENGTH) return nullptr;
KMutexAcquire(&mmNamedSharedRegionsMutex);
EsDefer(KMutexRelease(&mmNamedSharedRegionsMutex));
LinkedItem<MMSharedRegion> *item = mmNamedSharedRegions.firstItem;
while (item) {
MMSharedRegion *region = item->thisItem;
if (EsCStringLength(region->cName) == nameBytes && 0 == EsMemoryCompare(region->cName, name, nameBytes)) {
if (flags & ES_MEMORY_OPEN_FAIL_IF_FOUND) return nullptr;
OpenHandleToObject(region, KERNEL_OBJECT_SHMEM);
return region;
}
item = item->nextItem;
}
if (flags & ES_MEMORY_OPEN_FAIL_IF_NOT_FOUND) return nullptr;
MMSharedRegion *region = MMSharedCreateRegion(fallbackSizeBytes);
if (!region) return nullptr;
EsMemoryCopy(region->cName, name, nameBytes);
region->namedItem.thisItem = region;
mmNamedSharedRegions.InsertEnd(&region->namedItem);
return region;
}
MMSharedRegion *MMSharedCreateRegion(size_t sizeBytes, bool fixed, uintptr_t below) { MMSharedRegion *MMSharedCreateRegion(size_t sizeBytes, bool fixed, uintptr_t below) {
if (!sizeBytes) return nullptr; if (!sizeBytes) return nullptr;
@ -2303,11 +2265,12 @@ void MMInitialise() {
} }
{ {
// Create the global data shared region. // Create the global data shared region, and the API table region.
MMSharedRegion *region = MMSharedOpenRegion(EsLiteral("Desktop.Global"), sizeof(GlobalData), ES_FLAGS_DEFAULT); mmAPITableRegion = MMSharedCreateRegion(0xF000, false, 0);
globalData = (GlobalData *) MMMapShared(kernelMMSpace, region, 0, sizeof(GlobalData), MM_REGION_FIXED); mmGlobalDataRegion = MMSharedCreateRegion(sizeof(GlobalData), false, 0);
MMFaultRange((uintptr_t) globalData, sizeof(GlobalData), MM_HANDLE_PAGE_FAULT_FOR_SUPERVISOR); mmGlobalData = (GlobalData *) MMMapShared(kernelMMSpace, mmGlobalDataRegion, 0, sizeof(GlobalData), MM_REGION_FIXED);
MMFaultRange((uintptr_t) mmGlobalData, sizeof(GlobalData), MM_HANDLE_PAGE_FAULT_FOR_SUPERVISOR);
} }
} }

View File

@ -738,11 +738,9 @@ void ProcessLoadExecutable() {
if (success) { if (success) {
// We "link" the API by putting its table of function pointers at a known address. // We "link" the API by putting its table of function pointers at a known address.
MMSharedRegion *tableRegion = MMSharedOpenRegion(EsLiteral("Desktop.APITable"), 0xF000, ES_FLAGS_DEFAULT);
// TODO Write protection. // TODO Write protection.
if (!MMMapShared(thisProcess->vmm, tableRegion, 0, 0xF000, ES_FLAGS_DEFAULT, ES_API_BASE)) { if (!MMMapShared(thisProcess->vmm, mmAPITableRegion, 0, mmAPITableRegion->sizeBytes, ES_FLAGS_DEFAULT, ES_API_BASE)) {
success = false; success = false;
} }
} }
@ -763,6 +761,12 @@ void ProcessLoadExecutable() {
startupInformation->tlsImageBytes = application.tlsImageBytes; startupInformation->tlsImageBytes = application.tlsImageBytes;
startupInformation->tlsBytes = application.tlsBytes; startupInformation->tlsBytes = application.tlsBytes;
startupInformation->timeStampTicksPerMs = timeStampTicksPerMs; startupInformation->timeStampTicksPerMs = timeStampTicksPerMs;
if (OpenHandleToObject(mmGlobalDataRegion, KERNEL_OBJECT_SHMEM, ES_FLAGS_DEFAULT)) {
// TODO Write protection.
startupInformation->globalDataRegion = thisProcess->handleTable.OpenHandle(mmGlobalDataRegion, ES_FLAGS_DEFAULT, KERNEL_OBJECT_SHMEM);
}
EsMemoryCopy(&startupInformation->data, &thisProcess->data, sizeof(EsProcessCreateData)); EsMemoryCopy(&startupInformation->data, &thisProcess->data, sizeof(EsProcessCreateData));
} }
} }
@ -1135,7 +1139,7 @@ void Scheduler::Yield(InterruptContext *context) {
if (!local->processorID) { if (!local->processorID) {
// Update the scheduler's time. // Update the scheduler's time.
timeMs = ArchGetTimeMs(); timeMs = ArchGetTimeMs();
globalData->schedulerTimeMs = timeMs; mmGlobalData->schedulerTimeMs = timeMs;
// Notify the necessary timers. // Notify the necessary timers.
KSpinlockAcquire(&activeTimersSpinlock); KSpinlockAcquire(&activeTimersSpinlock);

View File

@ -59,12 +59,19 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_PRINT) {
} }
SYSCALL_IMPLEMENT(ES_SYSCALL_MEMORY_ALLOCATE) { SYSCALL_IMPLEMENT(ES_SYSCALL_MEMORY_ALLOCATE) {
EsMemoryProtection protection = (EsMemoryProtection) argument2; if (argument3) {
uint32_t flags = MM_REGION_USER; if (argument0 > ES_SHARED_MEMORY_MAXIMUM_SIZE) SYSCALL_RETURN(ES_FATAL_ERROR_OUT_OF_RANGE, true);
if (protection == ES_MEMORY_PROTECTION_READ_ONLY) flags |= MM_REGION_READ_ONLY; MMSharedRegion *region = MMSharedCreateRegion(argument0, false, 0);
if (protection == ES_MEMORY_PROTECTION_EXECUTABLE) flags |= MM_REGION_EXECUTABLE; if (!region) SYSCALL_RETURN(ES_ERROR_INSUFFICIENT_RESOURCES, false);
uintptr_t address = (uintptr_t) MMStandardAllocate(currentVMM, argument0, flags, nullptr, argument1 & ES_MEMORY_RESERVE_COMMIT_ALL); SYSCALL_RETURN(currentProcess->handleTable.OpenHandle(region, 0, KERNEL_OBJECT_SHMEM), false);
SYSCALL_RETURN(address, false); } else {
EsMemoryProtection protection = (EsMemoryProtection) argument2;
uint32_t flags = MM_REGION_USER;
if (protection == ES_MEMORY_PROTECTION_READ_ONLY) flags |= MM_REGION_READ_ONLY;
if (protection == ES_MEMORY_PROTECTION_EXECUTABLE) flags |= MM_REGION_EXECUTABLE;
uintptr_t address = (uintptr_t) MMStandardAllocate(currentVMM, argument0, flags, nullptr, argument1 & ES_MEMORY_RESERVE_COMMIT_ALL);
SYSCALL_RETURN(address, false);
}
} }
SYSCALL_IMPLEMENT(ES_SYSCALL_MEMORY_FREE) { SYSCALL_IMPLEMENT(ES_SYSCALL_MEMORY_FREE) {
@ -536,21 +543,6 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_THREAD_CREATE) {
SYSCALL_RETURN(ES_SUCCESS, false); SYSCALL_RETURN(ES_SUCCESS, false);
} }
SYSCALL_IMPLEMENT(ES_SYSCALL_MEMORY_OPEN) {
if (argument0 > ES_SHARED_MEMORY_MAXIMUM_SIZE) SYSCALL_RETURN(ES_FATAL_ERROR_OUT_OF_RANGE, true);
if (argument1 && !argument2) SYSCALL_RETURN(ES_FATAL_ERROR_INVALID_BUFFER, true);
if (argument2 > ES_SHARED_MEMORY_NAME_MAX_LENGTH) SYSCALL_RETURN(ES_FATAL_ERROR_OUT_OF_RANGE, true);
char *name;
if (argument2 > SYSCALL_BUFFER_LIMIT) SYSCALL_RETURN(ES_FATAL_ERROR_INVALID_BUFFER, true);
SYSCALL_READ_HEAP(name, argument1, argument2);
MMSharedRegion *region = MMSharedOpenRegion(name, argument2, argument0, argument3);
if (!region) SYSCALL_RETURN(ES_INVALID_HANDLE, false);
SYSCALL_RETURN(currentProcess->handleTable.OpenHandle(region, 0, KERNEL_OBJECT_SHMEM), false);
}
SYSCALL_IMPLEMENT(ES_SYSCALL_MEMORY_MAP_OBJECT) { SYSCALL_IMPLEMENT(ES_SYSCALL_MEMORY_MAP_OBJECT) {
SYSCALL_HANDLE_2(argument0, (KernelObjectType) (KERNEL_OBJECT_SHMEM | KERNEL_OBJECT_NODE), object); SYSCALL_HANDLE_2(argument0, (KernelObjectType) (KERNEL_OBJECT_SHMEM | KERNEL_OBJECT_NODE), object);
@ -908,8 +900,8 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_WINDOW_SET_CURSOR) {
windowManager.cursorImageOffsetY = (int8_t) ((argument2 >> 8) & 0xFF); windowManager.cursorImageOffsetY = (int8_t) ((argument2 >> 8) & 0xFF);
windowManager.cursorShadow = argument3 & (1 << 30); windowManager.cursorShadow = argument3 & (1 << 30);
int width = imageWidth + CURSOR_SHADOW_OFFSET; int width = imageWidth + CURSOR_SHADOW_OFFSET_X;
int height = imageHeight + CURSOR_SHADOW_OFFSET; int height = imageHeight + CURSOR_SHADOW_OFFSET_Y;
if (windowManager.cursorSurface.Resize(width, height) if (windowManager.cursorSurface.Resize(width, height)
&& windowManager.cursorSwap.Resize(width, height) && windowManager.cursorSwap.Resize(width, height)

View File

@ -87,7 +87,7 @@ EsMemoryCopyReverse=85
EsMemoryFill=86 EsMemoryFill=86
EsINIPeek=87 EsINIPeek=87
EsMemoryMove=88 EsMemoryMove=88
EsMemoryOpen=89 EsMemoryCreateShareableRegion=89
EsMemoryShare=90 EsMemoryShare=90
EsMemorySumBytes=91 EsMemorySumBytes=91
EsMemoryZero=92 EsMemoryZero=92
@ -140,8 +140,6 @@ EsInstanceClose=138
EsMutexAcquire=140 EsMutexAcquire=140
EsMutexDestroy=141 EsMutexDestroy=141
EsMutexRelease=142 EsMutexRelease=142
EsPerformanceTimerPush=143
EsPerformanceTimerPop=144
EsSchedulerYield=145 EsSchedulerYield=145
EsSleep=146 EsSleep=146
EsSpinlockAcquire=147 EsSpinlockAcquire=147