From f5cf248cd25db65ef066feab86c8897e1ce2e4e0 Mon Sep 17 00:00:00 2001 From: nakst <> Date: Fri, 31 Dec 2021 15:19:44 +0000 Subject: [PATCH] launch installed application if already installed in run temporary; remove apps/test.cpp --- apps/test.cpp | 292 -------------------------------------------- apps/test.ini | 9 -- desktop/desktop.cpp | 30 +++-- 3 files changed, 18 insertions(+), 313 deletions(-) delete mode 100644 apps/test.cpp delete mode 100644 apps/test.ini diff --git a/apps/test.cpp b/apps/test.cpp deleted file mode 100644 index 0add923..0000000 --- a/apps/test.cpp +++ /dev/null @@ -1,292 +0,0 @@ -// This file is part of the Essence operating system. -// It is released under the terms of the MIT license -- see LICENSE.md. -// Written by: nakst. - -#include -#include - -// #include - -EsTextbox *textbox; - -#if 0 - -char *master; -char **undo; - -void OffsetToLineAndByte(uintptr_t offset, int32_t *_line, int32_t *_byte) { - int32_t line = 0, byte = 0; - - for (uintptr_t i = 0; i < offset; i++) { - if (master[i] == '\n') { - line++; - byte = 0; - } else { - byte++; - } - } - - *_line = line; - *_byte = byte; -} - -void Compare() { - size_t bytes; - char *contents = EsTextboxGetContents(textbox, &bytes); - // EsPrint("\tContents: '%e'\n\tMaster: '%e'\n", bytes, contents, arrlenu(master), master); - EsAssert(bytes == arrlenu(master)); - EsAssert(0 == EsMemoryCompare(master, contents, bytes)); - EsHeapFree(contents); -} - -void FakeUndoItem(const void *, EsUndoManager *manager, EsMessage *message) { - if (message->type == ES_MSG_UNDO_INVOKE) { - EsUndoPush(manager, FakeUndoItem, nullptr, 0); - } -} - -void AddUndoItem() { - char *copy = nullptr; - arrsetlen(copy, arrlenu(master)); - EsMemoryCopy(copy, master, arrlenu(copy)); - arrput(undo, copy); -} - -void Complete() { - EsUndoPush(textbox->instance->undoManager, FakeUndoItem, nullptr, 0); - EsUndoEndGroup(textbox->instance->undoManager); -} - -void Insert(uintptr_t offset, const char *string, size_t stringBytes) { - if (!stringBytes) return; - AddUndoItem(); - // EsPrint("Insert '%e' at %d.\n", stringBytes, string, offset); - int32_t line, byte; - OffsetToLineAndByte(offset, &line, &byte); - EsTextboxSetSelection(textbox, line, byte, line, byte); - EsTextboxInsert(textbox, string, stringBytes); - arrinsn(master, offset, stringBytes); - EsMemoryCopy(master + offset, string, stringBytes); - Compare(); - Complete(); -} - -void Delete(uintptr_t from, uintptr_t to) { - if (from == to) return; - AddUndoItem(); - // EsPrint("Delete from %d to %d.\n", from, to); - int32_t fromLine, fromByte, toLine, toByte; - OffsetToLineAndByte(from, &fromLine, &fromByte); - OffsetToLineAndByte(to, &toLine, &toByte); - EsTextboxSetSelection(textbox, fromLine, fromByte, toLine, toByte); - EsTextboxInsert(textbox, 0, 0); - if (to > from) arrdeln(master, from, to - from); - else arrdeln(master, to, from - to); - Compare(); - Complete(); -} - -void Test() { - EsRandomSeed(10); - EsTextboxSetUndoManager(textbox, textbox->instance->undoManager); - - while (true) { - uint8_t action = EsRandomU8(); - - if (action < 0x70) { - size_t stringBytes = EsRandomU8() & 0x1F; - char string[0x20]; - - for (uintptr_t i = 0; i < stringBytes; i++) { - string[i] = EsRandomU8() < 0x40 ? '\n' : ((EsRandomU8() % 26) + 'a'); - } - - Insert(EsRandomU64() % (arrlenu(master) + 1), string, stringBytes); - } else if (action < 0xE0) { - if (arrlenu(master)) { - Delete(EsRandomU64() % arrlenu(master), EsRandomU64() % arrlenu(master)); - } - } else { - if (!EsUndoIsEmpty(textbox->instance->undoManager, false)) { - // EsPrint("Undo.\n"); - EsUndoInvokeGroup(textbox->instance->undoManager, false); - arrfree(master); - master = arrlast(undo); - arrpop(undo); - Compare(); - } - } - } -} - -#endif - -const EsStyle stylePanel = { - .inherit = ES_STYLE_PANEL_WINDOW_BACKGROUND, - - .metrics = { - .mask = ES_THEME_METRICS_INSETS | ES_THEME_METRICS_GAP_MAJOR, - .insets = ES_RECT_1(20), - .gapMajor = 1, - }, -}; - -int TestCanvasMessage(EsElement *, EsMessage *message) { - if (message->type == ES_MSG_PAINT) { - size_t dataBytes; - const void *data = EsBundleFind(nullptr, "test", -1, &dataBytes); - if (data) EsDrawVectorFile(message->painter, EsPainterBoundsClient(message->painter), data, dataBytes); - - uint32_t cornerRadii[4] = { 10, 20, 30, 40 }; - EsDrawRoundedRectangle(message->painter, EsPainterBoundsClient(message->painter), 0xFF00FF00, 0xFFFF00FF, ES_RECT_1(10), cornerRadii); - } else if (message->type == ES_MSG_GET_WIDTH) { - message->measure.width = 256; - } else if (message->type == ES_MSG_GET_HEIGHT) { - message->measure.height = 256; - } - - return 0; -} - -const uint16_t daysBeforeMonthStart[] = { - 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, // Normal year. - 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, // Leap year. -}; - -uint64_t DateToLinear(const EsDateComponents *components) { - uint64_t dayCount = 365 * components->year + daysBeforeMonthStart[components->month - 1] + components->day - 1; - uint16_t year = components->month < 3 ? components->year - 1 : components->year; - dayCount += 1 + year / 4 - year / 100 + year / 400; // Add additional days for leap years, only including this year's if we're past February. - return components->millisecond + 1000 * (components->second + 60 * (components->minute + 60 * (components->hour + 24 * dayCount))); -} - -void InitialiseInstance(EsInstance *instance) { - // EsPanel *panel = EsPanelCreate(instance->window, ES_CELL_FILL, ES_STYLE_PANEL_WINDOW_DIVIDER); - // textbox = EsTextboxCreate(panel, ES_CELL_FILL | ES_TEXTBOX_ALLOW_TABS | ES_TEXTBOX_MULTILINE, ES_STYLE_TEXTBOX_NO_BORDER); - // Test(); - - EsPanel *panel = EsPanelCreate(instance->window, ES_CELL_FILL, &stylePanel); - - EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Crash (memory error)"), [] (EsInstance *, EsElement *, EsCommand *) { - EsMemoryZero((void *) 0, 1); - }); - - EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Crash (system call error)"), [] (EsInstance *, EsElement *, EsCommand *) { - EsEventSet(1); - }); - - EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Timing"), [] (EsInstance *, EsElement *element, EsCommand *) { - EsDateComponents start, end; - - EsDateNowUTC(&start); - EsPerformanceTimerPush(); - - for (uintptr_t i = 0; i < 50000000; i++) { - EsHeapFree(EsHeapAllocate(10, true)); - } - - double performanceTime = EsPerformanceTimerPop(); - EsDateNowUTC(&end); - - char message[4096]; - size_t messageBytes = EsStringFormat(message, sizeof(message), "Performance time: %F s.\nScheduler time: %F s.\n", - performanceTime, (DateToLinear(&end) - DateToLinear(&start)) / 1000.0); - EsDialogShow(element->window, "Timing results", -1, - message, messageBytes, ES_ICON_DIALOG_INFORMATION, ES_DIALOG_ALERT_OK_BUTTON); - }); - - EsButtonCreate(panel, ES_BUTTON_CHECKBOX, 0, "Checkbox"); - - EsTextboxCreate(panel); - EsTextboxCreate(panel); - - EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Alert 1"), [] (EsInstance *, EsElement *element, EsCommand *) { - EsDialog *dialog = EsDialogShow(element->window, "Rename multiple items", -1, - "Choose the format for the new names.", -1, ES_ICON_DOCUMENT_EDIT, ES_FLAGS_DEFAULT); - EsElement *contentArea = EsDialogGetContentArea(dialog); - - EsPanel *table = EsPanelCreate(contentArea, ES_PANEL_HORIZONTAL | ES_PANEL_TABLE, ES_STYLE_PANEL_FORM_TABLE); - EsPanelSetBands(table, 2); - EsTextDisplayCreate(table, ES_CELL_H_RIGHT, ES_STYLE_TEXT_LABEL, "Prefix:"); - EsTextboxInsert(EsTextboxCreate(table), "file "); - EsTextDisplayCreate(table, ES_CELL_H_RIGHT | ES_CELL_V_TOP, ES_STYLE_TEXT_RADIO_GROUP_LABEL, "Content:"); - EsPanel *radioGroup = EsPanelCreate(table, ES_PANEL_RADIO_GROUP | ES_CELL_H_EXPAND); - EsButton *button = EsButtonCreate(radioGroup, ES_BUTTON_RADIOBOX | ES_CELL_H_EXPAND, 0, "Counter"); - EsButtonSetCheck(button, ES_CHECK_CHECKED); - EsButtonCreate(radioGroup, ES_BUTTON_RADIOBOX | ES_CELL_H_EXPAND, 0, "Original name"); - EsButtonCreate(radioGroup, ES_BUTTON_RADIOBOX | ES_CELL_H_EXPAND, 0, "Date modified"); - EsTextDisplayCreate(table, ES_CELL_H_RIGHT, ES_STYLE_TEXT_LABEL, "Suffix:"); - EsTextboxCreate(table); - EsTextDisplayCreate(contentArea, ES_CELL_H_EXPAND, ES_STYLE_TEXT_PARAGRAPH, "Example: file 1.txt"); - EsDialogAddButton(dialog, ES_FLAGS_DEFAULT, 0, "Cancel"); - EsDialogAddButton(dialog, ES_BUTTON_DEFAULT, 0, "Rename all"); - }); - - EsPanel *table = EsPanelCreate(panel, ES_CELL_H_FILL | ES_PANEL_TABLE | ES_PANEL_HORIZONTAL | ES_PANEL_TABLE_H_JUSTIFY); - EsPanelSetBands(table, 3); - - for (uintptr_t i = 0; i < 8; i++) { - EsButtonCreate(table, ES_FLAGS_DEFAULT, 0, "Justified columns"); - } - -#if 0 - EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Crash"), [] (EsInstance *, EsElement *, EsCommand *) { EsAssert(false); }); - EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Hang"), [] (EsInstance *, EsElement *, EsCommand *) { while (true); }); - EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Wait"), [] (EsInstance *, EsElement *, EsCommand *) { EsSleep(8000); }); - EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Wait, then crash"), [] (EsInstance *, EsElement *, EsCommand *) { EsSleep(8000); EsAssert(false); }); - EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Wait, then exit"), [] (EsInstance *, EsElement *, EsCommand *) { EsSleep(1000); EsProcessTerminateCurrent(); }); - - EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Crash 2"), [] (EsInstance *, EsElement *, EsCommand *) { - EsSyscall(ES_SYSCALL_WAIT, 0x8000000000000000, 1, 0, 0); - }); - - EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Crash 3"), [] (EsInstance *, EsElement *, EsCommand *) { - EsSyscall(ES_SYSCALL_PRINT, 0, 16, 0, 0); - }); - - EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Crash 4"), [] (EsInstance *, EsElement *, EsCommand *) { - EsSyscall(ES_SYSCALL_WAIT, 0x0000FFFFFFFFFFFF, 1, 0, 0); - }); - - EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Crash 5"), [] (EsInstance *, EsElement *, EsCommand *) { - EsSyscall(ES_SYSCALL_WAIT, 0x00000FFFFFFFFFFF, 1, 0, 0); - }); - - EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Crash 6"), [] (EsInstance *, EsElement *, EsCommand *) { - EsMemoryCopy(nullptr, nullptr, 1); - }); -#endif - - EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Move file"), [] (EsInstance *, EsElement *, EsCommand *) { - EsPathMove("0:/A Study in Scarlet.txt", -1, "0:/moved.txt", -1, ES_PATH_MOVE_ALLOW_COPY_AND_DELETE); - }); - - EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Announcement 1"), [] (EsInstance *, EsElement *element, EsCommand *) { - EsRectangle bounds = EsElementGetWindowBounds(element); - EsAnnouncementShow(element->window, ES_FLAGS_DEFAULT, (bounds.l + bounds.r) / 2, (bounds.t + bounds.b) / 2, "Hello, world!", -1); - }); - - EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Announcement 2"), [] (EsInstance *, EsElement *element, EsCommand *) { - EsRectangle bounds = EsElementGetWindowBounds(element); - EsAnnouncementShow(element->window, ES_FLAGS_DEFAULT, (bounds.l + bounds.r) / 2, (bounds.t + bounds.b) / 2, INTERFACE_STRING(DesktopApplicationStartupError)); - }); - - EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Push"); - EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Push"); - EsTextboxUseNumberOverlay(EsTextboxCreate(panel, ES_TEXTBOX_EDIT_BASED), true); - EsCustomElementCreate(panel)->messageUser = TestCanvasMessage; -} - -void _start() { - _init(); - - EsApplicationRunTemporary(EsLiteral("what")); - - while (true) { - EsMessage *message = EsMessageReceive(); - - if (message->type == ES_MSG_INSTANCE_CREATE) { - InitialiseInstance(EsInstanceCreate(message, "Test App")); - } - } -} diff --git a/apps/test.ini b/apps/test.ini deleted file mode 100644 index ddeb66d..0000000 --- a/apps/test.ini +++ /dev/null @@ -1,9 +0,0 @@ -[general] -name=Test -icon=icon_system_software_install -use_single_process=1 -permission_all_files=1 -permission_run_temporary_application=1 - -[build] -source=apps/test.cpp diff --git a/desktop/desktop.cpp b/desktop/desktop.cpp index 520923d..42d221c 100644 --- a/desktop/desktop.cpp +++ b/desktop/desktop.cpp @@ -2918,16 +2918,27 @@ void DesktopSyscall(EsMessage *message, uint8_t *buffer, EsBuffer *pipe) { InstalledApplication *requestingApplication = ApplicationFindByPID(message->desktop.processID); if (requestingApplication && (requestingApplication->permissions & APPLICATION_PERMISSION_RUN_TEMPORARY_APPLICATION)) { + for (uintptr_t i = 0; i < desktop.installedApplications.Length(); i++) { + if (EsCStringLength(desktop.installedApplications[i]->cExecutable) == message->desktop.bytes - 1 + && 0 == EsMemoryCompare(desktop.installedApplications[i]->cExecutable, buffer + 1, message->desktop.bytes - 1)) { + ApplicationInstanceCreate(desktop.installedApplications[i]->id, nullptr, nullptr); + return; + } + } + InstalledApplication *application = (InstalledApplication *) EsHeapAllocate(sizeof(InstalledApplication), true); + if (!application) return; application->temporary = true; application->hidden = true; application->useSingleProcess = true; application->cExecutable = (char *) EsHeapAllocate(message->desktop.bytes, false); + if (!application->cExecutable) { EsHeapFree(application); return; } EsMemoryCopy(application->cExecutable, buffer + 1, message->desktop.bytes - 1); application->cExecutable[message->desktop.bytes - 1] = 0; static int64_t nextTemporaryID = -1; application->id = nextTemporaryID--; application->cName = (char *) EsHeapAllocate(32, false); + if (!application->cName) { EsHeapFree(application->cExecutable); EsHeapFree(application); return; } for (int i = 1; i < 31; i++) application->cName[i] = (EsRandomU8() % 26) + 'a'; application->cName[0] = '_', application->cName[31] = 0; EsHandle handle; @@ -2936,12 +2947,7 @@ void DesktopSyscall(EsMessage *message, uint8_t *buffer, EsBuffer *pipe) { desktop.installedApplications.Add(application); ApplicationInstanceCreate(application->id, nullptr, nullptr); } - } else if (!instance) { - // ------------------------------------------------- - // | Messages below here require a valid instance. | - // ------------------------------------------------- - EsPrint("DesktopSyscall - Received message %d without an instance.\n", buffer[0]); - } else if (buffer[0] == DESKTOP_MSG_SET_TITLE || buffer[0] == DESKTOP_MSG_SET_ICON) { + } else if ((buffer[0] == DESKTOP_MSG_SET_TITLE || buffer[0] == DESKTOP_MSG_SET_ICON) && instance) { if (buffer[0] == DESKTOP_MSG_SET_TITLE) { instance->titleBytes = EsStringFormat(instance->title, sizeof(instance->title), "%s", message->desktop.bytes - 1, buffer + 1); @@ -2962,11 +2968,11 @@ void DesktopSyscall(EsMessage *message, uint8_t *buffer, EsBuffer *pipe) { instance->tab->container->taskBarButton->Repaint(true); } } - } else if (buffer[0] == DESKTOP_MSG_SET_MODIFIED && message->desktop.bytes == 2) { + } else if (buffer[0] == DESKTOP_MSG_SET_MODIFIED && message->desktop.bytes == 2 && instance) { if (instance->tab) { EsButtonSetCheck(instance->tab->closeButton, buffer[1] ? ES_CHECK_CHECKED : ES_CHECK_UNCHECKED, false); } - } else if (buffer[0] == DESKTOP_MSG_SET_PROGRESS && message->desktop.bytes == 1 + sizeof(double) && instance->isUserTask) { + } else if (buffer[0] == DESKTOP_MSG_SET_PROGRESS && message->desktop.bytes == 1 + sizeof(double) && instance->isUserTask && instance) { double progress; EsMemoryCopy(&progress, buffer + 1, sizeof(double)); @@ -2975,9 +2981,9 @@ void DesktopSyscall(EsMessage *message, uint8_t *buffer, EsBuffer *pipe) { instance->progress = progress; EsElementRepaint(desktop.tasksButton); } - } else if (buffer[0] == DESKTOP_MSG_REQUEST_SAVE) { + } else if (buffer[0] == DESKTOP_MSG_REQUEST_SAVE && instance) { ApplicationInstanceRequestSave(instance, (const char *) buffer + 1, message->desktop.bytes - 1, false); - } else if (buffer[0] == DESKTOP_MSG_RENAME) { + } else if (buffer[0] == DESKTOP_MSG_RENAME && instance) { const char *newName = (const char *) buffer + 1; size_t newNameBytes = message->desktop.bytes - 1; OpenDocument *document = desktop.openDocuments.Get(&instance->documentID); @@ -3013,9 +3019,9 @@ void DesktopSyscall(EsMessage *message, uint8_t *buffer, EsBuffer *pipe) { EsHeapFree(oldPath); EsHeapFree(newPath); } - } else if (buffer[0] == DESKTOP_MSG_COMPLETE_SAVE) { + } else if (buffer[0] == DESKTOP_MSG_COMPLETE_SAVE && instance) { ApplicationInstanceCompleteSave(instance); - } else if (buffer[0] == DESKTOP_MSG_SHOW_IN_FILE_MANAGER) { + } else if (buffer[0] == DESKTOP_MSG_SHOW_IN_FILE_MANAGER && instance) { // TODO Don't open a new instance if the folder is already open? OpenDocument *document = desktop.openDocuments.Get(&instance->documentID);