mirror of https://gitlab.com/nakst/essence
low memory fixes
This commit is contained in:
parent
0c50335c62
commit
10b259ca66
118
desktop/api.cpp
118
desktop/api.cpp
|
@ -287,14 +287,20 @@ EsSystemConfigurationItem *SystemConfigurationGetItem(EsSystemConfigurationGroup
|
|||
if (createIfNeeded) {
|
||||
EsSystemConfigurationItem item = {};
|
||||
item.key = (char *) EsHeapAllocate(keyBytes, false);
|
||||
if (!item.key) return nullptr;
|
||||
item.keyBytes = keyBytes;
|
||||
EsMemoryCopy(item.key, key, keyBytes);
|
||||
|
||||
Array<EsSystemConfigurationItem> items = { group->items };
|
||||
EsSystemConfigurationItem *_item = items.Add(item);
|
||||
group->items = items.array;
|
||||
group->itemCount++;
|
||||
return _item;
|
||||
|
||||
if (_item) {
|
||||
group->itemCount++;
|
||||
return _item;
|
||||
} else {
|
||||
EsHeapFree(item.key);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -312,9 +318,16 @@ EsSystemConfigurationGroup *SystemConfigurationGetGroup(const char *section, ptr
|
|||
if (createIfNeeded) {
|
||||
EsSystemConfigurationGroup group = {};
|
||||
group.section = (char *) EsHeapAllocate(sectionBytes, false);
|
||||
if (!group.section) return nullptr;
|
||||
group.sectionBytes = sectionBytes;
|
||||
EsMemoryCopy(group.section, section, sectionBytes);
|
||||
return api.systemConfigurationGroups.Add(group);
|
||||
EsSystemConfigurationGroup *_group = api.systemConfigurationGroups.Add(group);
|
||||
|
||||
if (_group) {
|
||||
return _group;
|
||||
} else {
|
||||
EsHeapFree(group.section);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -325,6 +338,7 @@ char *EsSystemConfigurationGroupReadString(EsSystemConfigurationGroup *group, co
|
|||
if (!item) { if (valueBytes) *valueBytes = 0; return nullptr; }
|
||||
if (valueBytes) *valueBytes = item->valueBytes;
|
||||
char *copy = (char *) EsHeapAllocate(item->valueBytes + 1, false);
|
||||
if (!copy) { if (valueBytes) *valueBytes = 0; return nullptr; }
|
||||
copy[item->valueBytes] = 0;
|
||||
EsMemoryCopy(copy, item->value, item->valueBytes);
|
||||
return copy;
|
||||
|
@ -541,22 +555,28 @@ void _EsPathAnnouncePathMoved(const char *oldPath, ptrdiff_t oldPathBytes, const
|
|||
if (newPathBytes == -1) newPathBytes = EsCStringLength(newPath);
|
||||
size_t bufferBytes = 1 + sizeof(uintptr_t) * 2 + oldPathBytes + newPathBytes;
|
||||
char *buffer = (char *) EsHeapAllocate(bufferBytes, false);
|
||||
buffer[0] = DESKTOP_MSG_ANNOUNCE_PATH_MOVED;
|
||||
EsMemoryCopy(buffer + 1, &oldPathBytes, sizeof(uintptr_t));
|
||||
EsMemoryCopy(buffer + 1 + sizeof(uintptr_t), &newPathBytes, sizeof(uintptr_t));
|
||||
EsMemoryCopy(buffer + 1 + sizeof(uintptr_t) * 2, oldPath, oldPathBytes);
|
||||
EsMemoryCopy(buffer + 1 + sizeof(uintptr_t) * 2 + oldPathBytes, newPath, newPathBytes);
|
||||
MessageDesktop(buffer, bufferBytes);
|
||||
EsHeapFree(buffer);
|
||||
|
||||
if (buffer) {
|
||||
buffer[0] = DESKTOP_MSG_ANNOUNCE_PATH_MOVED;
|
||||
EsMemoryCopy(buffer + 1, &oldPathBytes, sizeof(uintptr_t));
|
||||
EsMemoryCopy(buffer + 1 + sizeof(uintptr_t), &newPathBytes, sizeof(uintptr_t));
|
||||
EsMemoryCopy(buffer + 1 + sizeof(uintptr_t) * 2, oldPath, oldPathBytes);
|
||||
EsMemoryCopy(buffer + 1 + sizeof(uintptr_t) * 2 + oldPathBytes, newPath, newPathBytes);
|
||||
MessageDesktop(buffer, bufferBytes);
|
||||
EsHeapFree(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void EsApplicationRunTemporary(EsInstance *instance, const char *path, ptrdiff_t pathBytes) {
|
||||
if (pathBytes == -1) pathBytes = EsCStringLength(path);
|
||||
char *buffer = (char *) EsHeapAllocate(pathBytes + 1, false);
|
||||
buffer[0] = DESKTOP_MSG_RUN_TEMPORARY_APPLICATION;
|
||||
EsMemoryCopy(buffer + 1, path, pathBytes);
|
||||
MessageDesktop(buffer, pathBytes + 1, instance->window->handle);
|
||||
EsHeapFree(buffer);
|
||||
|
||||
if (buffer) {
|
||||
buffer[0] = DESKTOP_MSG_RUN_TEMPORARY_APPLICATION;
|
||||
EsMemoryCopy(buffer + 1, path, pathBytes);
|
||||
MessageDesktop(buffer, pathBytes + 1, instance->window->handle);
|
||||
EsHeapFree(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void EsSystemShowShutdownDialog() {
|
||||
|
@ -574,10 +594,13 @@ void InstanceSave(EsInstance *_instance) {
|
|||
EsAssert(instance->instanceClass == ES_INSTANCE_CLASS_EDITOR);
|
||||
size_t bufferBytes = instance->editorSettings.newDocumentFileNameBytes + 1;
|
||||
char *buffer = (char *) EsHeapAllocate(bufferBytes, false);
|
||||
buffer[0] = DESKTOP_MSG_REQUEST_SAVE;
|
||||
EsMemoryCopy(buffer + 1, instance->editorSettings.newDocumentFileName, instance->editorSettings.newDocumentFileNameBytes);
|
||||
MessageDesktop(buffer, bufferBytes, _instance->window->handle);
|
||||
EsHeapFree(buffer);
|
||||
|
||||
if (buffer) {
|
||||
buffer[0] = DESKTOP_MSG_REQUEST_SAVE;
|
||||
EsMemoryCopy(buffer + 1, instance->editorSettings.newDocumentFileName, instance->editorSettings.newDocumentFileNameBytes);
|
||||
MessageDesktop(buffer, bufferBytes, _instance->window->handle);
|
||||
EsHeapFree(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void FileStoreCloseHandle(EsFileStore *fileStore) {
|
||||
|
@ -601,6 +624,7 @@ void FileStoreCloseHandle(EsFileStore *fileStore) {
|
|||
|
||||
EsFileStore *FileStoreCreateFromPath(const char *path, size_t pathBytes) {
|
||||
EsFileStore *fileStore = (EsFileStore *) EsHeapAllocate(sizeof(EsFileStore) + pathBytes, false);
|
||||
if (!fileStore) return nullptr;
|
||||
EsMemoryZero(fileStore, sizeof(EsFileStore));
|
||||
fileStore->type = FILE_STORE_PATH;
|
||||
fileStore->handles = 1;
|
||||
|
@ -613,6 +637,7 @@ EsFileStore *FileStoreCreateFromPath(const char *path, size_t pathBytes) {
|
|||
|
||||
EsFileStore *FileStoreCreateFromHandle(EsHandle handle) {
|
||||
EsFileStore *fileStore = (EsFileStore *) EsHeapAllocate(sizeof(EsFileStore), true);
|
||||
if (!fileStore) return nullptr;
|
||||
fileStore->type = FILE_STORE_HANDLE;
|
||||
fileStore->handles = 1;
|
||||
fileStore->error = ES_SUCCESS;
|
||||
|
@ -622,6 +647,7 @@ EsFileStore *FileStoreCreateFromHandle(EsHandle handle) {
|
|||
|
||||
EsFileStore *FileStoreCreateFromEmbeddedFile(const char *name, size_t nameBytes) {
|
||||
EsFileStore *fileStore = (EsFileStore *) EsHeapAllocate(sizeof(EsFileStore) + nameBytes, false);
|
||||
if (!fileStore) return nullptr;
|
||||
EsMemoryZero(fileStore, sizeof(EsFileStore));
|
||||
fileStore->type = FILE_STORE_EMBEDDED_FILE;
|
||||
fileStore->handles = 1;
|
||||
|
@ -919,35 +945,44 @@ EsMessage *EsMessageReceive() {
|
|||
} else if (type == ES_MSG_INSTANCE_SAVE_RESPONSE) {
|
||||
EsMessage m = {};
|
||||
m.type = ES_MSG_INSTANCE_SAVE;
|
||||
|
||||
m.instanceSave.file = (EsFileStore *) EsHeapAllocate(sizeof(EsFileStore), true);
|
||||
m.instanceSave.file->error = message.message.tabOperation.error;
|
||||
m.instanceSave.file->handle = message.message.tabOperation.handle;
|
||||
m.instanceSave.file->type = FILE_STORE_HANDLE;
|
||||
m.instanceSave.file->handles = 1;
|
||||
m.instanceSave.instance = InstanceFromWindowID(message.message.tabOperation.id);
|
||||
|
||||
if (m.instanceSave.file->error == ES_SUCCESS) {
|
||||
if (m.instanceSave.file) {
|
||||
m.instanceSave.file->error = message.message.tabOperation.error;
|
||||
m.instanceSave.file->handle = message.message.tabOperation.handle;
|
||||
m.instanceSave.file->type = FILE_STORE_HANDLE;
|
||||
m.instanceSave.file->handles = 1;
|
||||
m.instanceSave.instance = InstanceFromWindowID(message.message.tabOperation.id);
|
||||
|
||||
if (m.instanceSave.file->error == ES_SUCCESS) {
|
||||
EsMemoryCopy(&message.message, &m, sizeof(EsMessage));
|
||||
return &message.message;
|
||||
} else {
|
||||
EsInstanceSaveComplete(&m, false);
|
||||
}
|
||||
|
||||
EsMemoryCopy(&message.message, &m, sizeof(EsMessage));
|
||||
return &message.message;
|
||||
} else {
|
||||
EsInstanceSaveComplete(&m, false);
|
||||
if (message.message.tabOperation.handle) {
|
||||
EsHandleClose(message.message.tabOperation.handle);
|
||||
}
|
||||
}
|
||||
|
||||
EsMemoryCopy(&message.message, &m, sizeof(EsMessage));
|
||||
} else if (type == ES_MSG_INSTANCE_DOCUMENT_RENAMED) {
|
||||
char *buffer = (char *) EsHeapAllocate(message.message.tabOperation.bytes, false);
|
||||
EsConstantBufferRead(message.message.tabOperation.handle, buffer);
|
||||
EsInstance *_instance = InstanceFromWindowID(message.message.tabOperation.id);
|
||||
|
||||
if (_instance) {
|
||||
APIInstance *instance = (APIInstance *) _instance->_private;
|
||||
EsHeapFree((void *) instance->startupInformation->filePath);
|
||||
instance->startupInformation->filePath = buffer;
|
||||
instance->startupInformation->filePathBytes = message.message.tabOperation.bytes;
|
||||
EsWindowSetTitle(_instance->window, buffer, message.message.tabOperation.bytes);
|
||||
} else {
|
||||
EsHeapFree(buffer);
|
||||
if (buffer) {
|
||||
EsConstantBufferRead(message.message.tabOperation.handle, buffer);
|
||||
EsInstance *_instance = InstanceFromWindowID(message.message.tabOperation.id);
|
||||
|
||||
if (_instance) {
|
||||
APIInstance *instance = (APIInstance *) _instance->_private;
|
||||
EsHeapFree((void *) instance->startupInformation->filePath);
|
||||
instance->startupInformation->filePath = buffer;
|
||||
instance->startupInformation->filePathBytes = message.message.tabOperation.bytes;
|
||||
EsWindowSetTitle(_instance->window, buffer, message.message.tabOperation.bytes);
|
||||
} else {
|
||||
EsHeapFree(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
EsHandleClose(message.message.tabOperation.handle);
|
||||
|
@ -1014,7 +1049,9 @@ EsMessage *EsMessageReceive() {
|
|||
api.foundBootFileSystem = true;
|
||||
}
|
||||
|
||||
return &message.message;
|
||||
if (m->mountPoint) {
|
||||
return &message.message;
|
||||
}
|
||||
} else if (type == ES_MSG_UNREGISTER_FILE_SYSTEM) {
|
||||
for (uintptr_t i = 0; i < api.mountPoints.Length(); i++) {
|
||||
if (api.mountPoints[i].information.id == message.message.unregisterFileSystem.id) {
|
||||
|
@ -1279,6 +1316,7 @@ EsCommand *EsCommandRegister(EsCommand *command, EsInstance *_instance, EsComman
|
|||
const char *cDefaultKeyboardShortcut, bool enabled) {
|
||||
if (!command) {
|
||||
command = (EsCommand *) EsHeapAllocate(sizeof(EsCommand), true);
|
||||
if (!command) return nullptr;
|
||||
command->allocated = true;
|
||||
}
|
||||
|
||||
|
|
103
desktop/gui.cpp
103
desktop/gui.cpp
|
@ -394,17 +394,25 @@ struct ColorPickerHost {
|
|||
|
||||
void ColorPickerCreate(EsElement *parent, ColorPickerHost host, uint32_t initialColor, bool showTextbox);
|
||||
|
||||
void HeapDuplicate(void **pointer, const void *data, size_t bytes) {
|
||||
void HeapDuplicate(void **pointer, size_t *outBytes, const void *data, size_t bytes) {
|
||||
if (*pointer) {
|
||||
EsHeapFree(*pointer);
|
||||
}
|
||||
|
||||
if (!data && !bytes) {
|
||||
*pointer = nullptr;
|
||||
*outBytes = 0;
|
||||
} else {
|
||||
void *buffer = EsHeapAllocate(bytes, false);
|
||||
if (buffer) EsMemoryCopy(buffer, data, bytes);
|
||||
*pointer = buffer;
|
||||
|
||||
if (buffer) {
|
||||
EsMemoryCopy(buffer, data, bytes);
|
||||
*pointer = buffer;
|
||||
*outBytes = bytes;
|
||||
} else {
|
||||
*pointer = nullptr;
|
||||
*outBytes = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -674,7 +682,9 @@ void EsDialogClose(EsWindow *window) {
|
|||
EsElement *EsDialogShowAlert(EsWindow *window, const char *title, ptrdiff_t titleBytes,
|
||||
const char *content, ptrdiff_t contentBytes, uint32_t iconID, uint32_t flags) {
|
||||
EsElement *dialog = EsDialogShow(window);
|
||||
if (!dialog) return nullptr;
|
||||
EsPanel *heading = EsPanelCreate(dialog, ES_CELL_H_FILL | ES_PANEL_HORIZONTAL, ES_STYLE_DIALOG_HEADING);
|
||||
if (!heading) return nullptr;
|
||||
|
||||
if (iconID) {
|
||||
EsIconDisplayCreate(heading, ES_FLAGS_DEFAULT, {}, iconID);
|
||||
|
@ -687,6 +697,7 @@ EsElement *EsDialogShowAlert(EsWindow *window, const char *title, ptrdiff_t titl
|
|||
content, contentBytes)->cName = "dialog contents";
|
||||
|
||||
EsPanel *buttonArea = EsPanelCreate(dialog, ES_CELL_H_FILL | ES_PANEL_HORIZONTAL | ES_PANEL_REVERSE, ES_STYLE_DIALOG_BUTTON_AREA);
|
||||
if (!buttonArea) return nullptr;
|
||||
|
||||
if (flags & ES_DIALOG_ALERT_OK_BUTTON) {
|
||||
EsButton *button = EsButtonCreate(buttonArea, ES_BUTTON_DEFAULT, 0, "OK");
|
||||
|
@ -821,7 +832,13 @@ EsWindow *EsWindowCreate(EsInstance *instance, EsWindowStyle style) {
|
|||
}
|
||||
|
||||
EsWindow *window = (EsWindow *) EsHeapAllocate(sizeof(EsWindow), true);
|
||||
gui.allWindows.Add(window);
|
||||
if (!window) return nullptr;
|
||||
|
||||
if (!gui.allWindows.Add(window)) {
|
||||
EsHeapFree(window);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
window->instance = instance;
|
||||
|
||||
if (style == ES_WINDOW_NORMAL) {
|
||||
|
@ -945,6 +962,7 @@ EsElement *EsMenuGetSource(EsMenu *menu) {
|
|||
|
||||
EsMenu *EsMenuCreate(EsElement *source, uint64_t flags) {
|
||||
EsWindow *menu = (EsWindow *) EsWindowCreate(source->instance, ES_WINDOW_MENU);
|
||||
if (!menu) return nullptr;
|
||||
menu->flags |= flags;
|
||||
menu->activated = true;
|
||||
menu->source = source;
|
||||
|
@ -1063,11 +1081,13 @@ void FileMenuCreate(EsInstance *_instance, EsElement *element, EsCommand *) {
|
|||
APIInstance *instance = (APIInstance *) _instance->_private;
|
||||
EsAssert(instance->instanceClass == ES_INSTANCE_CLASS_EDITOR);
|
||||
EsInstanceClassEditorSettings *editorSettings = &instance->editorSettings;
|
||||
EsMenu *menu = EsMenuCreate(element, ES_FLAGS_DEFAULT);
|
||||
EsPanel *panel1 = EsPanelCreate(menu, ES_PANEL_HORIZONTAL | ES_CELL_H_LEFT, &styleFileMenuDocumentInformationPanel1);
|
||||
|
||||
bool newDocument = !instance->startupInformation || !instance->startupInformation->filePath;
|
||||
|
||||
EsMenu *menu = EsMenuCreate(element, ES_FLAGS_DEFAULT);
|
||||
if (!menu) return;
|
||||
EsPanel *panel1 = EsPanelCreate(menu, ES_PANEL_HORIZONTAL | ES_CELL_H_LEFT, &styleFileMenuDocumentInformationPanel1);
|
||||
if (!panel1) goto show;
|
||||
|
||||
{
|
||||
// TODO Get this icon from the file type database?
|
||||
// We'll probably need Desktop to send this via EsApplicationStartupInformation and when the file is renamed.
|
||||
|
@ -1076,7 +1096,9 @@ void FileMenuCreate(EsInstance *_instance, EsElement *element, EsCommand *) {
|
|||
EsSpacerCreate(panel1, ES_FLAGS_DEFAULT, 0, 5, 0);
|
||||
|
||||
EsPanel *panel2 = EsPanelCreate(panel1, ES_FLAGS_DEFAULT, &styleFileMenuDocumentInformationPanel2);
|
||||
if (!panel2) goto show;
|
||||
EsPanel *panel3 = EsPanelCreate(panel2, ES_PANEL_HORIZONTAL | ES_PANEL_H_LEFT, &styleFileMenuDocumentInformationPanel2);
|
||||
if (!panel3) goto show;
|
||||
|
||||
if (newDocument) {
|
||||
EsTextDisplayCreate(panel3, ES_FLAGS_DEFAULT, ES_STYLE_TEXT_LABEL,
|
||||
|
@ -1087,10 +1109,12 @@ void FileMenuCreate(EsInstance *_instance, EsElement *element, EsCommand *) {
|
|||
}
|
||||
|
||||
EsButton *renameButton = EsButtonCreate(panel3, ES_BUTTON_TOOLBAR); // TODO.
|
||||
if (!renameButton) goto show;
|
||||
EsButtonSetIcon(renameButton, ES_ICON_DOCUMENT_EDIT_SYMBOLIC);
|
||||
|
||||
if (!newDocument) {
|
||||
EsPanel *panel4 = EsPanelCreate(panel2, ES_PANEL_TABLE | ES_PANEL_HORIZONTAL | ES_CELL_H_LEFT, &styleFileMenuDocumentInformationPanel2);
|
||||
if (!panel4) goto show;
|
||||
EsPanelSetBands(panel4, 2 /* columns */);
|
||||
|
||||
char buffer[64];
|
||||
|
@ -1120,11 +1144,13 @@ void FileMenuCreate(EsInstance *_instance, EsElement *element, EsCommand *) {
|
|||
EsMenuAddItem(menu, newDocument ? ES_ELEMENT_DISABLED : ES_FLAGS_DEFAULT, INTERFACE_STRING(CommonFileShare)); // TODO.
|
||||
EsMenuAddItem(menu, newDocument ? ES_ELEMENT_DISABLED : ES_FLAGS_DEFAULT, INTERFACE_STRING(CommonFileVersionHistory)); // TODO.
|
||||
EsMenuAddCommand(menu, ES_FLAGS_DEFAULT, INTERFACE_STRING(CommonFileShowInFileManager), &instance->commandShowInFileManager);
|
||||
EsMenuShow(menu);
|
||||
|
||||
show: EsMenuShow(menu);
|
||||
}
|
||||
|
||||
void EsToolbarAddFileMenu(EsElement *element, const EsFileMenuSettings *settings) {
|
||||
EsButton *button = EsButtonCreate(element, ES_BUTTON_DROPDOWN, 0, INTERFACE_STRING(CommonFileMenu));
|
||||
if (!button) return;
|
||||
button->accessKey = 'F';
|
||||
button->userData = (void *) settings;
|
||||
EsButtonOnCommand(button, FileMenuCreate);
|
||||
|
@ -1651,7 +1677,7 @@ void EsElement::InternalPaint(EsPainter *painter, int paintFlags) {
|
|||
|
||||
bool EsElement::StartAnimating() {
|
||||
if ((state & UI_STATE_ANIMATING) || (state & UI_STATE_DESTROYING)) return false;
|
||||
gui.animatingElements.Add(this);
|
||||
if (!gui.animatingElements.Add(this)) return false;
|
||||
gui.animationSleep = false;
|
||||
state |= UI_STATE_ANIMATING;
|
||||
lastTimeStamp = 0;
|
||||
|
@ -2703,6 +2729,7 @@ int ProcessScrollbarButtonMessage(EsElement *element, EsMessage *message) {
|
|||
|
||||
EsScrollbar *ScrollbarCreate(EsElement *parent, uint64_t flags) {
|
||||
EsScrollbar *scrollbar = (EsScrollbar *) EsHeapAllocate(sizeof(EsScrollbar), true);
|
||||
if (!scrollbar) return nullptr;
|
||||
scrollbar->thumb = (EsElement *) EsHeapAllocate(sizeof(EsElement), true);
|
||||
|
||||
if (flags & ES_SCROLLBAR_HORIZONTAL) {
|
||||
|
@ -2792,7 +2819,15 @@ void ScrollPane::Setup(EsElement *_parent, uint8_t _xMode, uint8_t _yMode, uint1
|
|||
for (int axis = 0; axis < 2; axis++) {
|
||||
if (mode[axis] == SCROLL_MODE_FIXED || mode[axis] == SCROLL_MODE_AUTO) {
|
||||
uint64_t flags = ES_CELL_FILL | ES_ELEMENT_NON_CLIENT | (axis ? ES_SCROLLBAR_VERTICAL : ES_SCROLLBAR_HORIZONTAL);
|
||||
if (!bar[axis]) bar[axis] = ScrollbarCreate(parent, flags);
|
||||
|
||||
if (!bar[axis]) {
|
||||
bar[axis] = ScrollbarCreate(parent, flags);
|
||||
|
||||
if (!bar[axis]) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
bar[axis]->userData = this;
|
||||
|
||||
bar[axis]->messageUser = [] (EsElement *element, EsMessage *message) {
|
||||
|
@ -2816,7 +2851,7 @@ void ScrollPane::Setup(EsElement *_parent, uint8_t _xMode, uint8_t _yMode, uint1
|
|||
|
||||
if (bar[0] && bar[1]) {
|
||||
if (!pad) pad = EsCustomElementCreate(parent, ES_CELL_FILL | ES_ELEMENT_NON_CLIENT, ES_STYLE_SCROLLBAR_PAD);
|
||||
pad->cName = "scrollbar pad";
|
||||
if (pad) pad->cName = "scrollbar pad";
|
||||
} else if (pad) {
|
||||
EsElementDestroy(pad);
|
||||
pad = nullptr;
|
||||
|
@ -3333,6 +3368,7 @@ int ProcessPanelMessage(EsElement *element, EsMessage *message) {
|
|||
|
||||
EsPanel *EsPanelCreate(EsElement *parent, uint64_t flags, const EsStyle *style) {
|
||||
EsPanel *panel = (EsPanel *) EsHeapAllocate(sizeof(EsPanel), true);
|
||||
if (!panel) return nullptr;
|
||||
|
||||
panel->Initialise(parent, flags, ProcessPanelMessage, style);
|
||||
panel->cName = "panel";
|
||||
|
@ -3367,6 +3403,7 @@ int ProcessSpacerMessage(EsElement *element, EsMessage *message) {
|
|||
|
||||
EsElement *EsSpacerCreate(EsElement *panel, uint64_t flags, const EsStyle *style, int width, int height) {
|
||||
EsSpacer *spacer = (EsSpacer *) EsHeapAllocate(sizeof(EsSpacer), true);
|
||||
if (!spacer) return nullptr;
|
||||
spacer->Initialise(panel, flags, ProcessSpacerMessage, style);
|
||||
spacer->cName = "spacer";
|
||||
spacer->width = width == -1 ? 4 : width;
|
||||
|
@ -3376,6 +3413,7 @@ EsElement *EsSpacerCreate(EsElement *panel, uint64_t flags, const EsStyle *style
|
|||
|
||||
EsElement *EsCustomElementCreate(EsElement *parent, uint64_t flags, const EsStyle *style) {
|
||||
EsElement *element = (EsElement *) EsHeapAllocate(sizeof(EsElement), true);
|
||||
if (!element) return nullptr;
|
||||
element->Initialise(parent, flags, nullptr, style);
|
||||
element->cName = "custom element";
|
||||
return element;
|
||||
|
@ -3604,6 +3642,7 @@ int ProcessCanvasPaneMessage(EsElement *element, EsMessage *message) {
|
|||
|
||||
EsCanvasPane *EsCanvasPaneCreate(EsElement *parent, uint64_t flags, const EsStyle *style) {
|
||||
EsCanvasPane *pane = (EsCanvasPane *) EsHeapAllocate(sizeof(EsCanvasPane), true);
|
||||
if (!pane) return nullptr;
|
||||
pane->Initialise(parent, flags, ProcessCanvasPaneMessage, style);
|
||||
pane->cName = "canvas pane";
|
||||
pane->zoom = 1.0;
|
||||
|
@ -3659,12 +3698,12 @@ void EsAnnouncementShow(EsWindow *parent, uint64_t flags, int32_t x, int32_t y,
|
|||
(void) flags;
|
||||
|
||||
EsWindow *window = EsWindowCreate(nullptr, ES_WINDOW_TIP);
|
||||
if (!window) return;
|
||||
window->messageUser = AnnouncementMessage;
|
||||
|
||||
EsTextDisplay *display = EsTextDisplayCreate(window, ES_CELL_FILL, ES_STYLE_ANNOUNCEMENT, text, textBytes);
|
||||
|
||||
int32_t width = display->GetWidth(0);
|
||||
int32_t height = display->GetHeight(width);
|
||||
int32_t width = display ? display->GetWidth(0) : 0;
|
||||
int32_t height = display ? display->GetHeight(width) : 0;
|
||||
|
||||
EsRectangle parentBounds = {};
|
||||
if (parent) parentBounds = EsWindowGetBounds(parent);
|
||||
|
@ -3778,6 +3817,7 @@ int ProcessButtonMessage(EsElement *element, EsMessage *message) {
|
|||
|
||||
EsButton *EsButtonCreate(EsElement *parent, uint64_t flags, const EsStyle *style, const char *label, ptrdiff_t labelBytes) {
|
||||
EsButton *button = (EsButton *) EsHeapAllocate(sizeof(EsButton), true);
|
||||
if (!button) return button;
|
||||
|
||||
if (!style) {
|
||||
if (flags & ES_BUTTON_MENU_ITEM) {
|
||||
|
@ -3826,8 +3866,7 @@ EsButton *EsButtonCreate(EsElement *parent, uint64_t flags, const EsStyle *style
|
|||
}
|
||||
|
||||
if (labelBytes == -1) labelBytes = EsCStringLength(label);
|
||||
HeapDuplicate((void **) &button->label, label, labelBytes);
|
||||
button->labelBytes = labelBytes;
|
||||
HeapDuplicate((void **) &button->label, &button->labelBytes, label, labelBytes);
|
||||
|
||||
if ((flags & ES_BUTTON_MENU_ITEM) && (flags & ES_MENU_ITEM_HEADER)) {
|
||||
EsElementSetDisabled(button, true);
|
||||
|
@ -3904,6 +3943,7 @@ void EsMenuAddItem(EsMenu *menu, uint64_t flags, const char *label, ptrdiff_t la
|
|||
EsButton *button = (EsButton *) EsButtonCreate(menu,
|
||||
ES_BUTTON_NOT_FOCUSABLE | ES_BUTTON_MENU_ITEM | ES_CELL_H_FILL | flags, 0,
|
||||
label, labelBytes != -1 ? labelBytes : EsCStringLength(label));
|
||||
if (!button) return;
|
||||
button->userData = (void *) callback;
|
||||
|
||||
button->messageUser = [] (EsElement *element, EsMessage *message) {
|
||||
|
@ -3926,6 +3966,7 @@ void EsMenuAddCommand(EsMenu *menu, uint64_t flags, const char *label, ptrdiff_t
|
|||
EsButton *button = (EsButton *) EsButtonCreate(menu,
|
||||
ES_BUTTON_NOT_FOCUSABLE | ES_BUTTON_MENU_ITEM | ES_CELL_H_FILL | flags,
|
||||
0, label, labelBytes);
|
||||
if (!button) return;
|
||||
EsCommandAddButton(command, button);
|
||||
}
|
||||
|
||||
|
@ -4131,6 +4172,7 @@ int ProcessColorChosenPointMessage(EsElement *element, EsMessage *message) {
|
|||
|
||||
void ColorPickerCreate(EsElement *parent, ColorPickerHost host, uint32_t initialColor, bool showTextbox) {
|
||||
ColorPicker *picker = (ColorPicker *) EsHeapAllocate(sizeof(ColorPicker), true);
|
||||
if (!picker) return;
|
||||
picker->host = host;
|
||||
picker->color = initialColor & 0xFFFFFF;
|
||||
picker->opacity = (float) (initialColor >> 24) / 255.0f;
|
||||
|
@ -4500,6 +4542,7 @@ int ProcessColorWellMessage(EsElement *element, EsMessage *message) {
|
|||
DrawStyledBox(message->painter, box);
|
||||
} else if (message->type == ES_MSG_MOUSE_LEFT_CLICK) {
|
||||
EsMenu *menu = EsMenuCreate(well, ES_FLAGS_DEFAULT);
|
||||
if (!menu) return ES_HANDLED;
|
||||
ColorPickerHost host = { well, &well->indeterminate, (well->flags & ES_COLOR_WELL_HAS_OPACITY) ? true : false };
|
||||
ColorPickerCreate((EsElement *) menu, host, well->color, true);
|
||||
EsMenuShow(menu);
|
||||
|
@ -4512,6 +4555,7 @@ int ProcessColorWellMessage(EsElement *element, EsMessage *message) {
|
|||
|
||||
EsColorWell *EsColorWellCreate(EsElement *parent, uint64_t flags, uint32_t initialColor) {
|
||||
EsColorWell *well = (EsColorWell *) EsHeapAllocate(sizeof(EsColorWell), true);
|
||||
if (!well) return nullptr;
|
||||
well->color = initialColor;
|
||||
well->Initialise(parent, flags | ES_ELEMENT_FOCUSABLE, ProcessColorWellMessage, ES_STYLE_PUSH_BUTTON_NORMAL_COLOR_WELL);
|
||||
well->cName = "color well";
|
||||
|
@ -4706,6 +4750,11 @@ int ProcessSplitterMessage(EsElement *element, EsMessage *message) {
|
|||
currentSizes.Add(splitter->resizeStartSizes[i]);
|
||||
}
|
||||
|
||||
if (currentSizes.Length() != childCount / 2 + 1) {
|
||||
currentSizes.Free();
|
||||
return ES_HANDLED;
|
||||
}
|
||||
|
||||
// Step 2: Calculate the fixed size, and total weight.
|
||||
|
||||
int64_t fixedSize = 0, totalWeight = 0;
|
||||
|
@ -4867,6 +4916,7 @@ int ProcessSplitterMessage(EsElement *element, EsMessage *message) {
|
|||
|
||||
EsSplitter *EsSplitterCreate(EsElement *parent, uint64_t flags, const EsStyle *style) {
|
||||
EsSplitter *splitter = (EsSplitter *) EsHeapAllocate(sizeof(EsSplitter), true);
|
||||
if (!splitter) return nullptr;
|
||||
splitter->horizontal = flags & ES_SPLITTER_HORIZONTAL;
|
||||
splitter->Initialise(parent, flags | ES_ELEMENT_NO_CLIP, ProcessSplitterMessage,
|
||||
style ?: ES_STYLE_PANEL_WINDOW_BACKGROUND);
|
||||
|
@ -4914,8 +4964,9 @@ int ProcessImageDisplayMessage(EsElement *element, EsMessage *message) {
|
|||
}
|
||||
|
||||
if (~display->flags & UI_STATE_CHECK_VISIBLE) {
|
||||
display->state |= UI_STATE_CHECK_VISIBLE;
|
||||
display->window->checkVisible.Add(display);
|
||||
if (display->window->checkVisible.Add(display)) {
|
||||
display->state |= UI_STATE_CHECK_VISIBLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4944,6 +4995,7 @@ int ProcessImageDisplayMessage(EsElement *element, EsMessage *message) {
|
|||
|
||||
EsImageDisplay *EsImageDisplayCreate(EsElement *parent, uint64_t flags, const EsStyle *style) {
|
||||
EsImageDisplay *display = (EsImageDisplay *) EsHeapAllocate(sizeof(EsImageDisplay), true);
|
||||
if (!display) return nullptr;
|
||||
display->Initialise(parent, flags, ProcessImageDisplayMessage, style);
|
||||
display->cName = "image";
|
||||
return display;
|
||||
|
@ -5009,6 +5061,7 @@ int ProcessIconDisplayMessage(EsElement *element, EsMessage *message) {
|
|||
|
||||
EsIconDisplay *EsIconDisplayCreate(EsElement *parent, uint64_t flags, const EsStyle *style, uint32_t iconID) {
|
||||
EsIconDisplay *display = (EsIconDisplay *) EsHeapAllocate(sizeof(EsIconDisplay), true);
|
||||
if (!display) return nullptr;
|
||||
display->Initialise(parent, flags, ProcessIconDisplayMessage, style ?: ES_STYLE_ICON_DISPLAY);
|
||||
display->cName = "icon";
|
||||
display->iconID = iconID;
|
||||
|
@ -5101,6 +5154,7 @@ void EsSliderSetValue(EsSlider *slider, double newValue, bool sendUpdatedMessage
|
|||
|
||||
EsSlider *EsSliderCreate(EsElement *parent, uint64_t flags, const EsStyle *style, double value, uint32_t steps) {
|
||||
EsSlider *slider = (EsSlider *) EsHeapAllocate(sizeof(EsSlider), true);
|
||||
if (!slider) return nullptr;
|
||||
slider->Initialise(parent, flags | ES_ELEMENT_FOCUSABLE, ProcessSliderMessage, style ?: ES_STYLE_SLIDER_TRACK);
|
||||
slider->cName = "slider";
|
||||
slider->point = EsCustomElementCreate(slider, ES_FLAGS_DEFAULT, ES_STYLE_SLIDER_POINT);
|
||||
|
@ -5254,6 +5308,11 @@ EsElement *EsWindowGetToolbar(EsWindow *window, bool createNew) {
|
|||
if (createNew || !window->toolbar) {
|
||||
bool first = !window->toolbar;
|
||||
window->toolbar = EsPanelCreate(window->toolbarSwitcher, ES_PANEL_HORIZONTAL | ES_CELL_FILL, ES_STYLE_PANEL_TOOLBAR);
|
||||
|
||||
if (!window->toolbar) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
window->toolbar->cName = "toolbar";
|
||||
EsAssert(window->toolbar->messageClass == ProcessPanelMessage);
|
||||
|
||||
|
@ -6099,8 +6158,9 @@ void AccessKeysGather(EsElement *element) {
|
|||
|
||||
entry.bounds = hintBounds;
|
||||
|
||||
gui.accessKeys.entries.Add(entry);
|
||||
gui.accessKeys.numbers[entry.character - 'A']++;
|
||||
if (gui.accessKeys.entries.Add(entry)) {
|
||||
gui.accessKeys.numbers[entry.character - 'A']++;
|
||||
}
|
||||
}
|
||||
|
||||
void AccessKeyHintsShow(EsPainter *painter) {
|
||||
|
@ -7071,8 +7131,7 @@ int InspectorContentTextboxCallback(EsElement *element, EsMessage *message) {
|
|||
|
||||
if (e->messageClass == ProcessButtonMessage) {
|
||||
EsButton *button = (EsButton *) e;
|
||||
HeapDuplicate((void **) &button->label, newContent, newContentBytes);
|
||||
button->labelBytes = newContentBytes;
|
||||
HeapDuplicate((void **) &button->label, &button->labelBytes, newContent, newContentBytes);
|
||||
} else if (e->messageClass == ProcessTextDisplayMessage) {
|
||||
EsTextDisplay *display = (EsTextDisplay *) e;
|
||||
EsTextDisplaySetContents(display, newContent, newContentBytes);
|
||||
|
|
|
@ -1979,6 +1979,7 @@ void EsListViewChangeStyles(EsListView *view, const EsStyle *style, const EsStyl
|
|||
EsListView *EsListViewCreate(EsElement *parent, uint64_t flags, const EsStyle *style,
|
||||
const EsStyle *itemStyle, const EsStyle *headerItemStyle, const EsStyle *footerItemStyle) {
|
||||
EsListView *view = (EsListView *) EsHeapAllocate(sizeof(EsListView), true);
|
||||
if (!view) return nullptr;
|
||||
|
||||
view->primaryCellStyle = GetStyle(MakeStyleKey(ES_STYLE_LIST_PRIMARY_CELL, 0), false);
|
||||
view->secondaryCellStyle = GetStyle(MakeStyleKey(ES_STYLE_LIST_SECONDARY_CELL, 0), false);
|
||||
|
@ -2009,7 +2010,10 @@ void EsListViewInsertGroup(EsListView *view, EsListViewIndex group, uint32_t fla
|
|||
|
||||
ListViewGroup empty = { .flags = flags };
|
||||
EsAssert(group <= (EsListViewIndex) view->groups.Length()); // Invalid group index.
|
||||
view->groups.Insert(empty, group);
|
||||
|
||||
if (!view->groups.Insert(empty, group)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the group index on visible items.
|
||||
|
||||
|
@ -2339,8 +2343,7 @@ void EsListViewSelect(EsListView *view, EsListViewIndex group, EsListViewIndex i
|
|||
void EsListViewSetEmptyMessage(EsListView *view, const char *message, ptrdiff_t messageBytes) {
|
||||
EsMessageMutexCheck();
|
||||
if (messageBytes == -1) messageBytes = EsCStringLength(message);
|
||||
HeapDuplicate((void **) &view->emptyMessage, message, messageBytes);
|
||||
view->emptyMessageBytes = messageBytes;
|
||||
HeapDuplicate((void **) &view->emptyMessage, &view->emptyMessageBytes, message, messageBytes);
|
||||
|
||||
if (!view->totalItemCount) {
|
||||
view->Repaint(true);
|
||||
|
@ -2389,8 +2392,7 @@ EsListViewIndex EsListViewFixedItemInsert(EsListView *view, const char *string,
|
|||
ListViewFixedItem item = {};
|
||||
item.data = data;
|
||||
item.iconID = iconID;
|
||||
HeapDuplicate((void **) &item.firstColumn.string, string, stringBytes);
|
||||
item.firstColumn.bytes = stringBytes;
|
||||
HeapDuplicate((void **) &item.firstColumn.string, &item.firstColumn.bytes, string, stringBytes);
|
||||
view->fixedItems.Insert(item, index);
|
||||
|
||||
EsListViewInsert(view, 0, index, 1);
|
||||
|
@ -2403,9 +2405,13 @@ void EsListViewFixedItemAddString(EsListView *view, EsListViewIndex index, const
|
|||
EsAssert(index >= 0 && index < (intptr_t) view->fixedItems.Length());
|
||||
ListViewFixedString fixedString = {};
|
||||
fixedString.bytes = stringBytes == -1 ? EsCStringLength(string) : stringBytes;
|
||||
HeapDuplicate((void **) &fixedString, string, fixedString.bytes);
|
||||
view->fixedItems[index].otherColumns.Add(fixedString);
|
||||
EsListViewInvalidateContent(view, 0, index);
|
||||
size_t outBytes;
|
||||
HeapDuplicate((void **) &fixedString, &outBytes, string, fixedString.bytes);
|
||||
|
||||
if (outBytes == fixedString.bytes) {
|
||||
view->fixedItems[index].otherColumns.Add(fixedString);
|
||||
EsListViewInvalidateContent(view, 0, index);
|
||||
}
|
||||
}
|
||||
|
||||
bool EsListViewFixedItemFindIndex(EsListView *view, EsGeneric data, EsListViewIndex *index) {
|
||||
|
@ -2473,6 +2479,11 @@ EsTextbox *EsListViewCreateInlineTextbox(EsListView *view, EsListViewIndex group
|
|||
}
|
||||
|
||||
view->inlineTextbox = EsTextboxCreate(view, textboxFlags, ES_STYLE_TEXTBOX_INLINE);
|
||||
|
||||
if (!view->inlineTextbox) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EsAssert(view->inlineTextbox->messageClass == ProcessTextboxMessage);
|
||||
view->inlineTextbox->messageClass = ListViewInlineTextboxMessage;
|
||||
|
||||
|
|
|
@ -187,12 +187,21 @@ void SettingsNumberBoxSetValue(EsElement *element, double newValueDouble) {
|
|||
EsTextboxInsert(textbox, buffer, bytes);
|
||||
|
||||
EsMutexAcquire(&api.systemConfigurationMutex);
|
||||
|
||||
EsSystemConfigurationGroup *group = SystemConfigurationGetGroup(control->cConfigurationSection, -1, true);
|
||||
EsSystemConfigurationItem *item = SystemConfigurationGetItem(group, control->cConfigurationKey, -1, true);
|
||||
int32_t oldValue = EsIntegerParse(item->value, item->valueBytes);
|
||||
EsHeapFree(item->value);
|
||||
item->value = (char *) EsHeapAllocate(65, true);
|
||||
item->valueBytes = EsStringFormat(item->value, 64, "%fd", ES_STRING_FORMAT_SIMPLE, newValue);
|
||||
int32_t oldValue = 0;
|
||||
|
||||
if (group) {
|
||||
EsSystemConfigurationItem *item = SystemConfigurationGetItem(group, control->cConfigurationKey, -1, true);
|
||||
|
||||
if (item) {
|
||||
oldValue = EsIntegerParse(item->value, item->valueBytes);
|
||||
EsHeapFree(item->value);
|
||||
item->value = (char *) EsHeapAllocate(65, true);
|
||||
item->valueBytes = EsStringFormat(item->value, 64, "%fd", ES_STRING_FORMAT_SIMPLE, newValue);
|
||||
}
|
||||
}
|
||||
|
||||
EsMutexRelease(&api.systemConfigurationMutex);
|
||||
|
||||
if (oldValue != newValue) {
|
||||
|
@ -245,13 +254,22 @@ void SettingsCheckboxCommand(EsInstance *_instance, EsElement *element, EsComman
|
|||
bool newValue = EsButtonGetCheck(button) == ES_CHECK_CHECKED;
|
||||
|
||||
EsMutexAcquire(&api.systemConfigurationMutex);
|
||||
|
||||
EsSystemConfigurationGroup *group = SystemConfigurationGetGroup(control->cConfigurationSection, -1, true);
|
||||
EsSystemConfigurationItem *item = SystemConfigurationGetItem(group, control->cConfigurationKey, -1, true);
|
||||
bool oldValue = EsIntegerParse(item->value, item->valueBytes);
|
||||
EsHeapFree(item->value);
|
||||
item->value = (char *) EsHeapAllocate(2, true);
|
||||
*item->value = newValue ? '1' : '0';
|
||||
item->valueBytes = 1;
|
||||
bool oldValue;
|
||||
|
||||
if (group) {
|
||||
EsSystemConfigurationItem *item = SystemConfigurationGetItem(group, control->cConfigurationKey, -1, true);
|
||||
|
||||
if (item) {
|
||||
oldValue = EsIntegerParse(item->value, item->valueBytes);
|
||||
EsHeapFree(item->value);
|
||||
item->value = (char *) EsHeapAllocate(2, true);
|
||||
*item->value = newValue ? '1' : '0';
|
||||
item->valueBytes = 1;
|
||||
}
|
||||
}
|
||||
|
||||
EsMutexRelease(&api.systemConfigurationMutex);
|
||||
|
||||
if (oldValue == newValue) return;
|
||||
|
@ -362,13 +380,22 @@ int SettingsSliderMessage(EsElement *element, EsMessage *message) {
|
|||
|
||||
if (message->type == ES_MSG_SLIDER_MOVED && !message->sliderMoved.inDrag) {
|
||||
EsMutexAcquire(&api.systemConfigurationMutex);
|
||||
|
||||
EsSystemConfigurationGroup *group = SystemConfigurationGetGroup(control->cConfigurationSection, -1, true);
|
||||
EsSystemConfigurationItem *item = SystemConfigurationGetItem(group, control->cConfigurationKey, -1, true);
|
||||
int32_t oldValue;
|
||||
int32_t newValue = LinearMap(0, 1, control->minimumValue, control->maximumValue, EsSliderGetValue(slider));
|
||||
int32_t oldValue = EsIntegerParse(item->value, item->valueBytes);
|
||||
EsHeapFree(item->value);
|
||||
item->value = (char *) EsHeapAllocate(65, true);
|
||||
item->valueBytes = EsStringFormat(item->value, 64, "%fd", ES_STRING_FORMAT_SIMPLE, newValue);
|
||||
|
||||
if (group) {
|
||||
EsSystemConfigurationItem *item = SystemConfigurationGetItem(group, control->cConfigurationKey, -1, true);
|
||||
|
||||
if (item) {
|
||||
oldValue = EsIntegerParse(item->value, item->valueBytes);
|
||||
EsHeapFree(item->value);
|
||||
item->value = (char *) EsHeapAllocate(65, true);
|
||||
item->valueBytes = EsStringFormat(item->value, 64, "%fd", ES_STRING_FORMAT_SIMPLE, newValue);
|
||||
}
|
||||
}
|
||||
|
||||
EsMutexRelease(&api.systemConfigurationMutex);
|
||||
|
||||
if (oldValue != newValue) {
|
||||
|
|
|
@ -800,6 +800,7 @@ EsFileStore *EsClipboardOpen(EsClipboard clipboard) {
|
|||
EsBufferReadInto(&buffer, &error, sizeof(error));
|
||||
EsHeapFree(buffer.out);
|
||||
EsFileStore *fileStore = FileStoreCreateFromHandle(file);
|
||||
if (!fileStore) return nullptr;
|
||||
fileStore->error = error;
|
||||
return fileStore;
|
||||
}
|
||||
|
@ -823,8 +824,13 @@ EsError EsClipboardCloseAndAdd(EsClipboard clipboard, EsClipboardFormat format,
|
|||
|
||||
EsError EsClipboardAddText(EsClipboard clipboard, const char *text, ptrdiff_t textBytes) {
|
||||
EsFileStore *fileStore = EsClipboardOpen(clipboard);
|
||||
EsFileStoreWriteAll(fileStore, text, textBytes);
|
||||
return EsClipboardCloseAndAdd(clipboard, ES_CLIPBOARD_FORMAT_TEXT, fileStore);
|
||||
|
||||
if (fileStore) {
|
||||
EsFileStoreWriteAll(fileStore, text, textBytes);
|
||||
return EsClipboardCloseAndAdd(clipboard, ES_CLIPBOARD_FORMAT_TEXT, fileStore);
|
||||
} else {
|
||||
return ES_ERROR_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
}
|
||||
|
||||
void ClipboardGetInformation(EsHandle *file, ClipboardInformation *information) {
|
||||
|
|
158
desktop/text.cpp
158
desktop/text.cpp
|
@ -557,10 +557,7 @@ bool EsFontDatabaseLookupByID(EsFontFamily id, EsFontInformation *information) {
|
|||
|
||||
EsFontFamily EsFontDatabaseInsertFile(const EsFontInformation *information, EsFileStore *store) {
|
||||
FontInitialise();
|
||||
|
||||
EsAssert(store->handles);
|
||||
store->handles++;
|
||||
|
||||
FontDatabaseEntry *entry = nullptr;
|
||||
|
||||
if (information->nameBytes) {
|
||||
|
@ -586,12 +583,18 @@ EsFontFamily EsFontDatabaseInsertFile(const EsFontInformation *information, EsFi
|
|||
FontDatabaseEntry e = {};
|
||||
EsMemoryCopy(&e, information, sizeof(EsFontInformation));
|
||||
e.id = fontManagement.database.Length();
|
||||
fontManagement.database.Add(e);
|
||||
entry = &fontManagement.database.Last();
|
||||
|
||||
if (fontManagement.database.Add(e)) {
|
||||
entry = &fontManagement.database.Last();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
addFileToFamily:;
|
||||
|
||||
store->handles++;
|
||||
|
||||
entry->availableWeightsNormal |= information->availableWeightsNormal;
|
||||
entry->availableWeightsItalic |= information->availableWeightsItalic;
|
||||
|
||||
|
@ -1846,13 +1849,13 @@ void TextAddEllipsis(EsTextPlan *plan, int32_t maximumLineWidth, bool needFinalE
|
|||
TextPiece piece = {};
|
||||
piece.style = plan->currentTextStyle;
|
||||
piece.glyphOffset = plan->glyphInfos.Length();
|
||||
piece.glyphCount = glyphCount;
|
||||
piece.ascent = FontGetAscent (&plan->font) + plan->currentTextStyle->baselineOffset,
|
||||
piece.descent = -FontGetDescent(&plan->font) - plan->currentTextStyle->baselineOffset;
|
||||
|
||||
for (uintptr_t i = 0; i < glyphCount; i++) {
|
||||
plan->glyphInfos.Add(glyphInfos[i]);
|
||||
plan->glyphPositions.Add(glyphPositions[i]);
|
||||
if (!plan->glyphInfos.Add(glyphInfos[i])) break;
|
||||
if (!plan->glyphPositions.Add(glyphPositions[i])) break;
|
||||
piece.glyphCount++;
|
||||
int32_t width = glyphPositions[i].x_advance;
|
||||
piece.width += width, line->width += width;
|
||||
}
|
||||
|
@ -1938,18 +1941,19 @@ int32_t TextExpandTabs(EsTextPlan *plan, uintptr_t pieceOffset, int32_t width) {
|
|||
piece->width = firstWidth + tabWidth * (piece->end - piece->start - 1);
|
||||
addedWidth += piece->width;
|
||||
piece->glyphOffset = plan->glyphInfos.Length();
|
||||
piece->glyphCount = piece->end - piece->start;
|
||||
piece->glyphCount = 0;
|
||||
piece->ascent = FontGetAscent(&plan->font);
|
||||
piece->descent = -FontGetDescent(&plan->font);
|
||||
|
||||
for (uintptr_t i = 0; i < piece->glyphCount; i++) {
|
||||
for (uintptr_t i = 0; i < piece->end - piece->start; i++) {
|
||||
hb_glyph_info_t info = {};
|
||||
info.cluster = piece->start + i;
|
||||
info.codepoint = 0xFFFFFFFF;
|
||||
hb_glyph_position_t position = {};
|
||||
position.x_advance = i ? tabWidth : firstWidth;
|
||||
plan->glyphInfos.Add(info);
|
||||
plan->glyphPositions.Add(position);
|
||||
if (!plan->glyphInfos.Add(info)) break;
|
||||
if (!plan->glyphPositions.Add(position)) break;
|
||||
piece->glyphCount++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2004,14 +2008,17 @@ int32_t TextBuildTextPieces(EsTextPlan *plan, uintptr_t sectionStart, uintptr_t
|
|||
|
||||
if (plan->string[start] == '\t') {
|
||||
TextPiece _piece = {};
|
||||
plan->pieces.Add(_piece);
|
||||
TextPiece *piece = &plan->pieces.Last();
|
||||
piece->style = plan->currentTextStyle;
|
||||
piece->glyphOffset = 0;
|
||||
piece->glyphCount = 0;
|
||||
piece->start = start;
|
||||
piece->end = end;
|
||||
piece->isTabPiece = true;
|
||||
|
||||
if (plan->pieces.Add(_piece)) {
|
||||
TextPiece *piece = &plan->pieces.Last();
|
||||
piece->style = plan->currentTextStyle;
|
||||
piece->glyphOffset = 0;
|
||||
piece->glyphCount = 0;
|
||||
piece->start = start;
|
||||
piece->end = end;
|
||||
piece->isTabPiece = true;
|
||||
}
|
||||
|
||||
plan->textRunPosition++;
|
||||
continue;
|
||||
}
|
||||
|
@ -2041,31 +2048,34 @@ int32_t TextBuildTextPieces(EsTextPlan *plan, uintptr_t sectionStart, uintptr_t
|
|||
// Create the text piece.
|
||||
|
||||
TextPiece _piece = {};
|
||||
plan->pieces.Add(_piece);
|
||||
TextPiece *piece = &plan->pieces.Last();
|
||||
piece->style = plan->currentTextStyle;
|
||||
piece->glyphOffset = plan->glyphInfos.Length();
|
||||
piece->glyphCount = glyphCount;
|
||||
piece->ascent = FontGetAscent (&plan->font) + plan->currentTextStyle->baselineOffset;
|
||||
piece->descent = -FontGetDescent(&plan->font) - plan->currentTextStyle->baselineOffset;
|
||||
piece->start = start;
|
||||
piece->end = end;
|
||||
|
||||
for (uintptr_t i = 0; i < glyphCount; i++) {
|
||||
plan->glyphInfos.Add(glyphInfos[i]);
|
||||
plan->glyphPositions.Add(glyphPositions[i]);
|
||||
if (plan->pieces.Add(_piece)) {
|
||||
TextPiece *piece = &plan->pieces.Last();
|
||||
piece->style = plan->currentTextStyle;
|
||||
piece->glyphOffset = plan->glyphInfos.Length();
|
||||
piece->glyphCount = 0;
|
||||
piece->ascent = FontGetAscent (&plan->font) + plan->currentTextStyle->baselineOffset;
|
||||
piece->descent = -FontGetDescent(&plan->font) - plan->currentTextStyle->baselineOffset;
|
||||
piece->start = start;
|
||||
piece->end = end;
|
||||
|
||||
piece->width += glyphPositions[i].x_advance;
|
||||
for (uintptr_t i = 0; i < glyphCount; i++) {
|
||||
if (!plan->glyphInfos.Add(glyphInfos[i])) break;
|
||||
if (!plan->glyphPositions.Add(glyphPositions[i])) break;
|
||||
piece->glyphCount++;
|
||||
|
||||
if (i == glyphCount - 1 || glyphInfos[i].cluster != glyphInfos[i + 1].cluster) {
|
||||
piece->width += plan->currentTextStyle->tracking * FREETYPE_UNIT_SCALE;
|
||||
piece->width += glyphPositions[i].x_advance;
|
||||
|
||||
if (i == glyphCount - 1 || glyphInfos[i].cluster != glyphInfos[i + 1].cluster) {
|
||||
piece->width += plan->currentTextStyle->tracking * FREETYPE_UNIT_SCALE;
|
||||
}
|
||||
|
||||
// EsPrint("\t%d\n", glyphInfos[i].codepoint);
|
||||
}
|
||||
|
||||
// EsPrint("\t%d\n", glyphInfos[i].codepoint);
|
||||
width += piece->width;
|
||||
}
|
||||
|
||||
width += piece->width;
|
||||
|
||||
// Go to the next run.
|
||||
|
||||
plan->textRunPosition++;
|
||||
|
@ -2115,7 +2125,10 @@ EsTextPlan *EsTextPlanCreate(EsElement *element, EsTextPlanProperties *propertie
|
|||
plan.properties = *properties;
|
||||
|
||||
TextLine blankLine = {};
|
||||
plan.lines.Add(blankLine);
|
||||
|
||||
if (!plan.lines.Add(blankLine)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Setup the HarfBuzz buffer.
|
||||
|
||||
|
@ -2166,8 +2179,9 @@ EsTextPlan *EsTextPlanCreate(EsElement *element, EsTextPlanProperties *propertie
|
|||
break;
|
||||
}
|
||||
|
||||
plan.lines.Add(blankLine);
|
||||
plan.lines.Last().pieceOffset = pieceOffset;
|
||||
if (plan.lines.Add(blankLine)) {
|
||||
plan.lines.Last().pieceOffset = pieceOffset;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -3980,7 +3994,14 @@ char *EsTextboxGetContents(EsTextbox *textbox, size_t *_bytes, uint32_t flags) {
|
|||
buffer[position] = 0;
|
||||
EsAssert(position <= bytes);
|
||||
if (_bytes) *_bytes = position;
|
||||
return (char *) EsHeapReallocate(buffer, position + 1, false);
|
||||
|
||||
char *result = (char *) EsHeapReallocate(buffer, position + 1, false);
|
||||
|
||||
if (!result) {
|
||||
EsHeapFree(buffer);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
double EsTextboxGetContentsAsDouble(EsTextbox *textbox, uint32_t flags) {
|
||||
|
@ -4210,7 +4231,8 @@ int ProcessTextboxMarginMessage(EsElement *element, EsMessage *message) {
|
|||
textRun[1].offset = EsStringFormat(label, sizeof(label), "%d", i + textbox->firstVisibleLine + 1);
|
||||
EsTextPlanProperties properties = {};
|
||||
properties.flags = ES_TEXT_V_CENTER | ES_TEXT_H_RIGHT | ES_TEXT_ELLIPSIS | ES_TEXT_PLAN_SINGLE_USE;
|
||||
EsDrawText(painter, EsTextPlanCreate(element, &properties, bounds, label, textRun, 1), bounds, nullptr, nullptr);
|
||||
EsTextPlan *plan = EsTextPlanCreate(element, &properties, bounds, label, textRun, 1);
|
||||
if (plan) EsDrawText(painter, plan, bounds, nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4317,7 +4339,9 @@ int ProcessTextboxMessage(EsElement *element, EsMessage *message) {
|
|||
selectionProperties.caret1 = caret1;
|
||||
EsTextPlan *plan;
|
||||
|
||||
if (textRuns[1].offset) {
|
||||
if (!textRuns.Length()) {
|
||||
plan = nullptr;
|
||||
} else if (textRuns[1].offset) {
|
||||
plan = EsTextPlanCreate(element, &properties, lineBounds, line->GetBuffer(textbox), textRuns.array, textRuns.Length() - 1);
|
||||
} else {
|
||||
textRuns[1].offset = 1; // Make sure that the caret and selection is draw correctly, even on empty lines.
|
||||
|
@ -4503,6 +4527,7 @@ int ProcessTextboxMessage(EsElement *element, EsMessage *message) {
|
|||
} else if (message->type == ES_MSG_MOUSE_RIGHT_UP) {
|
||||
textbox->inRightClickDrag = false;
|
||||
EsMenu *menu = EsMenuCreate(textbox, ES_MENU_AT_CURSOR);
|
||||
if (!menu) return ES_HANDLED;
|
||||
|
||||
// TODO User customisation of menus.
|
||||
|
||||
|
@ -4613,6 +4638,7 @@ int ProcessTextboxMessage(EsElement *element, EsMessage *message) {
|
|||
|
||||
EsTextbox *EsTextboxCreate(EsElement *parent, uint64_t flags, const EsStyle *style) {
|
||||
EsTextbox *textbox = (EsTextbox *) EsHeapAllocate(sizeof(EsTextbox), true);
|
||||
if (!textbox) return nullptr;
|
||||
|
||||
if (!style) {
|
||||
if (flags & ES_TEXTBOX_MULTILINE) {
|
||||
|
@ -4767,6 +4793,10 @@ void TextboxBreadcrumbOverlayRecreate(EsTextbox *textbox) {
|
|||
EsPanel *panel = EsPanelCreate(textbox, ES_PANEL_HORIZONTAL | ES_CELL_FILL | ES_ELEMENT_NO_HOVER, ES_STYLE_BREADCRUMB_BAR_PANEL);
|
||||
textbox->overlayData = panel;
|
||||
|
||||
if (!panel) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t _buffer[256];
|
||||
EsBuffer buffer = { .out = _buffer, .bytes = sizeof(_buffer) };
|
||||
EsMessage m = { ES_MSG_TEXTBOX_GET_BREADCRUMB };
|
||||
|
@ -4780,19 +4810,22 @@ void TextboxBreadcrumbOverlayRecreate(EsTextbox *textbox) {
|
|||
|
||||
EsButton *crumb = EsButtonCreate(panel, ES_BUTTON_NOT_FOCUSABLE | ES_BUTTON_COMPACT | ES_CELL_V_FILL,
|
||||
ES_STYLE_BREADCRUMB_BAR_CRUMB, (char *) buffer.out, buffer.position);
|
||||
crumb->userData = m.getBreadcrumb.index;
|
||||
|
||||
crumb->messageUser = [] (EsElement *element, EsMessage *message) {
|
||||
if (message->type == ES_MSG_MOUSE_LEFT_CLICK) {
|
||||
EsMessage m = { ES_MSG_TEXTBOX_ACTIVATE_BREADCRUMB };
|
||||
m.activateBreadcrumb = element->userData.u;
|
||||
EsMessageSend(element->parent->parent, &m);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
if (crumb) {
|
||||
crumb->userData = m.getBreadcrumb.index;
|
||||
|
||||
return ES_HANDLED;
|
||||
};
|
||||
crumb->messageUser = [] (EsElement *element, EsMessage *message) {
|
||||
if (message->type == ES_MSG_MOUSE_LEFT_CLICK) {
|
||||
EsMessage m = { ES_MSG_TEXTBOX_ACTIVATE_BREADCRUMB };
|
||||
m.activateBreadcrumb = element->userData.u;
|
||||
EsMessageSend(element->parent->parent, &m);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ES_HANDLED;
|
||||
};
|
||||
}
|
||||
|
||||
m.getBreadcrumb.index++;
|
||||
}
|
||||
|
@ -4954,7 +4987,14 @@ void EsTextDisplaySetStyledContents(EsTextDisplay *display, const char *string,
|
|||
|
||||
display->textRuns = (EsTextRun *) EsHeapAllocate(sizeof(EsTextRun) * (runCount + 1), true);
|
||||
display->textRunCount = runCount;
|
||||
HeapDuplicate((void **) &display->contents, string, runs[runCount].offset);
|
||||
|
||||
size_t outBytes;
|
||||
HeapDuplicate((void **) &display->contents, &outBytes, string, runs[runCount].offset);
|
||||
|
||||
if (outBytes != runs[runCount].offset) {
|
||||
// TODO Handle allocation failure.
|
||||
}
|
||||
|
||||
EsMemoryCopy(display->textRuns, runs, sizeof(EsTextRun) * (runCount + 1));
|
||||
|
||||
display->usingSyntaxHighlighting = false;
|
||||
|
@ -4973,7 +5013,7 @@ void EsTextDisplaySetContents(EsTextDisplay *display, const char *string, ptrdif
|
|||
display->currentStyle->GetTextStyle(&baseStyle);
|
||||
EsRichTextParse(string, stringBytes, &display->contents, &display->textRuns, &display->textRunCount, &baseStyle);
|
||||
} else {
|
||||
HeapDuplicate((void **) &display->contents, string, stringBytes);
|
||||
HeapDuplicate((void **) &display->contents, (size_t *) &stringBytes, string, stringBytes);
|
||||
display->textRuns = (EsTextRun *) EsHeapAllocate(sizeof(EsTextRun) * 2, true);
|
||||
display->currentStyle->GetTextStyle(&display->textRuns[0].style);
|
||||
display->textRuns[1].offset = stringBytes;
|
||||
|
@ -4987,6 +5027,7 @@ void EsTextDisplaySetContents(EsTextDisplay *display, const char *string, ptrdif
|
|||
|
||||
EsTextDisplay *EsTextDisplayCreate(EsElement *parent, uint64_t flags, const EsStyle *style, const char *label, ptrdiff_t labelBytes) {
|
||||
EsTextDisplay *display = (EsTextDisplay *) EsHeapAllocate(sizeof(EsTextDisplay), true);
|
||||
if (!display) return nullptr;
|
||||
display->Initialise(parent, flags, ProcessTextDisplayMessage, style ?: UIGetDefaultStyleVariant(ES_STYLE_TEXT_LABEL, parent));
|
||||
display->cName = "text display";
|
||||
if (labelBytes == -1) labelBytes = EsCStringLength(label);
|
||||
|
@ -5100,7 +5141,7 @@ int ProcessListDisplayMessage(EsElement *element, EsMessage *message) {
|
|||
bounds.t += child->offsetY;
|
||||
bounds.b = bounds.t + child->height;
|
||||
EsTextPlan *plan = EsTextPlanCreate(element, &properties, bounds, buffer, textRun, 1);
|
||||
EsDrawText(message->painter, plan, bounds);
|
||||
if (plan) EsDrawText(message->painter, plan, bounds);
|
||||
bounds.t -= child->offsetY;
|
||||
counter++;
|
||||
}
|
||||
|
@ -5115,6 +5156,7 @@ int ProcessListDisplayMessage(EsElement *element, EsMessage *message) {
|
|||
|
||||
EsListDisplay *EsListDisplayCreate(EsElement *parent, uint64_t flags, const EsStyle *style) {
|
||||
EsListDisplay *display = (EsListDisplay *) EsHeapAllocate(sizeof(EsListDisplay), true);
|
||||
if (!display) return nullptr;
|
||||
display->Initialise(parent, flags, ProcessListDisplayMessage, style ?: ES_STYLE_LIST_DISPLAY_DEFAULT);
|
||||
display->cName = "list display";
|
||||
return display;
|
||||
|
|
|
@ -2074,14 +2074,21 @@ void UIStyle::PaintText(EsPainter *painter, EsElement *element, EsRectangle rect
|
|||
size_t textRunCount;
|
||||
EsRichTextParse(text, textBytes, &string, &textRuns, &textRunCount, &textRun[0].style);
|
||||
EsTextPlan *plan = EsTextPlanCreate(element, &properties, textBounds, string, textRuns, textRunCount);
|
||||
EsDrawText(painter, plan, textBounds, nullptr, selectionProperties);
|
||||
EsTextPlanDestroy(plan);
|
||||
|
||||
if (plan) {
|
||||
EsDrawText(painter, plan, textBounds, nullptr, selectionProperties);
|
||||
EsTextPlanDestroy(plan);
|
||||
}
|
||||
|
||||
EsHeapFree(textRuns);
|
||||
EsHeapFree(string);
|
||||
} else {
|
||||
EsTextPlan *plan = EsTextPlanCreate(element, &properties, textBounds, text, textRun, 1);
|
||||
PaintTextLayers(painter, plan, textBounds, selectionProperties);
|
||||
EsTextPlanDestroy(plan);
|
||||
|
||||
if (plan) {
|
||||
PaintTextLayers(painter, plan, textBounds, selectionProperties);
|
||||
EsTextPlanDestroy(plan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -328,8 +328,12 @@ ES_EXTERN_C ACPI_STATUS AcpiOsExecute(ACPI_EXECUTE_TYPE type, ACPI_OSD_EXEC_CALL
|
|||
KernelPanic("AcpiOsExecute - Exceeded maximum event count, 256.\n");
|
||||
}
|
||||
|
||||
acpiEvents[acpiEventCount++] = thread;
|
||||
return AE_OK;
|
||||
if (thread) {
|
||||
acpiEvents[acpiEventCount++] = thread;
|
||||
return AE_OK;
|
||||
} else {
|
||||
return AE_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
ES_EXTERN_C void AcpiOsSleep(UINT64 ms) {
|
||||
|
|
|
@ -202,6 +202,7 @@ EsError KLoadELF(KNode *node, KLoadedExecutable *executable) {
|
|||
if (header.instructionSet != 0x3E) return ES_ERROR_UNSUPPORTED_EXECUTABLE;
|
||||
|
||||
ElfProgramHeader *programHeaders = (ElfProgramHeader *) EsHeapAllocate(programHeaderEntrySize * header.programHeaderEntries, false, K_PAGED);
|
||||
if (!programHeaders) return ES_ERROR_INSUFFICIENT_RESOURCES;
|
||||
EsDefer(EsHeapFree(programHeaders, 0, K_PAGED));
|
||||
|
||||
bytesRead = FSFileReadSync(node, (uint8_t *) programHeaders, executableOffset + header.programHeaderTable, programHeaderEntrySize * header.programHeaderEntries, 0);
|
||||
|
|
|
@ -1182,7 +1182,7 @@ void FSNodeCloseHandle(KNode *node, uint32_t flags) {
|
|||
// Spawn a thread to unmount it.
|
||||
fileSystem->unmounting = true;
|
||||
__sync_fetch_and_add(&fs.fileSystemsUnmounting, 1);
|
||||
KThreadCreate("FSUnmount", FSUnmountFileSystem, (uintptr_t) fileSystem);
|
||||
KThreadCreate("FSUnmount", FSUnmountFileSystem, (uintptr_t) fileSystem); // TODO What should happen if creating the thread fails?
|
||||
}
|
||||
|
||||
if (deleted) {
|
||||
|
@ -1799,6 +1799,11 @@ void FSDetectFileSystem(KBlockDevice *device) {
|
|||
}
|
||||
|
||||
uint8_t *information = (uint8_t *) EsHeapAllocate(sectorsToRead * device->sectorSize, false, K_FIXED);
|
||||
|
||||
if (!information) {
|
||||
return;
|
||||
}
|
||||
|
||||
device->information = information;
|
||||
|
||||
KDMABuffer dmaBuffer = { (uintptr_t) information };
|
||||
|
|
|
@ -1982,16 +1982,12 @@ void *Pool::Add(size_t _elementSize) {
|
|||
|
||||
void *address;
|
||||
|
||||
#if 1
|
||||
if (cacheEntries) {
|
||||
address = cache[--cacheEntries];
|
||||
EsMemoryZero(address, elementSize);
|
||||
} else {
|
||||
address = EsHeapAllocate(elementSize, true, K_FIXED);
|
||||
}
|
||||
#else
|
||||
address = EsHeapAllocate(elementSize, true);
|
||||
#endif
|
||||
|
||||
return address;
|
||||
}
|
||||
|
|
|
@ -195,6 +195,10 @@ namespace POSIX {
|
|||
KMutexAcquire(&threadPOSIXDataMutex);
|
||||
if (!currentThread->posixData) currentThread->posixData = (POSIXThread *) EsHeapAllocate(sizeof(POSIXThread), true, K_FIXED);
|
||||
KMutexRelease(&threadPOSIXDataMutex);
|
||||
|
||||
if (!currentThread->posixData) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentThread->posixData->forkProcess) {
|
||||
|
@ -260,7 +264,7 @@ namespace POSIX {
|
|||
}
|
||||
|
||||
file->path = (char *) EsHeapAllocate(pathLength + 1, true, K_FIXED);
|
||||
EsMemoryCopy(file->path, path, pathLength);
|
||||
if (file->path) EsMemoryCopy(file->path, path, pathLength);
|
||||
|
||||
if ((flags & O_TRUNC) && file->type == POSIX_FILE_NORMAL) {
|
||||
FSFileResize(file->node, 0);
|
||||
|
@ -278,7 +282,7 @@ namespace POSIX {
|
|||
SYSCALL_BUFFER_POSIX(syscall.arguments[1], syscall.arguments[2], 2, true);
|
||||
KMutexAcquire(&file->mutex);
|
||||
EsDefer(KMutexRelease(&file->mutex));
|
||||
int length = EsCStringLength(file->path);
|
||||
int length = file->path ? EsCStringLength(file->path) : 0;
|
||||
if (length > syscall.arguments[2]) length = syscall.arguments[2];
|
||||
EsMemoryZero((void *) syscall.arguments[1], syscall.arguments[2]);
|
||||
EsMemoryCopy((void *) syscall.arguments[1], file->path, length);
|
||||
|
|
|
@ -378,6 +378,7 @@ Thread *Scheduler::SpawnThread(const char *cName, uintptr_t startAddress, uintpt
|
|||
if (terminating) return nullptr;
|
||||
|
||||
Thread *thread = (Thread *) threadPool.Add(sizeof(Thread));
|
||||
if (!thread) return nullptr;
|
||||
KernelLog(LOG_INFO, "Scheduler", "spawn thread", "Created thread, %x to start at %x\n", thread, startAddress);
|
||||
thread->isKernelThread = !userland;
|
||||
thread->priority = (flags & SPAWN_THREAD_LOW_PRIORITY) ? THREAD_PRIORITY_LOW : THREAD_PRIORITY_NORMAL;
|
||||
|
|
|
@ -1454,6 +1454,11 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_SYSTEM_TAKE_SNAPSHOT) {
|
|||
KSpinlockRelease(&scheduler.lock);
|
||||
|
||||
buffer = EsHeapAllocate(bufferSize, true, K_FIXED);
|
||||
|
||||
if (!buffer) {
|
||||
SYSCALL_RETURN(ES_ERROR_INSUFFICIENT_RESOURCES, false);
|
||||
}
|
||||
|
||||
EsMemoryZero(buffer, bufferSize);
|
||||
|
||||
KSpinlockAcquire(&scheduler.lock);
|
||||
|
|
|
@ -880,6 +880,12 @@ char *EsStringAllocateAndFormatV(size_t *bytes, const char *format, va_list argu
|
|||
|
||||
if (bytes) *bytes = needed;
|
||||
char *buffer = (char *) EsHeapAllocate(needed + 1, false);
|
||||
|
||||
if (!buffer) {
|
||||
if (bytes) *bytes = 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char *position = buffer;
|
||||
buffer[needed] = 0;
|
||||
|
||||
|
@ -1625,6 +1631,11 @@ size_t EsPathFindUniqueName(char *buffer, size_t originalBytes, size_t bufferByt
|
|||
}
|
||||
|
||||
char *buffer2 = (char *) EsHeapAllocate(bufferBytes, false);
|
||||
|
||||
if (!buffer2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
EsDefer(EsHeapFree(buffer2));
|
||||
|
||||
uintptr_t attempt = 2;
|
||||
|
|
|
@ -1524,6 +1524,10 @@ namespace Calculator {
|
|||
|
||||
if (!allocationPool) {
|
||||
allocationPool = (char *) EsHeapAllocate(CALCULATOR_PARSER_ALLOCATION_POOL_SIZE, false);
|
||||
|
||||
if (!allocationPool) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void *pointer = allocationPool + allocatedBytes;
|
||||
|
|
Loading…
Reference in New Issue