diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..c34e84e89 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,100 @@ +version: 2 + +# Keeps the pinned action SHAs moving. +# +# Every action reference under .github/workflows is a 40-character commit SHA +# with the version in a trailing comment. A SHA pin *without* this file is worse +# than a floating tag: it freezes CI on whatever was current the day it was +# written. This repository is the case study. Nothing had ever reported that an +# action moved, so actions/upload-artifact sat on v3.1.3 in all four Windows +# workflows -- four majors behind, and a version GitHub began auto-failing on +# 2025-01-30. actions/checkout sat on an unpinned @v4, three majors behind. +# +# Dependabot understands the SHA form and rewrites the trailing version comment +# together with the pin, so the comment cannot drift away from the SHA it +# describes. That is what keeps "which exact code ran in our CI" answerable from +# the repository, which the SBOM and certification work needs on its own. +# +# This follows the pattern set by eclipse-threadx/threadx, which added the same +# configuration in August 2026 after the same drift was measured there. +# +# What this does not fix: it reports drift, not silence. A workflow that never +# triggers rots unnoticed no matter what is pinned in it, and this repository had +# that failure in its more severe form -- the four Windows workflows requested +# runs-on: windows-2019 for more than a year after GitHub retired that image, so +# every run queued for 24 hours and was cancelled without reaching a runner. No +# amount of pinning would have said so. The runner image fix is a separate +# change; this file is the drift half only. +# +# There is no entry for any other ecosystem, and that is a decision rather than +# an oversight: the project forbids external dependencies and there are no +# submodules. The one pinned toolchain input -- the Windows SDK version passed +# to VsDevCmd in scripts/build_guix_studio.cmd -- lives in a batch file that no +# Dependabot ecosystem can parse. That pin moves by hand. +updates: + - package-ecosystem: "github-actions" + # "/" is the only accepted value for this ecosystem; it covers + # .github/workflows and .github/actions. The cross-repository reusable + # workflow in regression_test.yml + # (eclipse-threadx/threadx/.github/workflows/regression_template.yml@master) + # is correctly left alone: it references a branch, not a version, so there + # is nothing for Dependabot to move. Tracking that branch is deliberate -- + # it is first-party, in the same organisation, and it means this repository + # picks up harness fixes without a bump here. + directory: "/" + + schedule: + interval: "weekly" + day: "monday" + time: "06:00" + timezone: "Etc/UTC" + + # Dependabot reads this file from the repository's DEFAULT branch, which is + # master. But master is deliberately kept behind dev, and pull requests + # belong on dev. target-branch sends the pull requests to dev and makes + # Dependabot read the workflows it is updating from dev as well. + # + # The consequence to plan for: landing this file on dev arms it, it does not + # fire it. Nothing happens until a release merge carries it to master. + # + # Setting target-branch also opts out of Dependabot *security* updates, + # which only ever run against the default branch. For this ecosystem the + # cost is small -- an action advisory arrives as an ordinary version bump on + # the weekly run -- but it is a real trade and not a detail to rediscover + # later. + target-branch: "dev" + + groups: + # Patch and minor arrive together in one pull request: they are the + # routine traffic, and reviewing them one at a time is how an update queue + # starts being ignored, which is the failure mode this file exists to + # prevent. Majors stay ungrouped, one pull request each, because every + # breaking change met in an action here has been a major: upload-artifact + # v4 stopped allowing an artifact name to be uploaded twice in a run, and + # v6 requires a runner of 2.327.1 or newer. + actions-minor-and-patch: + patterns: + - "*" + update-types: + - "minor" + - "patch" + + # Only three distinct actions are in use today -- actions/checkout, + # actions/upload-artifact and EnricoMi/publish-unit-test-result-action -- so + # the default limit of five would be enough for now. Ten is set to match the + # sibling repositories and to leave room for a wave of majors after a long + # gap, which is exactly the situation this file is being added into. + open-pull-requests-limit: 10 + + # This repository has no "dependencies" label yet; Dependabot creates it on + # the first pull request. + labels: + - "dependencies" + + # Reviewers are not listed. Unlike eclipse-threadx/threadx this repository + # has no .github/CODEOWNERS, so there is no path routing for Dependabot to + # honour. Adding one is worth doing, but it is not this file's job. + # + # Commit subjects are left at Dependabot's own "Bump x from a to b" wording. + # The project asks for a past-tense subject and still gets one: these pull + # requests are squash-merged, and the subject is set at that point. diff --git a/.github/workflows/studio_demo_test.yml b/.github/workflows/studio_demo_test.yml index 1acc41033..ac48a7d75 100644 --- a/.github/workflows/studio_demo_test.yml +++ b/.github/workflows/studio_demo_test.yml @@ -6,19 +6,22 @@ # https://opensource.org/licenses/MIT. # # SPDX-License-Identifier: MIT +# Some portions generated by Claude Code (Opus 5). # This is a basic workflow that is manually triggered name: GUIX Studio Demo Test -# Controls when the action will run. Triggers the workflow on push or pull request -# events but only for the master branch +# Controls when the action will run. dev is included deliberately: it is the +# integration branch, so a master-only trigger gated no pull request that +# anybody opened. Verified green on a runner before being switched on -- +# 227 of 227 generation tests and 212 of 212 compile tests. on: - workflow_dispatch: + workflow_dispatch: push: - branches: [ master ] + branches: [ master, dev ] pull_request: - branches: [ master ] + branches: [ master, dev ] # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: @@ -31,12 +34,21 @@ jobs: pull-requests: write # The type of runner that the job will run on - runs-on: windows-2019 + # Pinned deliberately rather than windows-latest: the image this job + # needs has to be a reviewable commit, not something that changes + # underneath the build. windows-2019 sat here until 2026-08-26, more + # than a year after GitHub retired that image, so every run queued for + # 24 hours and was then cancelled without ever reaching a runner. + runs-on: windows-2022 # Steps represent a sequence of tasks that will be executed as part of the job steps: + # Actions are pinned to a commit SHA, with the version in the trailing + # comment. A tag can be moved; a SHA cannot, so this is what makes "which + # code ran in CI" answerable from the repository. Dependabot moves these + # pins and rewrites the comment with them -- see .github/dependabot.yml. - name: Check out the repository - uses: actions/checkout@v4 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: submodules: true @@ -47,7 +59,7 @@ jobs: run: scripts\test_studio_demo.cmd - name: Publish Test Results - uses: EnricoMi/publish-unit-test-result-action/composite@v2 + uses: EnricoMi/publish-unit-test-result-action/composite@d0a4676d0e0b938bc201470d88276b7c74c712b3 # v2.24.0 if: always() with: check_name: Test Results GUIX Studio Demo @@ -56,7 +68,7 @@ jobs: - name: Upload Test Results if: success() || failure() - uses: actions/upload-artifact@v3.1.3 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: test_reports path: | diff --git a/.github/workflows/studio_demo_test_compile.yml b/.github/workflows/studio_demo_test_compile.yml index 897eb3fcd..a5c9142c9 100644 --- a/.github/workflows/studio_demo_test_compile.yml +++ b/.github/workflows/studio_demo_test_compile.yml @@ -6,19 +6,22 @@ # https://opensource.org/licenses/MIT. # # SPDX-License-Identifier: MIT +# Some portions generated by Claude Code (Opus 5). # This is a basic workflow that is manually triggered name: GUIX Studio Demo Compile Test -# Controls when the action will run. Triggers the workflow on push or pull request -# events but only for the master branch +# Controls when the action will run. dev is included deliberately: it is the +# integration branch, so a master-only trigger gated no pull request that +# anybody opened. Verified green on a runner before being switched on -- +# 227 of 227 generation tests and 212 of 212 compile tests. on: - workflow_dispatch: + workflow_dispatch: push: - branches: [ master ] + branches: [ master, dev ] pull_request: - branches: [ master ] + branches: [ master, dev ] # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: @@ -31,12 +34,21 @@ jobs: pull-requests: write # The type of runner that the job will run on - runs-on: windows-2019 + # Pinned deliberately rather than windows-latest: the image this job + # needs has to be a reviewable commit, not something that changes + # underneath the build. windows-2019 sat here until 2026-08-26, more + # than a year after GitHub retired that image, so every run queued for + # 24 hours and was then cancelled without ever reaching a runner. + runs-on: windows-2022 # Steps represent a sequence of tasks that will be executed as part of the job steps: + # Actions are pinned to a commit SHA, with the version in the trailing + # comment. A tag can be moved; a SHA cannot, so this is what makes "which + # code ran in CI" answerable from the repository. Dependabot moves these + # pins and rewrites the comment with them -- see .github/dependabot.yml. - name: Check out the repository - uses: actions/checkout@v4 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: submodules: true @@ -47,7 +59,7 @@ jobs: run: scripts\test_studio_demo_compile.cmd - name: Publish Test Results - uses: EnricoMi/publish-unit-test-result-action/composite@v2 + uses: EnricoMi/publish-unit-test-result-action/composite@d0a4676d0e0b938bc201470d88276b7c74c712b3 # v2.24.0 if: always() with: check_name: Test Results GUIX Studio Demo Compile @@ -56,7 +68,7 @@ jobs: - name: Upload Test Results if: success() || failure() - uses: actions/upload-artifact@v3.1.3 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: test_reports path: | diff --git a/.github/workflows/studio_msix_package.yml b/.github/workflows/studio_msix_package.yml index 2ff833560..cce0d49da 100644 --- a/.github/workflows/studio_msix_package.yml +++ b/.github/workflows/studio_msix_package.yml @@ -6,6 +6,7 @@ # https://opensource.org/licenses/MIT. # # SPDX-License-Identifier: MIT +# Some portions generated by Claude Code (Opus 5). # This is a basic workflow that is manually triggered @@ -26,12 +27,21 @@ jobs: pull-requests: write # The type of runner that the job will run on - runs-on: windows-2019 + # Pinned deliberately rather than windows-latest: the image this job + # needs has to be a reviewable commit, not something that changes + # underneath the build. windows-2019 sat here until 2026-08-26, more + # than a year after GitHub retired that image, so every run queued for + # 24 hours and was then cancelled without ever reaching a runner. + runs-on: windows-2022 # Steps represent a sequence of tasks that will be executed as part of the job steps: + # Actions are pinned to a commit SHA, with the version in the trailing + # comment. A tag can be moved; a SHA cannot, so this is what makes "which + # code ran in CI" answerable from the repository. Dependabot moves these + # pins and rewrites the comment with them -- see .github/dependabot.yml. - name: Check out the repository - uses: actions/checkout@v4 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: submodules: true @@ -39,9 +49,9 @@ jobs: run: scripts/build_guix_studio_msix_package.cmd - name: Upload GUIX Studio package upload file - uses: actions/upload-artifact@v3.1.3 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: GUIXStudioPackages - path: guix_studio/build/vs_2019/msix_package_project/AppPackages + path: guix_studio/build/vs_2022/msix_package_project/AppPackages \ No newline at end of file diff --git a/.github/workflows/studio_view_test.yml b/.github/workflows/studio_view_test.yml index dac9be92d..cc4b2cb2d 100644 --- a/.github/workflows/studio_view_test.yml +++ b/.github/workflows/studio_view_test.yml @@ -6,6 +6,7 @@ # https://opensource.org/licenses/MIT. # # SPDX-License-Identifier: MIT +# Some portions generated by Claude Code (Opus 5). # This is a basic workflow that is manually triggered @@ -31,12 +32,21 @@ jobs: pull-requests: write # The type of runner that the job will run on - runs-on: windows-2019 + # Pinned deliberately rather than windows-latest: the image this job + # needs has to be a reviewable commit, not something that changes + # underneath the build. windows-2019 sat here until 2026-08-26, more + # than a year after GitHub retired that image, so every run queued for + # 24 hours and was then cancelled without ever reaching a runner. + runs-on: windows-2022 # Steps represent a sequence of tasks that will be executed as part of the job steps: + # Actions are pinned to a commit SHA, with the version in the trailing + # comment. A tag can be moved; a SHA cannot, so this is what makes "which + # code ran in CI" answerable from the repository. Dependabot moves these + # pins and rewrites the comment with them -- see .github/dependabot.yml. - name: Check out the repository - uses: actions/checkout@v4 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: submodules: true @@ -47,7 +57,7 @@ jobs: run: scripts\test_studio_view.cmd - name: Publish Test Results - uses: EnricoMi/publish-unit-test-result-action/composite@v2 + uses: EnricoMi/publish-unit-test-result-action/composite@d0a4676d0e0b938bc201470d88276b7c74c712b3 # v2.24.0 if: always() with: check_name: Test Results GUIX Studio View @@ -56,7 +66,7 @@ jobs: - name: Upload Test Results if: success() || failure() - uses: actions/upload-artifact@v3.1.3 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: test_reports path: | diff --git a/common/inc/gx_api.h b/common/inc/gx_api.h index 7e3e4e94a..b47dc46f3 100644 --- a/common/inc/gx_api.h +++ b/common/inc/gx_api.h @@ -61,7 +61,7 @@ extern "C" { #define GUIX_MINOR_VERSION 5 #define GUIX_PATCH_VERSION 1 #define GUIX_BUILD_VERSION 202602 -#define GUIX_HOTFIX_VERSION ' ' +#define GUIX_HOTFIX_VERSION 'a' /* The following symbols are defined for backward compatibility reasons.*/ #define __PRODUCT_GUIX__ @@ -132,6 +132,10 @@ typedef struct GX_STRING_STRUCT #ifndef GX_DISABLE_DEPRECATED_STRING_API #define GX_ENABLE_DEPRECATED_STRING_API +#pragma message("GUIX deprecated string API is enabled. The pre-5.6 char* string " \ + "functions do not carry a length and are unsafe with non-NUL-terminated " \ + "buffers. Define GX_DISABLE_DEPRECATED_STRING_API and migrate to the " \ + "GX_STRING-based (_ext) variants.") #endif #if defined(GX_THREADX_BINDING) diff --git a/common/src/gx_animation_drag_tracking_start.c b/common/src/gx_animation_drag_tracking_start.c index bc12163d4..105c60d15 100644 --- a/common/src/gx_animation_drag_tracking_start.c +++ b/common/src/gx_animation_drag_tracking_start.c @@ -9,6 +9,7 @@ * SPDX-License-Identifier: MIT **************************************************************************/ // Some portions generated by Copilot (Claude Sonnet 4.6). +// Some portions generated by Claude Code (Opus 5). /**************************************************************************/ @@ -77,7 +78,7 @@ INT current_pos; GX_WINDOW_ROOT *root; GX_VALUE left; GX_VALUE top; -UINT status; +UINT draw_status; VOID (*active_display_area_set)(INT layer, GX_RECTANGLE *size); info = &animation -> gx_animation_info; @@ -285,8 +286,16 @@ VOID (*active_display_area_set)(INT layer, GX_RECTANGLE *size); /* and show the animation root window to make everything visible */ _gx_widget_show((GX_WIDGET *)root); - status = _gx_canvas_drawing_initiate(animation -> gx_animation_canvas, (GX_WIDGET *)root, &root -> gx_widget_size); - if (status == GX_SUCCESS || status == GX_NO_VIEWS) + /* The drawing status is deliberately kept out of the completion + status of this function: _gx_widget_show() above releases the + view list of the animation root window, so + _gx_canvas_drawing_initiate() reports GX_NO_VIEWS here. */ + draw_status = _gx_canvas_drawing_initiate(animation -> gx_animation_canvas, (GX_WIDGET *)root, &root -> gx_widget_size); + + /* Draw and complete only when a draw context was actually pushed. + GX_DRAW_NESTING_EXCEEDED means no context was pushed, so calling + _gx_canvas_drawing_complete() would corrupt the outer context. */ + if ((draw_status == GX_SUCCESS) || (draw_status == GX_NO_VIEWS)) { _gx_widget_children_draw((GX_WIDGET *)root); _gx_canvas_drawing_complete(animation -> gx_animation_canvas, GX_FALSE); diff --git a/common/src/gx_animation_start.c b/common/src/gx_animation_start.c index 61c2882b7..7392ca6a7 100644 --- a/common/src/gx_animation_start.c +++ b/common/src/gx_animation_start.c @@ -9,6 +9,7 @@ * SPDX-License-Identifier: MIT **************************************************************************/ // Some portions generated by Copilot (Claude Sonnet 4.6). +// Some portions generated by Claude Code (Opus 5). /**************************************************************************/ @@ -79,6 +80,7 @@ UINT _gx_animation_start(GX_ANIMATION *animation, GX_ANIMATION_INFO *info) { UINT status = GX_SUCCESS; +UINT draw_status; GX_WINDOW_ROOT *root; #ifdef GX_THREADX_BINDING @@ -122,8 +124,20 @@ GX_VALUE top; /* and show the animation root window to make everything visible */ _gx_widget_show((GX_WIDGET *)root); - status = _gx_canvas_drawing_initiate(animation -> gx_animation_canvas, (GX_WIDGET *) root, &root -> gx_widget_size); - if (status == GX_SUCCESS || status == GX_NO_VIEWS) + /* Keep the drawing status separate from the completion status returned + by this function. _gx_widget_show() above releases the view list of + the animation root window, so _gx_canvas_drawing_initiate() reports + GX_NO_VIEWS here. That is expected for an animation canvas and must + neither be returned to the caller nor prevent the animation from + being linked into the active list below. */ + draw_status = _gx_canvas_drawing_initiate(animation -> gx_animation_canvas, (GX_WIDGET *) root, &root -> gx_widget_size); + + /* Draw and complete only when a draw context was actually pushed. + GX_DRAW_NESTING_EXCEEDED means no context was pushed, so calling + _gx_canvas_drawing_complete() would corrupt the outer context. The + children of a root window with no views are still drawn, matching + the behaviour of _gx_system_canvas_refresh(). */ + if ((draw_status == GX_SUCCESS) || (draw_status == GX_NO_VIEWS)) { _gx_widget_children_draw((GX_WIDGET *)root); _gx_canvas_drawing_complete(animation -> gx_animation_canvas, GX_FALSE); diff --git a/common/src/gx_multi_line_text_input_draw.c b/common/src/gx_multi_line_text_input_draw.c index 7554906d1..8a6b6f96e 100644 --- a/common/src/gx_multi_line_text_input_draw.c +++ b/common/src/gx_multi_line_text_input_draw.c @@ -9,6 +9,7 @@ * SPDX-License-Identifier: MIT **************************************************************************/ // Some portions generated by Copilot (Claude Sonnet 4.6). +// Some portions generated by Claude Code (Opus 5). /**************************************************************************/ @@ -102,6 +103,8 @@ GX_VALUE client_width; GX_SCROLLBAR *scroll; GX_VALUE space_width; UINT status; +GX_DRAW_CONTEXT *context; +GX_RECTANGLE saved_dirty; if (input -> gx_widget_style & GX_STYLE_ENABLED) { @@ -205,10 +208,26 @@ UINT status; /* Offset client area by the size of whitespace. */ _gx_utility_rectangle_resize(&client, (GX_VALUE)(-input -> gx_multi_line_text_view_whitespace)); - _gx_utility_rectangle_overlap_detect(&_gx_system_current_draw_context -> gx_draw_context_dirty, &client, &draw_area); + /* Remember the current context and its clipping rectangle, in case the + draw context stack turns out to be full. */ + context = _gx_system_current_draw_context; + saved_dirty = context -> gx_draw_context_dirty; + + _gx_utility_rectangle_overlap_detect(&saved_dirty, &client, &draw_area); status = _gx_canvas_drawing_initiate(canvas, (GX_WIDGET *)input, &draw_area); - if (status == GX_SUCCESS) + if (status == GX_DRAW_NESTING_EXCEEDED) + { + /* The context stack is full, so no context was pushed. The context + that would have been pushed is created for this same widget, so + it differs from the current one only in its clipping rectangle. + Narrow the current context's clipping rectangle instead and draw + through it, rather than dropping the text. The rectangle is + restored once the text is drawn. */ + context -> gx_draw_context_dirty = draw_area; + } + + if ((status == GX_SUCCESS) || (status == GX_DRAW_NESTING_EXCEEDED)) { /* Pickup text height. */ line_height = (GX_VALUE)(font -> gx_font_line_height + input -> gx_multi_line_text_view_line_space); @@ -364,12 +383,29 @@ UINT status; } } - _gx_canvas_drawing_complete(canvas, GX_FALSE); + if (status == GX_SUCCESS) + { + _gx_canvas_drawing_complete(canvas, GX_FALSE); + } + else + { + /* Nothing was pushed, so _gx_canvas_drawing_complete() must + not be called: it would pop the caller's context. Restore + the clipping rectangle borrowed above instead. */ + context -> gx_draw_context_dirty = saved_dirty; + } } else if (status == GX_NO_VIEWS) { _gx_canvas_drawing_complete(canvas, GX_FALSE); } + else + { + /* Any other status, such as GX_INVALID_MEMORY_SIZE when drawing + into a partial frame buffer, is also returned before a context + is pushed, so there is nothing to draw and nothing to + complete. */ + } } } diff --git a/common/src/gx_multi_line_text_input_text_set.c b/common/src/gx_multi_line_text_input_text_set.c index 3d2db862d..acb4ed823 100644 --- a/common/src/gx_multi_line_text_input_text_set.c +++ b/common/src/gx_multi_line_text_input_text_set.c @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Claude Code (Opus 5). + /**************************************************************************/ /**************************************************************************/ @@ -92,7 +94,11 @@ UINT glyph_len; if (ch[0] == GX_KEY_CARRIAGE_RETURN) { - if (ch[1] == GX_KEY_LINE_FEED) + /* string now points at the byte after ch. Read it through string, so + that its length bounds the access: ch[1] would rely on the caller + having NUL terminated a GX_STRING, which carries its own length + and need not be terminated at all. */ + if ((string.gx_string_length > 0) && (string.gx_string_ptr[0] == GX_KEY_LINE_FEED)) { memcpy(text_input -> gx_multi_line_text_input_new_line_character, "\r\n", 3); /* Use case of memcpy is verified. */ text_input -> gx_multi_line_text_input_new_line_character_size = 2; diff --git a/common/src/gx_multi_line_text_view_display_info_get.c b/common/src/gx_multi_line_text_view_display_info_get.c index 127c8cb8a..4379efb58 100644 --- a/common/src/gx_multi_line_text_view_display_info_get.c +++ b/common/src/gx_multi_line_text_view_display_info_get.c @@ -1,7 +1,6 @@ /*************************************************************************** * Copyright (c) 2024 Microsoft Corporation * Copyright (c) 2026 Eclipse ThreadX contributors - * // Some portions generated by Copilot (Sonnet 4.6). * * This program and the accompanying materials are made available under the * terms of the MIT License which is available at @@ -10,6 +9,9 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Copilot (Sonnet 4.6). +// Some portions generated by Claude Code (Opus 5). + /**************************************************************************/ /**************************************************************************/ @@ -166,7 +168,12 @@ GX_FONT *font; if (ch.gx_string_ptr[0] == GX_KEY_CARRIAGE_RETURN) { - if (ch.gx_string_ptr[1] == GX_KEY_LINE_FEED) + /* string now points at the byte after ch, and its length is the + number of bytes still readable there. A GX_STRING carries its + own length and need not be NUL terminated, so the byte after a + trailing carriage return may lie outside the caller's buffer: + it must not be examined. */ + if ((string.gx_string_length > 0) && (string.gx_string_ptr[0] == GX_KEY_LINE_FEED)) { text_info -> gx_text_display_number = (USHORT)(text_info -> gx_text_display_number + 2); } @@ -197,6 +204,33 @@ GX_FONT *font; string.gx_string_ptr++; string.gx_string_length--; } + + /* If that whitespace ran to the end of the source line, take the + line terminator with it. Left behind, the terminator becomes a + row of its own, which draws as a blank line that is not present + in the text. */ + if (string.gx_string_length > 0) + { + if (string.gx_string_ptr[0] == GX_KEY_CARRIAGE_RETURN) + { + text_info -> gx_text_display_number++; + + if ((string.gx_string_length > 1) && (string.gx_string_ptr[1] == GX_KEY_LINE_FEED)) + { + text_info -> gx_text_display_number++; + } + } + else if (string.gx_string_ptr[0] == GX_KEY_LINE_FEED) + { + text_info -> gx_text_display_number++; + } + else + { + /* More text follows the whitespace, so the next row starts + at the next word. */ + } + } + break; } if (display_number == 0) diff --git a/common/src/gx_multi_line_text_view_text_draw.c b/common/src/gx_multi_line_text_view_text_draw.c index d63709c7f..186ffc125 100644 --- a/common/src/gx_multi_line_text_view_text_draw.c +++ b/common/src/gx_multi_line_text_view_text_draw.c @@ -9,6 +9,7 @@ * SPDX-License-Identifier: MIT **************************************************************************/ // Some portions generated by Copilot (Claude Sonnet 4.6). +// Some portions generated by Claude Code (Opus 5). /**************************************************************************/ @@ -115,6 +116,8 @@ GX_VALUE client_width; GX_FONT *font; GX_SCROLLBAR *scroll; UINT status; +GX_DRAW_CONTEXT *context; +GX_RECTANGLE saved_dirty; #if defined(GX_DYNAMIC_BIDI_TEXT_SUPPORT) GX_BIDI_RESOLVED_TEXT_INFO *next = GX_NULL; @@ -187,10 +190,25 @@ UINT bidi_text_line_index = 0; text_view -> gx_multi_line_text_view_text_scroll_shift = (space_width >> 1); } - _gx_utility_rectangle_overlap_detect(&_gx_system_current_draw_context -> gx_draw_context_dirty, &client, &draw_area); + /* Remember the current context and its clipping rectangle, in case the draw + context stack turns out to be full. */ + context = _gx_system_current_draw_context; + saved_dirty = context -> gx_draw_context_dirty; + + _gx_utility_rectangle_overlap_detect(&saved_dirty, &client, &draw_area); status = _gx_canvas_drawing_initiate(canvas, (GX_WIDGET *)text_view, &draw_area); - if (status == GX_SUCCESS) + if (status == GX_DRAW_NESTING_EXCEEDED) + { + /* The context stack is full, so no context was pushed. The context that + would have been pushed is created for this same widget, so it differs + from the current one only in its clipping rectangle. Narrow the current + context's clipping rectangle instead and draw through it, rather than + dropping the text. The rectangle is restored once the text is drawn. */ + context -> gx_draw_context_dirty = draw_area; + } + + if ((status == GX_SUCCESS) || (status == GX_DRAW_NESTING_EXCEEDED)) { /* Compute the start displaying position of pixels in x direction and y direction. */ y_pos = client.gx_rectangle_top; @@ -310,11 +328,27 @@ UINT bidi_text_line_index = 0; y_pos += line_height; } - _gx_canvas_drawing_complete(canvas, GX_FALSE); + if (status == GX_SUCCESS) + { + _gx_canvas_drawing_complete(canvas, GX_FALSE); + } + else + { + /* Nothing was pushed, so _gx_canvas_drawing_complete() must not be + called: it would pop the caller's context. Restore the clipping + rectangle borrowed above instead. */ + context -> gx_draw_context_dirty = saved_dirty; + } } else if (status == GX_NO_VIEWS) { _gx_canvas_drawing_complete(canvas, GX_FALSE); } + else + { + /* Any other status, such as GX_INVALID_MEMORY_SIZE when drawing into a + partial frame buffer, is also returned before a context is pushed, so + there is nothing to draw and nothing to complete. */ + } } diff --git a/common/src/gx_rich_text_view_text_draw.c b/common/src/gx_rich_text_view_text_draw.c index 9ecc2e180..6da05aa84 100644 --- a/common/src/gx_rich_text_view_text_draw.c +++ b/common/src/gx_rich_text_view_text_draw.c @@ -9,6 +9,7 @@ * SPDX-License-Identifier: MIT **************************************************************************/ // Some portions generated by Copilot (Claude Sonnet 4.6). +// Some portions generated by Claude Code (Opus 5). /**************************************************************************/ @@ -307,6 +308,8 @@ GX_VALUE ypos; GX_CANVAS *canvas; GX_RECTANGLE draw_area; UINT status; +GX_DRAW_CONTEXT *context; +GX_RECTANGLE saved_dirty; if (!text_view -> gx_multi_line_text_view_text.gx_string_length) { @@ -377,10 +380,25 @@ UINT status; /* pick up current canvas */ canvas = _gx_system_current_draw_context -> gx_draw_context_canvas; - _gx_utility_rectangle_overlap_detect(&_gx_system_current_draw_context -> gx_draw_context_dirty, &client, &draw_area); + /* Remember the current context and its clipping rectangle, in case the draw + context stack turns out to be full. */ + context = _gx_system_current_draw_context; + saved_dirty = context -> gx_draw_context_dirty; + + _gx_utility_rectangle_overlap_detect(&saved_dirty, &client, &draw_area); status = _gx_canvas_drawing_initiate(canvas, (GX_WIDGET *)text_view, &draw_area); - if (status == GX_SUCCESS) + if (status == GX_DRAW_NESTING_EXCEEDED) + { + /* The context stack is full, so no context was pushed. The context that + would have been pushed is created for this same widget, so it differs + from the current one only in its clipping rectangle. Narrow the current + context's clipping rectangle instead and draw through it, rather than + dropping the text. The rectangle is restored once the text is drawn. */ + context -> gx_draw_context_dirty = draw_area; + } + + if ((status == GX_SUCCESS) || (status == GX_DRAW_NESTING_EXCEEDED)) { /* Calculate the total rows of text view string. */ while (text.gx_string_length > 0) @@ -430,12 +448,28 @@ UINT status; text.gx_string_ptr += line_info.gx_rich_text_line_info_text.gx_string_length; text.gx_string_length -= line_info.gx_rich_text_line_info_text.gx_string_length; } - _gx_canvas_drawing_complete(canvas, GX_FALSE); + if (status == GX_SUCCESS) + { + _gx_canvas_drawing_complete(canvas, GX_FALSE); + } + else + { + /* Nothing was pushed, so _gx_canvas_drawing_complete() must not be + called: it would pop the caller's context. Restore the clipping + rectangle borrowed above instead. */ + context -> gx_draw_context_dirty = saved_dirty; + } } else if (status == GX_NO_VIEWS) { _gx_canvas_drawing_complete(canvas, GX_FALSE); } + else + { + /* Any other status, such as GX_INVALID_MEMORY_SIZE when drawing into a + partial frame buffer, is also returned before a context is pushed, so + there is nothing to draw and nothing to complete. */ + } _gx_rich_text_view_context_reset(); } diff --git a/common/src/gx_single_line_text_input_draw.c b/common/src/gx_single_line_text_input_draw.c index 356cd63a0..11a7c2ca9 100644 --- a/common/src/gx_single_line_text_input_draw.c +++ b/common/src/gx_single_line_text_input_draw.c @@ -9,6 +9,7 @@ * SPDX-License-Identifier: MIT **************************************************************************/ // Some portions generated by Copilot (Claude Sonnet 4.6). +// Some portions generated by Claude Code (Opus 5). /**************************************************************************/ @@ -107,6 +108,8 @@ GX_VALUE text_width; GX_BRUSH *brush; GX_CHAR *input_buffer = text_input -> gx_single_line_text_input_buffer; GX_STRING string; +GX_DRAW_CONTEXT *context; +GX_RECTANGLE saved_dirty; /* Draw text input background. */ if (text_input -> gx_widget_style & GX_STYLE_ENABLED) @@ -150,10 +153,26 @@ GX_STRING string; /* pick up current canvas */ canvas = _gx_system_current_draw_context -> gx_draw_context_canvas; - _gx_utility_rectangle_overlap_detect(&_gx_system_current_draw_context -> gx_draw_context_dirty, &client, &overlap); + + /* Remember the current context and its clipping rectangle, in case the draw + context stack turns out to be full. */ + context = _gx_system_current_draw_context; + saved_dirty = context -> gx_draw_context_dirty; + + _gx_utility_rectangle_overlap_detect(&saved_dirty, &client, &overlap); status = _gx_canvas_drawing_initiate(canvas, widget, &overlap); - if (status == GX_SUCCESS) + if (status == GX_DRAW_NESTING_EXCEEDED) + { + /* The context stack is full, so no context was pushed. The context that + would have been pushed is created for this same widget, so it differs + from the current one only in its clipping rectangle. Narrow the current + context's clipping rectangle instead and draw through it, rather than + dropping the text. The rectangle is restored once the text is drawn. */ + context -> gx_draw_context_dirty = overlap; + } + + if ((status == GX_SUCCESS) || (status == GX_DRAW_NESTING_EXCEEDED)) { /* Draw the cursor. */ if ((start_mark == end_mark) && @@ -237,12 +256,28 @@ GX_STRING string; } } - _gx_canvas_drawing_complete(canvas, GX_FALSE); + if (status == GX_SUCCESS) + { + _gx_canvas_drawing_complete(canvas, GX_FALSE); + } + else + { + /* Nothing was pushed, so _gx_canvas_drawing_complete() must not be + called: it would pop the caller's context. Restore the clipping + rectangle borrowed above instead. */ + context -> gx_draw_context_dirty = saved_dirty; + } } else if (status == GX_NO_VIEWS) { _gx_canvas_drawing_complete(canvas, GX_FALSE); } + else + { + /* Any other status, such as GX_INVALID_MEMORY_SIZE when drawing into a + partial frame buffer, is also returned before a context is pushed, so + there is nothing to draw and nothing to complete. */ + } _gx_widget_children_draw(widget); } diff --git a/guix_studio/StudioXProject.cpp b/guix_studio/StudioXProject.cpp index 527878a9d..517a99537 100644 --- a/guix_studio/StudioXProject.cpp +++ b/guix_studio/StudioXProject.cpp @@ -9,6 +9,7 @@ * SPDX-License-Identifier: MIT **************************************************************************/ // Some portions generated by Codex (OpenAI GPT-5.5). +// Some portions generated by Claude Code (Opus 5). #include "system_pngs.h" @@ -254,10 +255,10 @@ FONT_RECORD DEFAULT_FONT_TABLE[] = { {NULL, -1, NULL} }; -extern IMAGE_INFO _system_png_radio_on; -extern IMAGE_INFO _system_png_radio_off; -extern IMAGE_INFO _system_png_checkbox_on; -extern IMAGE_INFO _system_png_checkbox_off; +extern STUDIO_IMAGE_INFO _system_png_radio_on; +extern STUDIO_IMAGE_INFO _system_png_radio_off; +extern STUDIO_IMAGE_INFO _system_png_checkbox_on; +extern STUDIO_IMAGE_INFO _system_png_checkbox_off; // FIXME: do we want to use hardcoded path? PIXELMAP_RECORD DEFAULT_PIXELMAP_TABLE[] = { @@ -1521,7 +1522,7 @@ BOOL studiox_project::InitializeOnePixelmap(res_info *info, palette_info *theme_ image_reader *pReader = NULL; CString abspath; - IMAGE_INFO *default_image_info = NULL; + STUDIO_IMAGE_INFO *default_image_info = NULL; int frame_count = 1; int frame_id = -1; diff --git a/guix_studio/build/vs_2022/msix_package_project/Package.appxmanifest b/guix_studio/build/vs_2022/msix_package_project/Package.appxmanifest index 7d782ee47..f5405142c 100644 --- a/guix_studio/build/vs_2022/msix_package_project/Package.appxmanifest +++ b/guix_studio/build/vs_2022/msix_package_project/Package.appxmanifest @@ -22,7 +22,7 @@ + Version="6.5.1.03" /> Eclipse ThreadX GUIX Studio diff --git a/guix_studio/installer/guix_installer_release.iss b/guix_studio/installer/guix_installer_release.iss index 49d50a06b..5bf79a43d 100644 --- a/guix_studio/installer/guix_installer_release.iss +++ b/guix_studio/installer/guix_installer_release.iss @@ -11,7 +11,7 @@ ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! #ifndef StudioFullVersion -#define StudioFullVersion "6.5.1.202602" +#define StudioFullVersion "6.5.1.202602a" #endif #ifndef StudioShortVersion #define StudioShortVersion "6.5.1" @@ -20,7 +20,7 @@ #define StudioMajorMinorVersion "6.5" #endif #ifndef StudioVersionInfoVersion -#define StudioVersionInfoVersion "6.5.1.2" +#define StudioVersionInfoVersion "6.5.1.3" #endif [Setup] diff --git a/guix_studio/ports/gx_port.h b/guix_studio/ports/gx_port.h index c384508e3..c77e062b3 100644 --- a/guix_studio/ports/gx_port.h +++ b/guix_studio/ports/gx_port.h @@ -193,7 +193,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Win32/Visual Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Win32/Visual Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/guix_studio/resource_gen.cpp b/guix_studio/resource_gen.cpp index 5be93459d..cc24e35ab 100644 --- a/guix_studio/resource_gen.cpp +++ b/guix_studio/resource_gen.cpp @@ -9,6 +9,7 @@ * SPDX-License-Identifier: MIT **************************************************************************/ // Some portions generated by Codex (OpenAI GPT-5.5). +// Some portions generated by Claude Code (Opus 5). @@ -4156,7 +4157,7 @@ GX_PIXELMAP* resource_gen::RotatePixelmap(res_info* info, int theme_id, GX_PIXEL image_reader *pReader = NULL; CString abspath; - IMAGE_INFO* default_image_info = NULL; + STUDIO_IMAGE_INFO* default_image_info = NULL; int frame_count = 1; if (info->is_default && info->pathinfo.pathname.IsEmpty()) diff --git a/guix_studio/resource_view.h b/guix_studio/resource_view.h index f0296d399..8c6dcc452 100644 --- a/guix_studio/resource_view.h +++ b/guix_studio/resource_view.h @@ -8,6 +8,7 @@ * * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Claude Code (Opus 5). @@ -16,7 +17,7 @@ #include class resource_view_provider; -struct IMAGE_INFO; +struct STUDIO_IMAGE_INFO; struct COLOR_RECORD { char *name; @@ -34,7 +35,7 @@ struct PIXELMAP_RECORD { char *name; int pixelmap_id; BOOL include_alpha; - IMAGE_INFO *image_info; + STUDIO_IMAGE_INFO *image_info; }; struct font_table { diff --git a/guix_studio/screen_generator.cpp b/guix_studio/screen_generator.cpp index f7a944f13..61be10f45 100644 --- a/guix_studio/screen_generator.cpp +++ b/guix_studio/screen_generator.cpp @@ -9,6 +9,7 @@ * SPDX-License-Identifier: MIT **************************************************************************/ // Some portions generated by Codex (OpenAI GPT-5.5). +// Some portions generated by Claude Code (Opus 5). #include "studiox_includes.h" #ifdef _DEBUG @@ -1395,6 +1396,17 @@ CString out(""); /* Set output file to the default file: Empty means default output file. */ SetOutFile(out); + /* Write the prototypes of the static screen flow helpers. Declaring them up + front keeps the generated file compliant with projects that require a + visible prototype for every function definition. */ + out = "static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action);\n" + "static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action);\n" + "#if (GX_ANIMATION_POOL_SIZE > 0)\n" + "static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action);\n" + "static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action);\n" + "#endif\n\n"; + FileWrite(out); + out = "static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action)\n" "{\n" " GX_WIDGET *parent = GX_NULL;\n" @@ -1460,7 +1472,12 @@ CString out(""); "}\n\n"; FileWrite(out); - out = "static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action)\n" + /* gx_studio_action_parent_find() and gx_studio_animation_execute() are only + reachable from the GX_ACTION_TYPE_ANIMATION handler, and they reference the + animation API which is compiled out when the animation pool is empty. Guard + both so that a screen flow project builds with GX_ANIMATION_POOL_SIZE = 0. */ + out = "#if (GX_ANIMATION_POOL_SIZE > 0)\n" + "static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action)\n" "{\n" "GX_WIDGET *parent = GX_NULL;\n" "GX_STUDIO_WIDGET *widget_define;\n\n" @@ -1530,7 +1547,8 @@ CString out(""); " gx_animation_start(animation, &animation_info);\n" " }\n" " }\n" - "}\n\n"; + "}\n" + "#endif\n\n"; FileWrite(out); out = "UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record)\n" @@ -1610,9 +1628,11 @@ CString out(""); " gx_widget_hide(target);\n" " }\n" " break;\n\n" + "#if (GX_ANIMATION_POOL_SIZE > 0)\n" " case GX_ACTION_TYPE_ANIMATION:\n" " gx_studio_animation_execute(widget, action);\n" - " break;\n\n" + " break;\n" + "#endif\n\n" " case GX_ACTION_TYPE_WINDOW_EXECUTE:\n" " parent = widget->gx_widget_parent;\n" " target = gx_studio_action_target_get(widget, action);\n" @@ -1697,9 +1717,11 @@ CString out(""); " gx_widget_hide(target);\n" " }\n" " break;\n\n" + "#if (GX_ANIMATION_POOL_SIZE > 0)\n" " case GX_ACTION_TYPE_ANIMATION:\n" " gx_studio_animation_execute(widget, action);\n" - " break;\n\n" + " break;\n" + "#endif\n\n" " case GX_ACTION_TYPE_WINDOW_EXECUTE:\n" " if((action->flags & GX_ACTION_FLAG_POP_TARGET) ||\n" " (action->flags & GX_ACTION_FLAG_POP_PARENT))\n" diff --git a/guix_studio/studiox.rc b/guix_studio/studiox.rc index e1947836b..e65446258 100644 --- a/guix_studio/studiox.rc +++ b/guix_studio/studiox.rc @@ -1767,8 +1767,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 6,5,1,2 - PRODUCTVERSION 6,5,1,2 + FILEVERSION 6,5,1,3 + PRODUCTVERSION 6,5,1,3 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -1785,12 +1785,12 @@ BEGIN BEGIN VALUE "CompanyName", "Eclipse Foundation" VALUE "FileDescription", "GUIX Studio Application" - VALUE "FileVersion", "6.5.1.202602" + VALUE "FileVersion", "6.5.1.202602a" VALUE "InternalName", "studiox.exe" VALUE "LegalCopyright", "(c) Eclipse ThreadX contributors" VALUE "OriginalFilename", "studiox.exe" VALUE "ProductName", "Eclipse ThreadX GUIX Studio" - VALUE "ProductVersion", "6.5.1.202602" + VALUE "ProductVersion", "6.5.1.202602a" END END BLOCK "VarFileInfo" diff --git a/guix_studio/system_pngs.cpp b/guix_studio/system_pngs.cpp index f78df6074..b4fd771cb 100644 --- a/guix_studio/system_pngs.cpp +++ b/guix_studio/system_pngs.cpp @@ -8,6 +8,7 @@ * * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Claude Code (Opus 5). #include "system_pngs.h" @@ -112,22 +113,22 @@ static unsigned char SYSTEM_PNG_CHECKBOX_OFF_pixelmap_data[519] = 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; -IMAGE_INFO _system_png_radio_on = { +STUDIO_IMAGE_INFO _system_png_radio_on = { SYSTEM_PNG_RADIO_ON_pixelmap_data, sizeof(SYSTEM_PNG_RADIO_ON_pixelmap_data) }; -IMAGE_INFO _system_png_radio_off = { +STUDIO_IMAGE_INFO _system_png_radio_off = { SYSTEM_PNG_RADIO_OFF_pixelmap_data, sizeof(SYSTEM_PNG_RADIO_ON_pixelmap_data) }; -IMAGE_INFO _system_png_checkbox_on = { +STUDIO_IMAGE_INFO _system_png_checkbox_on = { SYSTEM_PNG_CHECKBOX_ON_pixelmap_data, sizeof(SYSTEM_PNG_CHECKBOX_ON_pixelmap_data) }; -IMAGE_INFO _system_png_checkbox_off = { +STUDIO_IMAGE_INFO _system_png_checkbox_off = { SYSTEM_PNG_CHECKBOX_OFF_pixelmap_data, sizeof(SYSTEM_PNG_CHECKBOX_OFF_pixelmap_data) }; \ No newline at end of file diff --git a/guix_studio/system_pngs.h b/guix_studio/system_pngs.h index 910499c09..1b3cff036 100644 --- a/guix_studio/system_pngs.h +++ b/guix_studio/system_pngs.h @@ -8,11 +8,12 @@ * * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Claude Code (Opus 5). #ifndef _SYSTEM_PNGS_ #define _SYSTEM_PNGS_ -struct IMAGE_INFO { +struct STUDIO_IMAGE_INFO { unsigned char* data; int data_len; }; diff --git a/ports/arc_em/metaware/inc/gx_port.h b/ports/arc_em/metaware/inc/gx_port.h index f215b1f4b..01aa24127 100644 --- a/ports/arc_em/metaware/inc/gx_port.h +++ b/ports/arc_em/metaware/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX ARCv2_EM/MetaWare Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX ARCv2_EM/MetaWare Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/arc_hs/metaware/inc/gx_port.h b/ports/arc_hs/metaware/inc/gx_port.h index 6fce23adb..b65b97043 100644 --- a/ports/arc_hs/metaware/inc/gx_port.h +++ b/ports/arc_hs/metaware/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX ARC_HS/MetaWare Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX ARC_HS/MetaWare Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/arm9/ac5/inc/gx_port.h b/ports/arm9/ac5/inc/gx_port.h index 03d32f6d0..2379034b1 100644 --- a/ports/arm9/ac5/inc/gx_port.h +++ b/ports/arm9/ac5/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX ARM9/AC5 Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX ARM9/AC5 Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/arm9/gnu/inc/gx_port.h b/ports/arm9/gnu/inc/gx_port.h index 09437bde8..14faebe45 100644 --- a/ports/arm9/gnu/inc/gx_port.h +++ b/ports/arm9/gnu/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX ARM9/GNU Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX ARM9/GNU Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/arm9/iar/inc/gx_port.h b/ports/arm9/iar/inc/gx_port.h index ceb8ac33e..a2266679b 100644 --- a/ports/arm9/iar/inc/gx_port.h +++ b/ports/arm9/iar/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX ARM9/IAR Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX ARM9/IAR Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/c667x/ccs/inc/gx_port.h b/ports/c667x/ccs/inc/gx_port.h index c58ab63b8..15ed57ef4 100644 --- a/ports/c667x/ccs/inc/gx_port.h +++ b/ports/c667x/ccs/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX C6xxx/TI Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX C6xxx/TI Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/ccrx/inc/gx_port.h b/ports/ccrx/inc/gx_port.h index 9f833ae1d..8c0ae1eee 100644 --- a/ports/ccrx/inc/gx_port.h +++ b/ports/ccrx/inc/gx_port.h @@ -140,7 +140,7 @@ typedef unsigned char GX_UCHAR; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_a15/gnu/inc/gx_port.h b/ports/cortex_a15/gnu/inc/gx_port.h index 354a64459..9d7776cb7 100644 --- a/ports/cortex_a15/gnu/inc/gx_port.h +++ b/ports/cortex_a15/gnu/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A15/GNU Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A15/GNU Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_a5/ac5/inc/gx_port.h b/ports/cortex_a5/ac5/inc/gx_port.h index 14f3657f1..4f9f726d6 100644 --- a/ports/cortex_a5/ac5/inc/gx_port.h +++ b/ports/cortex_a5/ac5/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A5/AC5 Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A5/AC5 Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_a5/gnu/inc/gx_port.h b/ports/cortex_a5/gnu/inc/gx_port.h index f6f052a28..c8bc7e737 100644 --- a/ports/cortex_a5/gnu/inc/gx_port.h +++ b/ports/cortex_a5/gnu/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A5/GNU Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A5/GNU Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_a5/iar/inc/gx_port.h b/ports/cortex_a5/iar/inc/gx_port.h index a2884e9ca..eeeeb1064 100644 --- a/ports/cortex_a5/iar/inc/gx_port.h +++ b/ports/cortex_a5/iar/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A5/IAR Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A5/IAR Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_a5x/ac6/inc/gx_port.h b/ports/cortex_a5x/ac6/inc/gx_port.h index 10b146001..f7be078d8 100644 --- a/ports/cortex_a5x/ac6/inc/gx_port.h +++ b/ports/cortex_a5x/ac6/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A5x/AC6 Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A5x/AC6 Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_a7/ac5/inc/gx_port.h b/ports/cortex_a7/ac5/inc/gx_port.h index a47d02e12..12f77f60e 100644 --- a/ports/cortex_a7/ac5/inc/gx_port.h +++ b/ports/cortex_a7/ac5/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A7/AC5 Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A7/AC5 Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_a7/gnu/inc/gx_port.h b/ports/cortex_a7/gnu/inc/gx_port.h index a086ef590..b9c451d62 100644 --- a/ports/cortex_a7/gnu/inc/gx_port.h +++ b/ports/cortex_a7/gnu/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A7/GNU Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A7/GNU Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_a7/iar/inc/gx_port.h b/ports/cortex_a7/iar/inc/gx_port.h index 514edb6b6..dabdbc50b 100644 --- a/ports/cortex_a7/iar/inc/gx_port.h +++ b/ports/cortex_a7/iar/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A7/IAR Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A7/IAR Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_a8/ac5/inc/gx_port.h b/ports/cortex_a8/ac5/inc/gx_port.h index af8048882..5d0ee0a2e 100644 --- a/ports/cortex_a8/ac5/inc/gx_port.h +++ b/ports/cortex_a8/ac5/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A8/AC5 Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A8/AC5 Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_a8/gnu/inc/gx_port.h b/ports/cortex_a8/gnu/inc/gx_port.h index 5f75c4ce1..011ccc268 100644 --- a/ports/cortex_a8/gnu/inc/gx_port.h +++ b/ports/cortex_a8/gnu/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A8/GNU Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A8/GNU Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_a8/iar/inc/gx_port.h b/ports/cortex_a8/iar/inc/gx_port.h index 6423e0b5a..2490244eb 100644 --- a/ports/cortex_a8/iar/inc/gx_port.h +++ b/ports/cortex_a8/iar/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A8/IAR Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A8/IAR Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_a9/ac5/inc/gx_port.h b/ports/cortex_a9/ac5/inc/gx_port.h index c6a472806..798bba73f 100644 --- a/ports/cortex_a9/ac5/inc/gx_port.h +++ b/ports/cortex_a9/ac5/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A9/AC5 Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A9/AC5 Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_a9/gnu/inc/gx_port.h b/ports/cortex_a9/gnu/inc/gx_port.h index 2c995e1df..c97ab73a7 100644 --- a/ports/cortex_a9/gnu/inc/gx_port.h +++ b/ports/cortex_a9/gnu/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A9/GNU Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A9/GNU Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_a9/iar/inc/gx_port.h b/ports/cortex_a9/iar/inc/gx_port.h index 5f00bef53..9a38832f6 100644 --- a/ports/cortex_a9/iar/inc/gx_port.h +++ b/ports/cortex_a9/iar/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A9/IAR Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-A9/IAR Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_m0/ac5/inc/gx_port.h b/ports/cortex_m0/ac5/inc/gx_port.h index e75d59876..ebb977928 100644 --- a/ports/cortex_m0/ac5/inc/gx_port.h +++ b/ports/cortex_m0/ac5/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M0/AC5 Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M0/AC5 Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_m0/gnu/inc/gx_port.h b/ports/cortex_m0/gnu/inc/gx_port.h index c65bf03b2..56689e65b 100644 --- a/ports/cortex_m0/gnu/inc/gx_port.h +++ b/ports/cortex_m0/gnu/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M0/GNU Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M0/GNU Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_m0/iar/inc/gx_port.h b/ports/cortex_m0/iar/inc/gx_port.h index 2a537f936..2f441d8f5 100644 --- a/ports/cortex_m0/iar/inc/gx_port.h +++ b/ports/cortex_m0/iar/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M0/IAR Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M0/IAR Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_m3/ac5/inc/gx_port.h b/ports/cortex_m3/ac5/inc/gx_port.h index bb2dd4a63..089b9bba3 100644 --- a/ports/cortex_m3/ac5/inc/gx_port.h +++ b/ports/cortex_m3/ac5/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M3/AC5 Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M3/AC5 Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_m3/gnu/inc/gx_port.h b/ports/cortex_m3/gnu/inc/gx_port.h index f08ec1ec2..8183bd8c7 100644 --- a/ports/cortex_m3/gnu/inc/gx_port.h +++ b/ports/cortex_m3/gnu/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M3/GNU Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M3/GNU Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_m3/iar/inc/gx_port.h b/ports/cortex_m3/iar/inc/gx_port.h index 9e478d411..f46a80955 100644 --- a/ports/cortex_m3/iar/inc/gx_port.h +++ b/ports/cortex_m3/iar/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M3/IAR Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M3/IAR Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_m3/keil/inc/gx_port.h b/ports/cortex_m3/keil/inc/gx_port.h index f2b8f7b16..27d2e85b8 100644 --- a/ports/cortex_m3/keil/inc/gx_port.h +++ b/ports/cortex_m3/keil/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M3/KEIL Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M3/KEIL Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_m4/ac5/inc/gx_port.h b/ports/cortex_m4/ac5/inc/gx_port.h index 35644488b..74b66fca5 100644 --- a/ports/cortex_m4/ac5/inc/gx_port.h +++ b/ports/cortex_m4/ac5/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M4/AC5 Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M4/AC5 Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_m4/gnu/inc/gx_port.h b/ports/cortex_m4/gnu/inc/gx_port.h index dae91ac3d..ba1cfb2eb 100644 --- a/ports/cortex_m4/gnu/inc/gx_port.h +++ b/ports/cortex_m4/gnu/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M4/GNU Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M4/GNU Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_m4/iar/inc/gx_port.h b/ports/cortex_m4/iar/inc/gx_port.h index 79353116e..2564b5897 100644 --- a/ports/cortex_m4/iar/inc/gx_port.h +++ b/ports/cortex_m4/iar/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M4/IAR Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M4/IAR Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_m4/keil/inc/gx_port.h b/ports/cortex_m4/keil/inc/gx_port.h index fd633b547..485250b73 100644 --- a/ports/cortex_m4/keil/inc/gx_port.h +++ b/ports/cortex_m4/keil/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M4/KEIL Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M4/KEIL Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_m7/ac5/inc/gx_port.h b/ports/cortex_m7/ac5/inc/gx_port.h index e59174306..34d1dd7e4 100644 --- a/ports/cortex_m7/ac5/inc/gx_port.h +++ b/ports/cortex_m7/ac5/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M7/AC5 Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M7/AC5 Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_m7/gnu/inc/gx_port.h b/ports/cortex_m7/gnu/inc/gx_port.h index cf5a57c34..da31dcd95 100644 --- a/ports/cortex_m7/gnu/inc/gx_port.h +++ b/ports/cortex_m7/gnu/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M7/GNU Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M7/GNU Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_m7/iar/inc/gx_port.h b/ports/cortex_m7/iar/inc/gx_port.h index 9d68cf35c..1ab1da137 100644 --- a/ports/cortex_m7/iar/inc/gx_port.h +++ b/ports/cortex_m7/iar/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M7/IAR Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-M7/IAR Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_r4/ac5/inc/gx_port.h b/ports/cortex_r4/ac5/inc/gx_port.h index 1499b62e1..a25231550 100644 --- a/ports/cortex_r4/ac5/inc/gx_port.h +++ b/ports/cortex_r4/ac5/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-R4/AC5 Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-R4/AC5 Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_r4/ac6/inc/gx_port.h b/ports/cortex_r4/ac6/inc/gx_port.h index 668dc3825..1faaba1d2 100644 --- a/ports/cortex_r4/ac6/inc/gx_port.h +++ b/ports/cortex_r4/ac6/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-R4/AC6 Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-R4/AC6 Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_r4/gnu/inc/gx_port.h b/ports/cortex_r4/gnu/inc/gx_port.h index 7691829a0..0af060f64 100644 --- a/ports/cortex_r4/gnu/inc/gx_port.h +++ b/ports/cortex_r4/gnu/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-R4/GNU Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-R4/GNU Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_r4/iar/inc/gx_port.h b/ports/cortex_r4/iar/inc/gx_port.h index 6aae85a48..1b3af8f08 100644 --- a/ports/cortex_r4/iar/inc/gx_port.h +++ b/ports/cortex_r4/iar/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-R4/IAR Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-R4/IAR Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_r5/ac5/inc/gx_port.h b/ports/cortex_r5/ac5/inc/gx_port.h index 6d7572281..a15636b1c 100644 --- a/ports/cortex_r5/ac5/inc/gx_port.h +++ b/ports/cortex_r5/ac5/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-R5/AC5 Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-R5/AC5 Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_r5/gnu/inc/gx_port.h b/ports/cortex_r5/gnu/inc/gx_port.h index 641cc3da9..7e7db2303 100644 --- a/ports/cortex_r5/gnu/inc/gx_port.h +++ b/ports/cortex_r5/gnu/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-R5/GNU Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-R5/GNU Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/cortex_r5/iar/inc/gx_port.h b/ports/cortex_r5/iar/inc/gx_port.h index 47d668f45..08de499e0 100644 --- a/ports/cortex_r5/iar/inc/gx_port.h +++ b/ports/cortex_r5/iar/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-R5/IAR Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Cortex-R5/IAR Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/generic/inc/gx_port.h b/ports/generic/inc/gx_port.h index c61d880d6..4e039d0a1 100644 --- a/ports/generic/inc/gx_port.h +++ b/ports/generic/inc/gx_port.h @@ -132,7 +132,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/linux/gnu/inc/gx_port.h b/ports/linux/gnu/inc/gx_port.h index a87270bd9..d3ac3b968 100644 --- a/ports/linux/gnu/inc/gx_port.h +++ b/ports/linux/gnu/inc/gx_port.h @@ -127,7 +127,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Linux/GNU Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Linux/GNU Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/win32/inc/gx_port.h b/ports/win32/inc/gx_port.h index 7e110770b..ab31cb420 100644 --- a/ports/win32/inc/gx_port.h +++ b/ports/win32/inc/gx_port.h @@ -147,7 +147,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Win32/Visual Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Win32/Visual Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/ports/win32/vs_2019_standalone/inc/gx_port.h b/ports/win32/vs_2019_standalone/inc/gx_port.h index 3217e7615..1b21b49b5 100644 --- a/ports/win32/vs_2019_standalone/inc/gx_port.h +++ b/ports/win32/vs_2019_standalone/inc/gx_port.h @@ -90,7 +90,7 @@ typedef SHORT GX_VALUE; #ifdef GX_SYSTEM_INIT CHAR _gx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Win32/Standalone/Visual Version 6.5.1.202602 *"; + "(c) 2024 Microsoft Corp. (c) 2026 Eclipse ThreadX contributors. * GUIX Win32/Standalone/Visual Version 6.5.1.202602a *"; #else extern CHAR _gx_version_id[]; #endif diff --git a/samples/demo_guix_car_infotainment/demo_guix_car_infotainment_specifications.c b/samples/demo_guix_car_infotainment/demo_guix_car_infotainment_specifications.c index e563dd49a..540f72c85 100644 --- a/samples/demo_guix_car_infotainment/demo_guix_car_infotainment_specifications.c +++ b/samples/demo_guix_car_infotainment/demo_guix_car_infotainment_specifications.c @@ -62,6 +62,13 @@ GX_STUDIO_DISPLAY_INFO demo_guix_car_infotainment_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -127,6 +134,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -192,6 +200,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -293,9 +302,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/samples/demo_guix_home_automation/demo_guix_home_automation_specifications.c b/samples/demo_guix_home_automation/demo_guix_home_automation_specifications.c index c5762eae5..58d4930c6 100644 --- a/samples/demo_guix_home_automation/demo_guix_home_automation_specifications.c +++ b/samples/demo_guix_home_automation/demo_guix_home_automation_specifications.c @@ -76,6 +76,13 @@ GX_STUDIO_DISPLAY_INFO demo_guix_home_automation_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -141,6 +148,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -206,6 +214,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -307,9 +316,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/samples/demo_guix_industrial/demo_guix_industrial_specifications.c b/samples/demo_guix_industrial/demo_guix_industrial_specifications.c index 6c81a0c38..2dc4e2c06 100644 --- a/samples/demo_guix_industrial/demo_guix_industrial_specifications.c +++ b/samples/demo_guix_industrial/demo_guix_industrial_specifications.c @@ -60,6 +60,13 @@ GX_STUDIO_DISPLAY_INFO demo_guix_industrial_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -125,6 +132,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -190,6 +198,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -291,9 +300,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/samples/demo_guix_medical/guix_medical_specifications.c b/samples/demo_guix_medical/guix_medical_specifications.c index 2276cf085..63f6118ab 100644 --- a/samples/demo_guix_medical/guix_medical_specifications.c +++ b/samples/demo_guix_medical/guix_medical_specifications.c @@ -59,6 +59,13 @@ GX_STUDIO_DISPLAY_INFO guix_medical_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -124,6 +131,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -189,6 +197,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -290,9 +299,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/samples/demo_guix_widget_types/guix_widget_types_specifications.c b/samples/demo_guix_widget_types/guix_widget_types_specifications.c index e78e10f98..91632ee47 100644 --- a/samples/demo_guix_widget_types/guix_widget_types_specifications.c +++ b/samples/demo_guix_widget_types/guix_widget_types_specifications.c @@ -63,6 +63,13 @@ GX_STUDIO_DISPLAY_INFO guix_widget_types_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -128,6 +135,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -193,6 +201,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -294,9 +303,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/scripts/build_guix.cmd b/scripts/build_guix.cmd index 205723baa..647d4ca44 100644 --- a/scripts/build_guix.cmd +++ b/scripts/build_guix.cmd @@ -7,13 +7,26 @@ @rem @rem SPDX-License-Identifier: MIT @rem Some portions generated by Codex (OpenAI GPT-5.5). +@rem Some portions generated by Claude Code (Opus 5). -rem Initialize the developer environment just like a developer box. Note that 'call' keyword that ensures that the script does not exist after -rem calling the other batch file. -call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 +rem Initialize the developer environment just like a developer box. The Visual +rem Studio edition differs between a developer machine and a GitHub runner, so +rem locate the installation with vswhere rather than assuming an edition path. +rem Note the 'call' keyword, which ensures that this script does not exit when +rem the other batch file returns. +set "VSINSTALL=" +set "VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" +if exist "%VSWHERE%" ( + for /f "usebackq tokens=*" %%i in (`"%VSWHERE%" -latest -products * -requires Microsoft.Component.MSBuild -property installationPath`) do set "VSINSTALL=%%i" +) -rem Set Python path -SET PATH=%PATH%;"C:\Program Files\Python36";"C:\Program Files\Python36\scripts" +if not defined VSINSTALL ( + echo Visual Studio 2022 with MSBuild was not found. + exit /B 1 +) + +call "%VSINSTALL%\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 +if ERRORLEVEL 1 exit /B %ERRORLEVEL% rem Save working directory so that we can restore it back after building everything. This will make developers happy and then rem switch to the folder this script resides in. Don't assume absolute paths because on the build host and on the dev host the locations may be different. diff --git a/scripts/build_guix_studio.cmd b/scripts/build_guix_studio.cmd index 6bebc2c7d..600a05ed3 100644 --- a/scripts/build_guix_studio.cmd +++ b/scripts/build_guix_studio.cmd @@ -6,15 +6,28 @@ @rem https://opensource.org/licenses/MIT. @rem @rem SPDX-License-Identifier: MIT +@rem Some portions generated by Claude Code (Opus 5). @echo off -rem Initialize the developer environment just like a developer box. Note that 'call' keyword that ensures that the script does not exist after -rem calling the other batch file. -call "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -winsdk=10.0.22621.0 +rem Initialize the developer environment just like a developer box. The Visual +rem Studio edition differs between a developer machine and a GitHub runner, so +rem locate the installation with vswhere rather than assuming an edition path. +rem Note the 'call' keyword, which ensures that this script does not exit when +rem the other batch file returns. +set "VSINSTALL=" +set "VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" +if exist "%VSWHERE%" ( + for /f "usebackq tokens=*" %%i in (`"%VSWHERE%" -latest -products * -requires Microsoft.Component.MSBuild -property installationPath`) do set "VSINSTALL=%%i" +) -rem Set Python path. Not needed if installed with WinGet. -rem SET PATH=%PATH%;"C:\Program Files\Python36";"C:\Program Files\Python36\scripts" +if not defined VSINSTALL ( + echo Visual Studio 2022 with MSBuild was not found. + exit /B 1 +) + +call "%VSINSTALL%\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 +if ERRORLEVEL 1 exit /B %ERRORLEVEL% rem Save working directory so that we can restore it back after building everything. This will make developers happy and then rem switch to the folder this script resides in. Don't assume absolute paths because on the build host and on the dev host the locations may be different. diff --git a/scripts/guix_studio_release.psm1 b/scripts/guix_studio_release.psm1 index 14a419d0a..a892e7870 100644 --- a/scripts/guix_studio_release.psm1 +++ b/scripts/guix_studio_release.psm1 @@ -5,6 +5,7 @@ # https://opensource.org/licenses/MIT. # # SPDX-License-Identifier: MIT +# Some portions generated by Claude Code (Opus 5). function Get-StudioReleaseVersion { [CmdletBinding()] @@ -13,8 +14,8 @@ function Get-StudioReleaseVersion { [string]$Version ) - if ($Version -notmatch '^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$') { - throw "Version must use the form major.minor.patch.build, for example 6.5.1.202602." + if ($Version -notmatch '^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)([a-z]?)$') { + throw "Version must use the form major.minor.patch.build[hotfix_letter], for example 6.5.1.202602 or 6.5.1.202602a." } $major = [int]$matches[1] @@ -22,12 +23,24 @@ function Get-StudioReleaseVersion { $patch = [int]$matches[3] $buildText = $matches[4] $build = [int]$buildText + $hotfix = $matches[5] + + # The Win32 and MSIX version formats are strictly numeric, so a hotfix + # letter cannot be carried over as is. Offset the revision by the position + # of the letter in the alphabet instead, so that 'a' produces a revision one + # higher than the base release and Windows recognizes the hotfix installer + # as the newer build. + $hotfixOffset = 0 + if ($hotfix) { + $hotfixOffset = [int][char]$hotfix - [int][char]'a' + 1 + } + $revisionText = $buildText if ($revisionText.Length -gt 2) { $revisionText = $revisionText.Substring($revisionText.Length - 2) } - $revisionText = $revisionText.PadLeft(2, '0') - $revision = [int]$revisionText + $revision = [int]$revisionText + $hotfixOffset + $revisionText = ([string]$revision).PadLeft(2, '0') foreach ($part in @($major, $minor, $patch, $revision)) { if ($part -lt 0 -or $part -gt 65535) { @@ -35,6 +48,13 @@ function Get-StudioReleaseVersion { } } + if ($hotfix) { + $hotfixDefine = "'$hotfix'" + } + else { + $hotfixDefine = "' '" + } + [PSCustomObject]@{ FullVersion = $Version ShortVersion = "$major.$minor.$patch" @@ -44,6 +64,8 @@ function Get-StudioReleaseVersion { Patch = $patch Build = $build BuildText = $buildText + Hotfix = $hotfix + HotfixDefine = $hotfixDefine Revision = $revision RevisionText = $revisionText Win32Version = "$major.$minor.$patch.$revision" diff --git a/scripts/prepare_release.sh b/scripts/prepare_release.sh index c90d3bff4..e832e92fd 100755 --- a/scripts/prepare_release.sh +++ b/scripts/prepare_release.sh @@ -10,11 +10,13 @@ # 1. Creates branch release--preparation from dev # 2. Updates version constants in common/inc/gx_api.h # (commit: "Updated version number constants") -# 3. Updates port version strings in all gx_port.h files +# 3. Updates port version strings in all gx_port.h files, both the GUIX +# ports and the GUIX Studio Win32 port # (commit: "Updated port version strings") # # Copyright (C) 2026 Eclipse ThreadX contributors # SPDX-License-Identifier: MIT +# Some portions generated by Claude Code (Opus 5). set -eu @@ -23,7 +25,7 @@ REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" API_HEADER="${REPO_ROOT}/common/inc/gx_api.h" PORT_HEADER_NAME="gx_port.h" -PORT_DIRS="ports" +PORT_DIRS="ports guix_studio/ports" # -------------------------------------------------------------------------- # Argument validation diff --git a/scripts/test_studio_demo.cmd b/scripts/test_studio_demo.cmd index 3143f485c..4a6bbca64 100644 --- a/scripts/test_studio_demo.cmd +++ b/scripts/test_studio_demo.cmd @@ -7,13 +7,26 @@ @rem @rem SPDX-License-Identifier: MIT @rem Some portions generated by Codex (OpenAI GPT-5.5). +@rem Some portions generated by Claude Code (Opus 5). -rem Initialize the developer environment just like a developer box. Note that 'call' keyword that ensures that the script does not exist after -rem calling the other batch file. -call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 +rem Initialize the developer environment just like a developer box. The Visual +rem Studio edition differs between a developer machine and a GitHub runner, so +rem locate the installation with vswhere rather than assuming an edition path. +rem Note the 'call' keyword, which ensures that this script does not exit when +rem the other batch file returns. +set "VSINSTALL=" +set "VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" +if exist "%VSWHERE%" ( + for /f "usebackq tokens=*" %%i in (`"%VSWHERE%" -latest -products * -requires Microsoft.Component.MSBuild -property installationPath`) do set "VSINSTALL=%%i" +) -rem Set Python path -SET PATH=%PATH%;"C:\Program Files\Python36";"C:\Program Files\Python36\scripts" +if not defined VSINSTALL ( + echo Visual Studio 2022 with MSBuild was not found. + exit /B 1 +) + +call "%VSINSTALL%\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 +if ERRORLEVEL 1 exit /B %ERRORLEVEL% rem Save working directory so that we can restore it back after building everything. This will make developers happy and then rem switch to the folder this script resides in. Don't assume absolute paths because on the build host and on the dev host the locations may be different. diff --git a/scripts/test_studio_demo_compile.cmd b/scripts/test_studio_demo_compile.cmd index 5a08cf24f..217cff9a1 100644 --- a/scripts/test_studio_demo_compile.cmd +++ b/scripts/test_studio_demo_compile.cmd @@ -7,13 +7,26 @@ @rem @rem SPDX-License-Identifier: MIT @rem Some portions generated by Codex (OpenAI GPT-5.5). +@rem Some portions generated by Claude Code (Opus 5). -rem Initialize the developer environment just like a developer box. Note that 'call' keyword that ensures that the script does not exist after -rem calling the other batch file. -call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 +rem Initialize the developer environment just like a developer box. The Visual +rem Studio edition differs between a developer machine and a GitHub runner, so +rem locate the installation with vswhere rather than assuming an edition path. +rem Note the 'call' keyword, which ensures that this script does not exit when +rem the other batch file returns. +set "VSINSTALL=" +set "VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" +if exist "%VSWHERE%" ( + for /f "usebackq tokens=*" %%i in (`"%VSWHERE%" -latest -products * -requires Microsoft.Component.MSBuild -property installationPath`) do set "VSINSTALL=%%i" +) -rem Set Python path -SET PATH=%PATH%;"C:\Program Files\Python36";"C:\Program Files\Python36\scripts" +if not defined VSINSTALL ( + echo Visual Studio 2022 with MSBuild was not found. + exit /B 1 +) + +call "%VSINSTALL%\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 +if ERRORLEVEL 1 exit /B %ERRORLEVEL% rem Save working directory so that we can restore it back after building everything. This will make developers happy and then rem switch to the folder this script resides in. Don't assume absolute paths because on the build host and on the dev host the locations may be different. diff --git a/scripts/test_studio_view.cmd b/scripts/test_studio_view.cmd index fa7724a41..2bcda14b6 100644 --- a/scripts/test_studio_view.cmd +++ b/scripts/test_studio_view.cmd @@ -7,13 +7,26 @@ @rem @rem SPDX-License-Identifier: MIT @rem Some portions generated by Codex (OpenAI GPT-5.5). +@rem Some portions generated by Claude Code (Opus 5). -rem Initialize the developer environment just like a developer box. Note that 'call' keyword that ensures that the script does not exist after -rem calling the other batch file. -call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 +rem Initialize the developer environment just like a developer box. The Visual +rem Studio edition differs between a developer machine and a GitHub runner, so +rem locate the installation with vswhere rather than assuming an edition path. +rem Note the 'call' keyword, which ensures that this script does not exit when +rem the other batch file returns. +set "VSINSTALL=" +set "VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" +if exist "%VSWHERE%" ( + for /f "usebackq tokens=*" %%i in (`"%VSWHERE%" -latest -products * -requires Microsoft.Component.MSBuild -property installationPath`) do set "VSINSTALL=%%i" +) -rem Set Python path -SET PATH=%PATH%;"C:\Program Files\Python36";"C:\Program Files\Python36\scripts" +if not defined VSINSTALL ( + echo Visual Studio 2022 with MSBuild was not found. + exit /B 1 +) + +call "%VSINSTALL%\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 +if ERRORLEVEL 1 exit /B %ERRORLEVEL% rem Save working directory so that we can restore it back after building everything. This will make developers happy and then rem switch to the folder this script resides in. Don't assume absolute paths because on the build host and on the dev host the locations may be different. diff --git a/scripts/update_studio_release_version.ps1 b/scripts/update_studio_release_version.ps1 index cb218687a..46807434c 100644 --- a/scripts/update_studio_release_version.ps1 +++ b/scripts/update_studio_release_version.ps1 @@ -5,6 +5,7 @@ # https://opensource.org/licenses/MIT. # # SPDX-License-Identifier: MIT +# Some portions generated by Claude Code (Opus 5). [CmdletBinding()] param( @@ -70,7 +71,7 @@ $content = Replace-Required $content '(?m)^#define GUIX_MAJOR_VERSION\s+\d+' "#d $content = Replace-Required $content '(?m)^#define GUIX_MINOR_VERSION\s+\d+' "#define GUIX_MINOR_VERSION $($release.Minor)" 'GUIX_MINOR_VERSION' $content = Replace-Required $content '(?m)^#define GUIX_PATCH_VERSION\s+\d+' "#define GUIX_PATCH_VERSION $($release.Patch)" 'GUIX_PATCH_VERSION' $content = Replace-Required $content '(?m)^#define GUIX_BUILD_VERSION\s+\d+' "#define GUIX_BUILD_VERSION $($release.Build)" 'GUIX_BUILD_VERSION' -$content = Replace-Required $content "(?m)^#define GUIX_HOTFIX_VERSION\s+'.*'" "#define GUIX_HOTFIX_VERSION ' '" 'GUIX_HOTFIX_VERSION' +$content = Replace-Required $content "(?m)^#define GUIX_HOTFIX_VERSION\s+'.*'" "#define GUIX_HOTFIX_VERSION $($release.HotfixDefine)" 'GUIX_HOTFIX_VERSION' Set-AsciiFile -Path $gxApi -Content $content $content = Get-Content -LiteralPath $studioProject -Raw @@ -96,5 +97,8 @@ $content = Replace-Required $content '#define StudioVersionInfoVersion "[^"]+"' Set-AsciiFile -Path $innoScript -Content $content Write-Host "Updated GUIX Studio release version to $($release.FullVersion)." +if ($release.Hotfix) { + Write-Host "Hotfix letter: $($release.Hotfix)" +} Write-Host "Win32 version: $($release.Win32Version)" Write-Host "MSIX version: $($release.MsixVersion)" diff --git a/test/example_internal/all_widgets/all_widgets_specifications.c b/test/example_internal/all_widgets/all_widgets_specifications.c index aa3bac2dc..077227294 100644 --- a/test/example_internal/all_widgets/all_widgets_specifications.c +++ b/test/example_internal/all_widgets/all_widgets_specifications.c @@ -69,6 +69,13 @@ GX_STUDIO_DISPLAY_INFO all_widgets_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -134,6 +141,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -199,6 +207,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -300,9 +309,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/test/example_internal/all_widgets_32argb/all_widgets_32argb_specifications.c b/test/example_internal/all_widgets_32argb/all_widgets_32argb_specifications.c index 4717e1997..94c6a5603 100644 --- a/test/example_internal/all_widgets_32argb/all_widgets_32argb_specifications.c +++ b/test/example_internal/all_widgets_32argb/all_widgets_32argb_specifications.c @@ -67,6 +67,13 @@ GX_STUDIO_DISPLAY_INFO all_widgets_32argb_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -132,6 +139,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -197,6 +205,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -298,9 +307,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/test/example_internal/all_widgets_565bgr/all_widgets_565bgr_specifications.c b/test/example_internal/all_widgets_565bgr/all_widgets_565bgr_specifications.c index 3c497d5ab..fe3b8b37f 100644 --- a/test/example_internal/all_widgets_565bgr/all_widgets_565bgr_specifications.c +++ b/test/example_internal/all_widgets_565bgr/all_widgets_565bgr_specifications.c @@ -68,6 +68,13 @@ GX_STUDIO_DISPLAY_INFO all_widgets_565bgr_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -133,6 +140,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -198,6 +206,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -299,9 +308,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/test/example_internal/all_widgets_5_4_0/all_widgets_5_4_0_specifications.c b/test/example_internal/all_widgets_5_4_0/all_widgets_5_4_0_specifications.c index c0ed43ac1..9c3864174 100644 --- a/test/example_internal/all_widgets_5_4_0/all_widgets_5_4_0_specifications.c +++ b/test/example_internal/all_widgets_5_4_0/all_widgets_5_4_0_specifications.c @@ -65,6 +65,13 @@ GX_STUDIO_DISPLAY_INFO all_widgets_5_4_0_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -130,6 +137,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -178,6 +186,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -260,9 +269,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: parent = widget->gx_widget_parent; diff --git a/test/example_internal/all_widgets_5_4_1/all_widgets_5_4_1_specifications.c b/test/example_internal/all_widgets_5_4_1/all_widgets_5_4_1_specifications.c index a4c7b17fc..6dc07a7e5 100644 --- a/test/example_internal/all_widgets_5_4_1/all_widgets_5_4_1_specifications.c +++ b/test/example_internal/all_widgets_5_4_1/all_widgets_5_4_1_specifications.c @@ -65,6 +65,13 @@ GX_STUDIO_DISPLAY_INFO all_widgets_5_4_1_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -130,6 +137,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -178,6 +186,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -260,9 +269,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: parent = widget->gx_widget_parent; diff --git a/test/example_internal/all_widgets_5_4_2/all_widgets_5_4_2_specifications.c b/test/example_internal/all_widgets_5_4_2/all_widgets_5_4_2_specifications.c index 0c2dd9c27..39b9b7b2f 100644 --- a/test/example_internal/all_widgets_5_4_2/all_widgets_5_4_2_specifications.c +++ b/test/example_internal/all_widgets_5_4_2/all_widgets_5_4_2_specifications.c @@ -65,6 +65,13 @@ GX_STUDIO_DISPLAY_INFO all_widgets_5_4_2_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -130,6 +137,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -178,6 +186,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -260,9 +269,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: parent = widget->gx_widget_parent; diff --git a/test/example_internal/all_widgets_5_5_1/all_widgets_5_5_1_specifications.c b/test/example_internal/all_widgets_5_5_1/all_widgets_5_5_1_specifications.c index bc6d3695f..efd0f73e9 100644 --- a/test/example_internal/all_widgets_5_5_1/all_widgets_5_5_1_specifications.c +++ b/test/example_internal/all_widgets_5_5_1/all_widgets_5_5_1_specifications.c @@ -66,6 +66,13 @@ GX_STUDIO_DISPLAY_INFO all_widgets_5_5_1_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -131,6 +138,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -196,6 +204,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -297,9 +306,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/test/example_internal/all_widgets_defined_5_4_0_compatibility/all_widgets_defined_5_4_0_compatibility_specifications.c b/test/example_internal/all_widgets_defined_5_4_0_compatibility/all_widgets_defined_5_4_0_compatibility_specifications.c index 1f1ee7b61..54fa4b78a 100644 --- a/test/example_internal/all_widgets_defined_5_4_0_compatibility/all_widgets_defined_5_4_0_compatibility_specifications.c +++ b/test/example_internal/all_widgets_defined_5_4_0_compatibility/all_widgets_defined_5_4_0_compatibility_specifications.c @@ -67,6 +67,13 @@ GX_STUDIO_DISPLAY_INFO all_widgets_defined_5_4_0_compatibility_display_table[1] } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -132,6 +139,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -197,6 +205,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -298,9 +307,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/test/example_internal/all_widgets_execute/all_widgets_execute_specifications.c b/test/example_internal/all_widgets_execute/all_widgets_execute_specifications.c index 753bf3624..91b23b867 100644 --- a/test/example_internal/all_widgets_execute/all_widgets_execute_specifications.c +++ b/test/example_internal/all_widgets_execute/all_widgets_execute_specifications.c @@ -65,6 +65,13 @@ GX_STUDIO_DISPLAY_INFO all_widgets_execute_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -130,6 +137,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -195,6 +203,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -296,9 +305,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/test/example_internal/all_widgets_synergy/all_widgets_synergy_specifications.c b/test/example_internal/all_widgets_synergy/all_widgets_synergy_specifications.c index 19806d362..8aa6b018e 100644 --- a/test/example_internal/all_widgets_synergy/all_widgets_synergy_specifications.c +++ b/test/example_internal/all_widgets_synergy/all_widgets_synergy_specifications.c @@ -66,6 +66,13 @@ GX_STUDIO_DISPLAY_INFO all_widgets_synergy_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -131,6 +138,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -196,6 +204,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -297,9 +306,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/test/example_internal/all_widgets_synergy_16bpp_flip/all_widgets_synergy_16bpp_flip_specifications.c b/test/example_internal/all_widgets_synergy_16bpp_flip/all_widgets_synergy_16bpp_flip_specifications.c index 15506b7b8..6a415a6aa 100644 --- a/test/example_internal/all_widgets_synergy_16bpp_flip/all_widgets_synergy_16bpp_flip_specifications.c +++ b/test/example_internal/all_widgets_synergy_16bpp_flip/all_widgets_synergy_16bpp_flip_specifications.c @@ -66,6 +66,13 @@ GX_STUDIO_DISPLAY_INFO all_widgets_synergy_16bpp_flip_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -131,6 +138,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -196,6 +204,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -297,9 +306,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/test/example_internal/all_widgets_synergy_24BPP_Dave_Disabled/all_widgets_synergy_dave_disabled_specifications.c b/test/example_internal/all_widgets_synergy_24BPP_Dave_Disabled/all_widgets_synergy_dave_disabled_specifications.c index 902fbc4a9..afe2a191d 100644 --- a/test/example_internal/all_widgets_synergy_24BPP_Dave_Disabled/all_widgets_synergy_dave_disabled_specifications.c +++ b/test/example_internal/all_widgets_synergy_24BPP_Dave_Disabled/all_widgets_synergy_dave_disabled_specifications.c @@ -65,6 +65,13 @@ GX_STUDIO_DISPLAY_INFO all_widgets_synergy_dave_disabled_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -130,6 +137,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -195,6 +203,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -296,9 +305,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/test/example_internal/all_widgets_synergy_565rgb/all_widgets_synergy_565rgb_specifications.c b/test/example_internal/all_widgets_synergy_565rgb/all_widgets_synergy_565rgb_specifications.c index 0cfac6bb7..efff969e4 100644 --- a/test/example_internal/all_widgets_synergy_565rgb/all_widgets_synergy_565rgb_specifications.c +++ b/test/example_internal/all_widgets_synergy_565rgb/all_widgets_synergy_565rgb_specifications.c @@ -66,6 +66,13 @@ GX_STUDIO_DISPLAY_INFO all_widgets_synergy_565rgb_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -131,6 +138,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -196,6 +204,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -297,9 +306,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/test/example_internal/all_widgets_synergy_5_4_2/all_widgets_synergy_5_4_2_specifications.c b/test/example_internal/all_widgets_synergy_5_4_2/all_widgets_synergy_5_4_2_specifications.c index 80f9a2a24..918f3ddde 100644 --- a/test/example_internal/all_widgets_synergy_5_4_2/all_widgets_synergy_5_4_2_specifications.c +++ b/test/example_internal/all_widgets_synergy_5_4_2/all_widgets_synergy_5_4_2_specifications.c @@ -64,6 +64,13 @@ GX_STUDIO_DISPLAY_INFO all_widgets_synergy_5_4_2_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -129,6 +136,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -177,6 +185,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -259,9 +268,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: parent = widget->gx_widget_parent; diff --git a/test/example_internal/folder_output_test/folder_output_test_specifications.c b/test/example_internal/folder_output_test/folder_output_test_specifications.c index 2cbfbf97f..e5150119a 100644 --- a/test/example_internal/folder_output_test/folder_output_test_specifications.c +++ b/test/example_internal/folder_output_test/folder_output_test_specifications.c @@ -128,6 +128,13 @@ static VOID gx_studio_screen_toggle(GX_WIDGET *target1, GX_WIDGET *target2) } } +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -193,6 +200,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -258,6 +266,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -344,9 +353,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/test/example_internal/guix_medical_mouse_support/guix_medical_mouse_support_specifications.c b/test/example_internal/guix_medical_mouse_support/guix_medical_mouse_support_specifications.c index c50b054e0..56f570a97 100644 --- a/test/example_internal/guix_medical_mouse_support/guix_medical_mouse_support_specifications.c +++ b/test/example_internal/guix_medical_mouse_support/guix_medical_mouse_support_specifications.c @@ -59,6 +59,13 @@ GX_STUDIO_DISPLAY_INFO guix_medical_mouse_support_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -124,6 +131,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -189,6 +197,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -290,9 +299,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/test/example_internal/partial_frame_buffer_16bpp/partial_frame_buffer_16bpp_specifications.c b/test/example_internal/partial_frame_buffer_16bpp/partial_frame_buffer_16bpp_specifications.c index d4ea65dac..631411370 100644 --- a/test/example_internal/partial_frame_buffer_16bpp/partial_frame_buffer_16bpp_specifications.c +++ b/test/example_internal/partial_frame_buffer_16bpp/partial_frame_buffer_16bpp_specifications.c @@ -71,6 +71,13 @@ GX_STUDIO_DISPLAY_INFO partial_frame_buffer_16bpp_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -136,6 +143,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -201,6 +209,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -302,9 +311,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/test/example_internal/standalone_binres_load_16bpp/standalone_binres_load_16bpp_specifications.c b/test/example_internal/standalone_binres_load_16bpp/standalone_binres_load_16bpp_specifications.c index a2d817f73..e0d953e3a 100644 --- a/test/example_internal/standalone_binres_load_16bpp/standalone_binres_load_16bpp_specifications.c +++ b/test/example_internal/standalone_binres_load_16bpp/standalone_binres_load_16bpp_specifications.c @@ -60,6 +60,13 @@ GX_STUDIO_DISPLAY_INFO standalone_binres_load_16bpp_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -125,6 +132,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -190,6 +198,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -291,9 +300,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/test/example_internal/system_screen_stack/system_screen_stack_specifications.c b/test/example_internal/system_screen_stack/system_screen_stack_specifications.c index 4c1425718..a42160f0f 100644 --- a/test/example_internal/system_screen_stack/system_screen_stack_specifications.c +++ b/test/example_internal/system_screen_stack/system_screen_stack_specifications.c @@ -61,6 +61,13 @@ GX_STUDIO_DISPLAY_INFO system_screen_stack_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -126,6 +133,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -191,6 +199,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -292,9 +301,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/test/example_internal/template/template_specifications.c b/test/example_internal/template/template_specifications.c index b69f7a229..6e689eb44 100644 --- a/test/example_internal/template/template_specifications.c +++ b/test/example_internal/template/template_specifications.c @@ -59,6 +59,13 @@ GX_STUDIO_DISPLAY_INFO template_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -124,6 +131,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -189,6 +197,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -290,9 +299,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/test/guix_studio_test/test_demo/demo_compile/CMakeLists.txt b/test/guix_studio_test/test_demo/demo_compile/CMakeLists.txt index 814e788cc..8bb7bcd33 100644 --- a/test/guix_studio_test/test_demo/demo_compile/CMakeLists.txt +++ b/test/guix_studio_test/test_demo/demo_compile/CMakeLists.txt @@ -18,4 +18,8 @@ FOREACH(TEST_FILE ${TEST_SLN_FILE_LIST}) FILE(RELATIVE_PATH TEST_NAME "${CMAKE_CURRENT_SOURCE_DIR}/../../../../" ${TEST_FILE}) ADD_TEST(${TEST_NAME} python ${CMAKE_CURRENT_SOURCE_DIR}/../test_main.py -p ${TEST_FILE} --compile_project --debug) SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES TIMEOUT 600) -ENDFOREACH() \ No newline at end of file +ENDFOREACH() + +#regression test for issue #172: Screen Flow output must build with an empty animation pool +ADD_TEST(animation_pool_size_zero python ${CMAKE_CURRENT_SOURCE_DIR}/../test_animation_pool_size.py --debug) +SET_TESTS_PROPERTIES(animation_pool_size_zero PROPERTIES TIMEOUT 1200) \ No newline at end of file diff --git a/test/guix_studio_test/test_demo/test_animation_pool_size.py b/test/guix_studio_test/test_demo/test_animation_pool_size.py new file mode 100644 index 000000000..6691569e7 --- /dev/null +++ b/test/guix_studio_test/test_demo/test_animation_pool_size.py @@ -0,0 +1,239 @@ +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# This program and the accompanying materials are made available under the +# terms of the MIT License which is available at +# https://opensource.org/licenses/MIT. +# +# SPDX-License-Identifier: MIT +# Some portions generated by Claude Code (Opus 5). + +"""Regression test for https://github.com/eclipse-threadx/guix/issues/172. + +GUIX Studio emits five static helper functions in the generated specification +file as soon as a project uses Screen Flow. Two of them, +gx_studio_action_parent_find() and gx_studio_animation_execute(), are reachable +only from the GX_ACTION_TYPE_ANIMATION handler and call the GUIX animation API, +which is compiled out when GX_ANIMATION_POOL_SIZE is 0. The generator must +therefore guard them with "#if (GX_ANIMATION_POOL_SIZE > 0)", otherwise a Screen +Flow project cannot be built with an empty animation pool. + +The test runs in two stages: + +1. Source check: every checked-in generated specification file that uses Screen + Flow must guard the animation helpers. This stage needs no compiler. +2. Compile check: the same files are compiled with GX_ANIMATION_POOL_SIZE set to + 0. The MSVC warning about an implicit function declaration (C4013) is + promoted to an error so that the missing gx_system_animation_get() macro is + reported, which is what a linker or GCC 14 would reject. +""" + +import argparse +import logging +import os +import shutil +import subprocess +import sys +import tempfile + +import search_gxps + +ANIMATION_HELPER = 'gx_studio_animation_execute' +ANIMATION_GUARD = '#if (GX_ANIMATION_POOL_SIZE > 0)' + +# Every one of these must sit inside an ANIMATION_GUARD block. The first two are +# the definitions of the helpers that reference the animation API, the third is +# the switch case that calls them. A prototype or a call ends with a semicolon, +# so the check below ignores those lines and only looks at the definitions and +# at the case label. +GUARDED_LINES = ['static GX_WIDGET *gx_studio_action_parent_find(', + 'static VOID gx_studio_animation_execute(', + 'case GX_ACTION_TYPE_ANIMATION:'] + +# These projects were generated for GUIX 5.4.0 and 5.4.1, whose widget API is +# not source compatible with the current library, so they cannot be compiled +# standalone. The demo compile test skips them for the same reason. Their +# generated files are still covered by the source check below. +UNCOMPILABLE_PROJECTS = ['all_widgets_5_4_0', 'all_widgets_5_4_1'] + +# Scratch directories that some Studio projects generate into. They hold copies +# of the generated files, not sources, so they are not part of this test. +SCRATCH_DIRECTORIES = ['output_files', 'project_output_folder', + 'xml_output_folder'] + +GX_USER_CONTENT = """/* Generated by test_animation_pool_size.py. Do not edit. */ + +#ifndef GX_USER_H +#define GX_USER_H + +/* Build without the animation pool to make sure the code generated for Screen + Flow does not reference the animation API. */ +#define GX_ANIMATION_POOL_SIZE 0 + +#endif +""" + +# count[total, passed, failed] +count_source = [0, 0, 0] +count_compile = [0, 0, 0] + + +def find_screen_flow_files(root_dir): + """Return the generated specification files that use Screen Flow.""" + + files = [] + for pathname in search_gxps.files_find(['*_specifications.c'], root_dir): + if os.path.basename(os.path.dirname(pathname)) in SCRATCH_DIRECTORIES: + continue + + with open(pathname, 'r') as source: + if ANIMATION_HELPER in source.read(): + files.append(pathname) + return sorted(files) + + +def check_source(pathname): + """Verify that the animation helpers are guarded in one generated file.""" + + with open(pathname, 'r') as source: + lines = source.readlines() + + guard_depth = 0 + guarded = dict.fromkeys(GUARDED_LINES, False) + + for line in lines: + stripped = line.strip() + if stripped == ANIMATION_GUARD: + guard_depth += 1 + elif stripped.startswith('#if'): + if guard_depth: + guard_depth += 1 + elif stripped.startswith('#endif'): + if guard_depth: + guard_depth -= 1 + elif guard_depth and not stripped.endswith(';'): + for expected in guarded: + if stripped.startswith(expected): + guarded[expected] = True + + missing = [expected for expected in GUARDED_LINES if not guarded[expected]] + if missing: + logging.error('**Error** %s: "%s" not guarded by "%s"', + pathname, '", "'.join(missing), ANIMATION_GUARD) + return False + return True + + +def compile_file(pathname, root_dir, gx_user_dir, output_dir): + """Compile one generated file with an empty animation pool.""" + + command = ['cl', '/nologo', '/c', '/W3', + # An undeclared gx_system_animation_get() is only a warning for + # MSVC. Promote it so that this test fails the way a GCC 14 or a + # link step would. + '/we4013', + '/DGX_INCLUDE_USER_DEFINE_FILE', + '/DWIN32', '/D_DEBUG', '/D_WINDOWS', + '/D_CRT_SECURE_NO_WARNINGS', + '/Fo' + os.path.join(output_dir, '')] + + for directory in [gx_user_dir, + os.path.dirname(pathname), + os.path.join(root_dir, 'common', 'inc'), + os.path.join(root_dir, 'ports', 'win32', 'inc'), + os.path.join(root_dir, 'ports', 'win32', 'lib', 'vs_2019')]: + command += ['/I', directory] + + command.append(pathname) + + result = subprocess.run(command, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + output = result.stdout.decode(errors='replace') + logging.debug(output) + + if result.returncode: + logging.error('**Error** Compilation failed for %s', pathname) + logging.error(output) + return False + return True + + +def write_test_result(): + logging.info('********************************************') + logging.info(' Source checked files : %d', count_source[0]) + logging.info(' Passed : %d', count_source[1]) + logging.info(' Failed : %d', count_source[2]) + logging.info(' Compiled files : %d', count_compile[0]) + logging.info(' Passed : %d', count_compile[1]) + logging.info(' Failed : %d', count_compile[2]) + + +def __main__(): + # Change the current working directory to the path of this file. + current_path = os.path.split(os.path.realpath(__file__))[0] + os.chdir(current_path) + root_dir = os.path.realpath(os.path.join(current_path, '..', '..', '..')) + + parser = argparse.ArgumentParser( + description='Test Screen Flow output with GX_ANIMATION_POOL_SIZE = 0.') + parser.add_argument('--debug', action='store_true', dest='debug', + help='Print the debug logs to console.') + args = parser.parse_args() + + logging.basicConfig(filename='animation_pool_size_test_log.txt', + filemode='w', level=logging.DEBUG, format='%(message)s') + console = logging.StreamHandler() + console.setLevel(logging.DEBUG if args.debug else logging.INFO) + console.setFormatter(logging.Formatter('%(message)s')) + logging.getLogger('').addHandler(console) + + files = [] + for directory in ['samples', os.path.join('test', 'example_internal'), + 'tutorials']: + files += find_screen_flow_files(os.path.join(root_dir, directory)) + + if not files: + logging.error('**Error** No Screen Flow specification file found.') + return 1 + + logging.info('Found %d Screen Flow specification files.', len(files)) + + for pathname in files: + count_source[0] += 1 + if check_source(pathname): + count_source[1] += 1 + else: + count_source[2] += 1 + + if shutil.which('cl') is None: + logging.warning('** Skipped ** cl.exe not found on PATH, the compile ' + 'stage of this test did not run. Run the test from a ' + 'Visual Studio developer command prompt.') + else: + work_dir = tempfile.mkdtemp(prefix='gx_animation_pool_size_') + try: + with open(os.path.join(work_dir, 'gx_user.h'), 'w') as gx_user: + gx_user.write(GX_USER_CONTENT) + + for pathname in files: + project = os.path.basename(os.path.dirname(pathname)) + if project in UNCOMPILABLE_PROJECTS: + logging.info('Skipping %s, it targets a legacy GUIX API.', + pathname) + continue + + count_compile[0] += 1 + if compile_file(pathname, root_dir, work_dir, work_dir): + count_compile[1] += 1 + else: + count_compile[2] += 1 + finally: + shutil.rmtree(work_dir, ignore_errors=True) + + write_test_result() + + if count_source[2] or count_compile[2]: + return 1 + return 0 + + +sys.exit(__main__()) diff --git a/test/guix_studio_test/test_demo/test_main.py b/test/guix_studio_test/test_demo/test_main.py index 76f5af255..7b2f8ebf7 100644 --- a/test/guix_studio_test/test_demo/test_main.py +++ b/test/guix_studio_test/test_demo/test_main.py @@ -641,7 +641,7 @@ def __main__(): os.chdir(current_path) studio_sln_path = "../../../guix_studio/build/vs_2022/studiox.sln" studio_exe_path = "../../../guix_studio/build/vs_2022/Release/guix_studio.exe" - guix_project_path = "../../../ports/win32/build/vs_2022/guix.vcxproj" + guix_project_path = "../../../ports/win32/build/vs_2019/guix.vcxproj" gxp_projects = [] diff --git a/test/guix_studio_test/test_view/golden_files/all_widgets_execute_specifications.c b/test/guix_studio_test/test_view/golden_files/all_widgets_execute_specifications.c index ee626729c..50865501c 100644 --- a/test/guix_studio_test/test_view/golden_files/all_widgets_execute_specifications.c +++ b/test/guix_studio_test/test_view/golden_files/all_widgets_execute_specifications.c @@ -63,6 +63,13 @@ GX_STUDIO_DISPLAY_INFO all_widgets_execute_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -128,6 +135,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -176,6 +184,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -258,9 +267,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: parent = widget->gx_widget_parent; diff --git a/test/guix_studio_test/test_view/golden_files/template_specifications.c b/test/guix_studio_test/test_view/golden_files/template_specifications.c index 2c8966e7c..7f3f78d38 100644 --- a/test/guix_studio_test/test_view/golden_files/template_specifications.c +++ b/test/guix_studio_test/test_view/golden_files/template_specifications.c @@ -61,6 +61,13 @@ GX_STUDIO_DISPLAY_INFO template_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -126,6 +133,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -191,6 +199,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -292,9 +301,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/test/guix_studio_test/test_view/golden_files/trigger_target_rename_specifications.c b/test/guix_studio_test/test_view/golden_files/trigger_target_rename_specifications.c index 03c95c589..fe5a44354 100644 --- a/test/guix_studio_test/test_view/golden_files/trigger_target_rename_specifications.c +++ b/test/guix_studio_test/test_view/golden_files/trigger_target_rename_specifications.c @@ -57,6 +57,13 @@ GX_STUDIO_DISPLAY_INFO trigger_target_rename_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -122,6 +129,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -170,6 +178,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -252,9 +261,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: parent = widget->gx_widget_parent; diff --git a/test/guix_studio_test/test_view/test_main.py b/test/guix_studio_test/test_view/test_main.py index 1146e3558..6cf431b4d 100644 --- a/test/guix_studio_test/test_view/test_main.py +++ b/test/guix_studio_test/test_view/test_main.py @@ -82,7 +82,7 @@ def __main__(): logging.basicConfig(stream=test_utils.test_log_stream, level=logging.DEBUG, format=Format) msbuild_exe_path = "C:/Windows/Microsoft.NET/Framework64/v4.0.30319/MSBuild.exe" - project_sln_path = "../../../guix_studio/build/vs_2019/studiox.sln" + project_sln_path = "../../../guix_studio/build/vs_2022/studiox.sln" parser = argparse.ArgumentParser(description = "Test Studio UI") parser.add_argument('-b', action='store_true', dest='build_studio', help='Build Studio') diff --git a/test/guix_studio_test/test_view/test_string_import_export.py b/test/guix_studio_test/test_view/test_string_import_export.py index 231b8d039..db513bbcf 100644 --- a/test/guix_studio_test/test_view/test_string_import_export.py +++ b/test/guix_studio_test/test_view/test_string_import_export.py @@ -98,7 +98,7 @@ def csv_string_import_export(): print("import string from command line") test_utils.toolbar_save() test_utils.close_project(1) - studio_release = test_utils.DEFAULT_OUTPUT_FILE_PATH + "../../../../guix_studio/build/vs_2019/Release/guix_studio.exe" + studio_release = test_utils.DEFAULT_OUTPUT_FILE_PATH + "../../../../guix_studio/build/vs_2022/Release/guix_studio.exe" project_pathname = test_utils.DEFAULT_OUTPUT_FILE_PATH + "/test_string_import_export.gxp" studio_release = os.path.abspath(studio_release) project_pathname = os.path.abspath(project_pathname) diff --git a/test/guix_studio_test/test_view/test_utils.py b/test/guix_studio_test/test_view/test_utils.py index dc7b5d18f..ae1849e1c 100644 --- a/test/guix_studio_test/test_view/test_utils.py +++ b/test/guix_studio_test/test_view/test_utils.py @@ -7,6 +7,7 @@ # https://opensource.org/licenses/MIT. # # SPDX-License-Identifier: MIT +# Some portions generated by Claude Code (Opus 5). import os import sys @@ -28,7 +29,7 @@ user32 = ctypes.windll.user32 -studio_exe_path = "../../../guix_studio/build/vs_2019/Release/guix_studio.exe" +studio_exe_path = "../../../guix_studio/build/vs_2022/Release/guix_studio.exe" top_windows = [] WM_CLOSE = 0x0010 reset_map_format = False @@ -217,7 +218,11 @@ def compare_file(pathname_1, pathname_2, encoding = "", compare_start_string = " start_row_2 = 0 if compare_start_string != "": - # find the line where comparing starts + # Find the line where comparing starts, independently in each file. The + # two files may reach that line at different offsets -- a generated file + # carries the Studio banner, while the golden checked in beside it also + # carries a licence header -- so each start row must be looked up in its + # own list. for line in list_1: if compare_start_string in line: start_row_1 = list_1.index(line) @@ -225,7 +230,7 @@ def compare_file(pathname_1, pathname_2, encoding = "", compare_start_string = " for line in list_2: if compare_start_string in line: - start_row_2 = list_1.index(line) + start_row_2 = list_2.index(line) break; # compare from the start line diff --git a/test/guix_test/cmake/regression/CMakeLists.txt b/test/guix_test/cmake/regression/CMakeLists.txt index ecac43750..30d8b8b50 100644 --- a/test/guix_test/cmake/regression/CMakeLists.txt +++ b/test/guix_test/cmake/regression/CMakeLists.txt @@ -286,6 +286,7 @@ set(all_widgets_REG_TESTS guix_button_deselect_no_output guix_canvas_drawing_complete guix_canvas_draw_nesting_overflow_no_output + guix_canvas_draw_nesting_overflow_render_no_output guix_canvas_hardware_layer guix_canvas_pixelmap_blend guix_canvas_pixelmap_get_no_output @@ -352,6 +353,7 @@ set(all_widgets_REG_TESTS guix_ml_input_char_insert_no_output guix_ml_input_text_set_no_output guix_ml_input_no_output + guix_ml_text_line_terminator_bounds_no_output guix_ml_text_view_word_wrap_no_output guix_ml_view_text_set_no_output guix_ml_view_no_output diff --git a/test/guix_test/regression_test/tests/validation_guix_canvas_draw_nesting_overflow_render_no_output.c b/test/guix_test/regression_test/tests/validation_guix_canvas_draw_nesting_overflow_render_no_output.c new file mode 100644 index 000000000..5032204ad --- /dev/null +++ b/test/guix_test/regression_test/tests/validation_guix_canvas_draw_nesting_overflow_render_no_output.c @@ -0,0 +1,202 @@ +/*************************************************************************** + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * AI Disclosure: This file was largely AI-generated by Claude Code (Opus 5). + * The AI-generated portions may be considered public domain (CC0-1.0) + * and not subject to the project's licence. The human contributor has + * reviewed and verified that the code is correct. + * + * SPDX-License-Identifier: MIT and CC0-1.0 + **************************************************************************/ + +/* Regression test for what a caller must RENDER when + * _gx_canvas_drawing_initiate() returns GX_DRAW_NESTING_EXCEEDED. + * + * guix_canvas_draw_nesting_overflow_no_output covers the other half of the + * contract: that the overflow is detected and that the draw context stack is + * left untouched. It says nothing about the pixels, and issue #148's fix + * originally answered "draw nothing", which silently dropped text that GUIX had + * always drawn. + * + * A widget such as a multi line text view pushes a nested context on itself for + * one reason only: to narrow the clipping rectangle to its client area. When + * the stack is full there is nothing to push, but the caller's context is still + * the correct context to draw through - it belongs to the same widget - so the + * widget narrows that context's clipping rectangle, draws, and restores it. + * + * Tests: + * 1. The text is still drawn when the draw context stack is full. + * 2. The borrowed context is restored: nesting count, context pointer and + * clipping rectangle are all exactly as they were. + * 3. The pixels produced at maximum nesting depth are identical to the pixels + * produced when a nested context is available. + */ + +#include +#include +#include "tx_api.h" +#include "gx_api.h" +#include "gx_system.h" +#include "gx_widget.h" +#include "gx_multi_line_text_view.h" +#include "gx_validation_utility.h" + +TEST_PARAM test_parameter = { + "guix_canvas_draw_nesting_overflow_render_no_output", + 0, 0, 0, 0 +}; + +int main(int argc, char **argv) +{ + tx_kernel_enter(); + return 0; +} + +static VOID control_thread_entry(ULONG input); + +VOID tx_application_define(void *first_unused_memory) +{ + gx_validation_control_thread_create(control_thread_entry); + gx_validation_application_define(first_unused_memory); + gx_validation_watchdog_create(100); +} + +#ifdef WIN32 +#undef WIN32 +#endif + +#include "gx_validation_wrapper.h" +#include "demo_guix_all_widgets.c" + +/* Sum every byte of the canvas frame buffer. Working in bytes keeps the + comparison independent of the colour depth, so the test behaves the same in + every build configuration. */ +static ULONG canvas_checksum(GX_CANVAS *canvas) +{ +ULONG sum = 0; +ULONG index; +GX_UBYTE *memory = (GX_UBYTE *)canvas -> gx_canvas_memory; + + for (index = 0; index < canvas -> gx_canvas_memory_size; index++) + { + sum += memory[index]; + } + + return sum; +} + +static VOID control_thread_entry(ULONG input) +{ +int failed_tests = 0; +GX_CANVAS *canvas; +GX_MULTI_LINE_TEXT_VIEW *text_view; +GX_RECTANGLE size; +GX_RECTANGLE saved_dirty; +GX_DRAW_CONTEXT *saved_context; +GX_UBYTE saved_nesting; +UINT status; +UINT index; +ULONG blank_sum; +ULONG overflow_sum; +ULONG nested_sum; + + canvas = root -> gx_window_root_canvas; + text_view = &text_screen.text_screen_text_view_1; + + /* Bring up the screen that owns the multi line text view, so that the widget + has a clip rectangle and a view list of its own. */ + ToggleScreen((GX_WINDOW *)&text_screen, (GX_WINDOW *)&button_screen); + tx_thread_sleep(10); + + /* Give the widget a non-zero whitespace. The rectangle it passes to + _gx_canvas_drawing_initiate() is its client area shrunk by the whitespace, + so the narrowed clipping rectangle becomes strictly smaller than the + widget's own clip rectangle. That is what makes the narrowing matter. */ + gx_multi_line_text_view_whitespace_set(text_view, 6); + tx_thread_sleep(10); + + size = text_view -> gx_widget_size; + + /* Pre-condition: the draw context stack must be clean. */ + EXPECT_EQ(0, (int)canvas -> gx_canvas_draw_nesting); + EXPECT_EQ(GX_NULL, _gx_system_current_draw_context); + + /* Fill the draw context stack, drawing on the text view itself so that every + context carries the widget's view list. The last one is the context the + widget has to borrow. */ + for (index = 0; index < GX_MAX_CONTEXT_NESTING; index++) + { + status = gx_canvas_drawing_initiate(canvas, (GX_WIDGET *)text_view, &size); + EXPECT_EQ(GX_SUCCESS, status); + } + + saved_nesting = canvas -> gx_canvas_draw_nesting; + saved_context = _gx_system_current_draw_context; + saved_dirty = saved_context -> gx_draw_context_dirty; + + memset(canvas -> gx_canvas_memory, 0, canvas -> gx_canvas_memory_size); + blank_sum = canvas_checksum(canvas); + + /* Test 1: the text is drawn even though the stack is full. */ + _gx_multi_line_text_view_text_draw(text_view, + text_view -> gx_multi_line_text_view_normal_text_color); + + overflow_sum = canvas_checksum(canvas); + + if (overflow_sum == blank_sum) + { + PRINT_ERROR("no pixels were written at maximum draw context nesting depth"); + failed_tests++; + } + + /* Test 2: the borrowed context is handed back untouched. */ + EXPECT_EQ(saved_nesting, canvas -> gx_canvas_draw_nesting); + EXPECT_EQ(saved_context, _gx_system_current_draw_context); + EXPECT_EQ(saved_dirty.gx_rectangle_left, saved_context -> gx_draw_context_dirty.gx_rectangle_left); + EXPECT_EQ(saved_dirty.gx_rectangle_top, saved_context -> gx_draw_context_dirty.gx_rectangle_top); + EXPECT_EQ(saved_dirty.gx_rectangle_right, saved_context -> gx_draw_context_dirty.gx_rectangle_right); + EXPECT_EQ(saved_dirty.gx_rectangle_bottom, saved_context -> gx_draw_context_dirty.gx_rectangle_bottom); + + /* Unwind the stack. */ + for (index = 0; index < GX_MAX_CONTEXT_NESTING; index++) + { + gx_canvas_drawing_complete(canvas, GX_FALSE); + } + + EXPECT_EQ(0, (int)canvas -> gx_canvas_draw_nesting); + EXPECT_EQ(GX_NULL, _gx_system_current_draw_context); + + /* Test 3: draw the same text again with room left on the stack, so that the + nested context is really pushed, and compare the two renderings. */ + status = gx_canvas_drawing_initiate(canvas, (GX_WIDGET *)text_view, &size); + EXPECT_EQ(GX_SUCCESS, status); + + memset(canvas -> gx_canvas_memory, 0, canvas -> gx_canvas_memory_size); + + _gx_multi_line_text_view_text_draw(text_view, + text_view -> gx_multi_line_text_view_normal_text_color); + + nested_sum = canvas_checksum(canvas); + + gx_canvas_drawing_complete(canvas, GX_FALSE); + + EXPECT_EQ(0, (int)canvas -> gx_canvas_draw_nesting); + EXPECT_EQ(GX_NULL, _gx_system_current_draw_context); + + EXPECT_EQ(nested_sum, overflow_sum); + + if (failed_tests == 0) + { + gx_validation_print_test_result(TEST_SUCCESS); + exit(0); + } + else + { + gx_validation_print_test_result(TEST_FAIL); + exit(1); + } +} diff --git a/test/guix_test/regression_test/tests/validation_guix_ml_text_line_terminator_bounds_no_output.c b/test/guix_test/regression_test/tests/validation_guix_ml_text_line_terminator_bounds_no_output.c new file mode 100644 index 000000000..9f021ad85 --- /dev/null +++ b/test/guix_test/regression_test/tests/validation_guix_ml_text_line_terminator_bounds_no_output.c @@ -0,0 +1,165 @@ +/*************************************************************************** + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * AI Disclosure: This file was largely AI-generated by Claude Code (Opus 5). + * The AI-generated portions may be considered public domain (CC0-1.0) + * and not subject to the project's licence. The human contributor has + * reviewed and verified that the code is correct. + * + * SPDX-License-Identifier: MIT and CC0-1.0 + **************************************************************************/ + +/* Regression test for reading one byte past the end of a GX_STRING when it + * ends with a carriage return. + * + * A GX_STRING carries its own length and need not be NUL terminated, and + * _gx_multi_line_text_view_text_set_ext() stores the caller's string verbatim + * unless GX_STYLE_TEXT_COPY is set. When the last byte of such a string is a + * carriage return, _gx_multi_line_text_view_display_info_get() examined the + * byte after it to decide whether the terminator was "\r" or "\r\n". That byte + * lies outside the caller's buffer. + * + * Beyond the read itself, if the byte happened to be a line feed the function + * reported a two-byte terminator for a one-byte remainder, so callers advanced + * their index past gx_string_length -- and + * _gx_multi_line_text_view_string_total_rows_compute() then read + * string.gx_string_ptr[index - 1] one byte past the end as well, and could add + * a row that is not in the text. + * + * The fixtures below place a line feed immediately after the string under test + * but outside the length the widget is given, so the over-read is observable + * without a sanitizer: the old code counts the out-of-bounds byte, the fixed + * code does not. + * + * Tests: + * 1. Range ending on a carriage return, line feed just past the end: the + * terminator counts as one byte, not two. + * 2. Control -- the same buffer with the line feed inside the range: two. + * 3. Control -- carriage return followed by ordinary text: one. + * 4. _gx_multi_line_text_input_new_line_character_get() gives a one-byte + * terminator for text ending in a lone carriage return, and two bytes for + * a "\r\n" pair. + */ + +#include +#include "tx_api.h" +#include "gx_api.h" +#include "gx_system.h" +#include "gx_widget.h" +#include "gx_multi_line_text_view.h" +#include "gx_validation_utility.h" + +TEST_PARAM test_parameter = { + "guix_ml_text_line_terminator_bounds_no_output", + 0, 0, 0, 0 +}; + +int main(int argc, char **argv) +{ + tx_kernel_enter(); + return 0; +} + +static VOID control_thread_entry(ULONG input); + +VOID tx_application_define(void *first_unused_memory) +{ + gx_validation_control_thread_create(control_thread_entry); + gx_validation_application_define(first_unused_memory); + gx_validation_watchdog_create(100); +} + +#ifdef WIN32 +#undef WIN32 +#endif + +#include "gx_validation_wrapper.h" +#include "demo_guix_all_widgets.c" + +static VOID control_thread_entry(ULONG input) +{ +int failed_tests = 0; +GX_MULTI_LINE_TEXT_VIEW text_view; +GX_MULTI_LINE_TEXT_INPUT *ml_input = &text_screen.text_screen_text_input_2; +GX_RECTANGLE size; +GX_MULTI_LINE_TEXT_INFO info; +GX_STRING string; + +/* The string under test is the first three bytes, "AB\r". The line feed is + deliberately present in the buffer but outside that length. */ +GX_CONST GX_CHAR cr_then_lf[] = "AB\r\n"; +GX_CONST GX_CHAR cr_then_text[] = "AB\rX"; +GX_CONST GX_CHAR trailing_cr[] = "A\r"; +GX_CONST GX_CHAR trailing_crlf[] = "A\r\n"; + + memset(&text_view, 0, sizeof(GX_MULTI_LINE_TEXT_VIEW)); + gx_utility_rectangle_define(&size, 0, 0, 200, 200); + gx_multi_line_text_view_create(&text_view, "test_terminator", GX_NULL, 0, 0, 0, &size); + text_view.gx_multi_line_text_view_font_id = GX_FONT_ID_TEXT_INPUT; + + /* Attach the widget to root so the display and font table can be found + through the parent chain. */ + text_view.gx_widget_parent = (GX_WIDGET *)root; + text_view.gx_widget_status |= GX_STATUS_VISIBLE; + + /* --- Test 1: carriage return is the last byte of the string --- */ + text_view.gx_multi_line_text_view_text.gx_string_ptr = cr_then_lf; + text_view.gx_multi_line_text_view_text.gx_string_length = 3; + + _gx_multi_line_text_view_display_info_get(&text_view, 0, 3, &info, 200); + + /* 'A', 'B' and the carriage return: 3. Counting the line feed that follows + the string would give 4 and advance the caller past its own buffer. */ + EXPECT_EQ(3, (int)info.gx_text_display_number); + + /* --- Test 2: control, the line feed is inside the string --- */ + text_view.gx_multi_line_text_view_text.gx_string_length = 4; + + _gx_multi_line_text_view_display_info_get(&text_view, 0, 4, &info, 200); + + EXPECT_EQ(4, (int)info.gx_text_display_number); + + /* --- Test 3: control, ordinary text follows the carriage return --- */ + text_view.gx_multi_line_text_view_text.gx_string_ptr = cr_then_text; + text_view.gx_multi_line_text_view_text.gx_string_length = 4; + + _gx_multi_line_text_view_display_info_get(&text_view, 0, 4, &info, 200); + + EXPECT_EQ(3, (int)info.gx_text_display_number); + + /* --- Test 4: the terminator a text input adopts from its text --- + _gx_multi_line_text_input_text_set_ext() writes a NUL after the copied + text, so the byte after a trailing carriage return is in bounds here. + These cases pin that behaviour rather than reproduce a read past the + end: the same idiom is fixed in that file so it does not depend on an + invariant established elsewhere. */ + string.gx_string_ptr = trailing_cr; + string.gx_string_length = sizeof(trailing_cr) - 1; + EXPECT_EQ(GX_SUCCESS, gx_multi_line_text_input_text_set_ext(ml_input, &string)); + + EXPECT_EQ(1, (int)ml_input -> gx_multi_line_text_input_new_line_character_size); + EXPECT_EQ(GX_KEY_CARRIAGE_RETURN, (int)ml_input -> gx_multi_line_text_input_new_line_character[0]); + + string.gx_string_ptr = trailing_crlf; + string.gx_string_length = sizeof(trailing_crlf) - 1; + EXPECT_EQ(GX_SUCCESS, gx_multi_line_text_input_text_set_ext(ml_input, &string)); + + EXPECT_EQ(2, (int)ml_input -> gx_multi_line_text_input_new_line_character_size); + EXPECT_EQ(GX_KEY_CARRIAGE_RETURN, (int)ml_input -> gx_multi_line_text_input_new_line_character[0]); + EXPECT_EQ(GX_KEY_LINE_FEED, (int)ml_input -> gx_multi_line_text_input_new_line_character[1]); + + if (failed_tests == 0) + { + gx_validation_print_test_result(TEST_SUCCESS); + exit(0); + } + else + { + gx_validation_print_test_result(TEST_FAIL); + exit(1); + } +} diff --git a/test/guix_test/regression_test/tests/validation_guix_ml_text_view_word_wrap_no_output.c b/test/guix_test/regression_test/tests/validation_guix_ml_text_view_word_wrap_no_output.c index 7f42aadb6..a75aef7db 100644 --- a/test/guix_test/regression_test/tests/validation_guix_ml_text_view_word_wrap_no_output.c +++ b/test/guix_test/regression_test/tests/validation_guix_ml_text_view_word_wrap_no_output.c @@ -13,22 +13,39 @@ * SPDX-License-Identifier: MIT and CC0-1.0 **************************************************************************/ -/* Regression test for issue #130: word-wrapping broken for UTF-8 strings. +// Some portions generated by Claude Code (Opus 5). + +/* Regression test for issue #130 (word wrapping broken for UTF-8 strings) and + * for the blank row that its first fix introduced. * * _gx_multi_line_text_view_display_info_get() had a guard * `(ch.gx_string_ptr[0] != ' ')` in the overflow condition that prevented * the overflow branch from executing when an ASCII space caused overflow. - * The space was instead appended to gx_text_display_width, making it - * exceed available_width. + * The space was instead appended to gx_text_display_width, making it exceed + * available_width. Removing that guard fixed the width but left the line + * terminator behind whenever the consumed whitespace ran to the end of the + * source line: the terminator then formed a row of its own, which draws as a + * blank line that is not in the text. + * + * available_width is derived from the measured glyph widths so that the space + * is the character that overflows, and is one pixel short of what the row plus + * that space would need. Appending the space therefore takes the row past + * available_width, which is what makes the width assertions discriminate. * * Tests: * 1. Space at overflow boundary: gx_text_display_width <= available_width. * 2. Space at overflow boundary: gx_text_display_number includes the * trailing space (next line does not start with a space). * 3. Multiple consecutive spaces at overflow boundary: all trailing spaces - * are consumed in gx_text_display_number. + * are consumed in gx_text_display_number, and the width stays within + * available_width. * 4. Normal word overflow (non-space char): backtrack to last word * boundary still works correctly (no regression). + * 5. Whitespace running to a line feed: the line feed is consumed with it, + * so no zero-width row is produced. + * 6. Same, with a carriage return / line feed pair: both bytes are consumed. + * 7. The row count a text view derives from the above: text shaped "A \nC" + * wraps to two rows, not three. */ #include @@ -81,6 +98,8 @@ GX_STRING ch; GX_CONST GX_CHAR text1[] = "A B"; GX_CONST GX_CHAR text2[] = "A B"; GX_CONST GX_CHAR text3[] = "AB CD"; +GX_CONST GX_CHAR text4[] = "A \nC"; +GX_CONST GX_CHAR text5[] = "A \r\nC"; memset(&text_view, 0, sizeof(GX_MULTI_LINE_TEXT_VIEW)); gx_utility_rectangle_define(&size, 0, 0, 200, 200); @@ -108,10 +127,12 @@ GX_CONST GX_CHAR text3[] = "AB CD"; EXPECT_EQ(1, a_width > 0); EXPECT_EQ(1, space_width > 0); - /* available_width = a_width + space_width forces the space in "A B" to + /* available_width = a_width + space_width - 1 forces the space in "A B" to be the character that causes overflow (running_width + space_width - == available_width >= available_width). */ - avail = (GX_VALUE)(a_width + space_width); + >= available_width), and leaves the row one pixel short of being able to + hold that space. Appending it, as the code before the issue #130 fix did, + therefore takes gx_text_display_width past available_width. */ + avail = (GX_VALUE)(a_width + space_width - 1); /* --- Test 1 & 2: single space at overflow boundary ("A B") --- */ text_view.gx_multi_line_text_view_text.gx_string_ptr = text1; @@ -135,6 +156,9 @@ GX_CONST GX_CHAR text3[] = "AB CD"; /* Both spaces must be consumed so the next line starts at 'B'. */ EXPECT_EQ(3, (int)info.gx_text_display_number); + /* Neither space contributes to the width of the row. */ + EXPECT_EQ(1, info.gx_text_display_width <= (USHORT)avail); + /* --- Test 4: non-space char causes overflow ("AB CD") --- */ /* available_width = a_width + b_width + space_width + 1 ensures the space fits (no overflow at space) but 'C' overflows, triggering @@ -153,6 +177,46 @@ GX_CONST GX_CHAR text3[] = "AB CD"; /* display_width must also be within available_width. */ EXPECT_EQ(1, info.gx_text_display_width <= (USHORT)avail); + /* --- Test 5: whitespace runs to a line feed ("A \nC") --- */ + avail = (GX_VALUE)(a_width + space_width - 1); + + text_view.gx_multi_line_text_view_text.gx_string_ptr = text4; + text_view.gx_multi_line_text_view_text.gx_string_length = sizeof(text4) - 1; + + _gx_multi_line_text_view_display_info_get(&text_view, 0, sizeof(text4) - 1, &info, avail); + + /* 'A', the space and the line feed: 3 bytes, so the next row starts at 'C'. + Leaving the line feed behind gives 2, and it becomes a row of its own. */ + EXPECT_EQ(3, (int)info.gx_text_display_number); + EXPECT_EQ(1, info.gx_text_display_width <= (USHORT)avail); + + /* --- Test 6: whitespace runs to a carriage return / line feed pair --- */ + text_view.gx_multi_line_text_view_text.gx_string_ptr = text5; + text_view.gx_multi_line_text_view_text.gx_string_length = sizeof(text5) - 1; + + _gx_multi_line_text_view_display_info_get(&text_view, 0, sizeof(text5) - 1, &info, avail); + + /* 'A', the space, and both terminator bytes: 4. */ + EXPECT_EQ(4, (int)info.gx_text_display_number); + EXPECT_EQ(1, info.gx_text_display_width <= (USHORT)avail); + + /* --- Test 7: the row count a text view derives from the above. + This is the quantity the golden frame tests depend on. Text shaped + "A \nC" is two rows; a leftover line feed makes it three. */ + text_view.gx_multi_line_text_view_text.gx_string_ptr = text4; + text_view.gx_multi_line_text_view_text.gx_string_length = sizeof(text4) - 1; + + /* _gx_multi_line_text_view_string_total_rows_compute() wraps at + (client width - 2 * whitespace) - 2, so size the client area to put the + wrap point exactly where the space overflows. */ + text_view.gx_window_client.gx_rectangle_left = 0; + text_view.gx_window_client.gx_rectangle_right = + (GX_VALUE)(avail + 1 + (text_view.gx_multi_line_text_view_whitespace * 2)); + + EXPECT_EQ(GX_SUCCESS, _gx_multi_line_text_view_string_total_rows_compute(&text_view)); + + EXPECT_EQ(2, (int)text_view.gx_multi_line_text_view_text_total_rows); + if (failed_tests == 0) { gx_validation_print_test_result(TEST_SUCCESS); diff --git a/tutorials/demo_guix_menu/demo_guix_menu_specifications.c b/tutorials/demo_guix_menu/demo_guix_menu_specifications.c index e618dea7c..d620c7b60 100644 --- a/tutorials/demo_guix_menu/demo_guix_menu_specifications.c +++ b/tutorials/demo_guix_menu/demo_guix_menu_specifications.c @@ -60,6 +60,13 @@ GX_STUDIO_DISPLAY_INFO demo_guix_menu_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -125,6 +132,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -190,6 +198,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -291,9 +300,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) || diff --git a/tutorials/demo_guix_transitions/demo_guix_transitions_specifications.c b/tutorials/demo_guix_transitions/demo_guix_transitions_specifications.c index b31603713..878e6f92d 100644 --- a/tutorials/demo_guix_transitions/demo_guix_transitions_specifications.c +++ b/tutorials/demo_guix_transitions/demo_guix_transitions_specifications.c @@ -62,6 +62,13 @@ GX_STUDIO_DISPLAY_INFO demo_guix_transitions_display_table[1] = } }; +static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#if (GX_ANIMATION_POOL_SIZE > 0) +static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action); +#endif + static GX_WIDGET *gx_studio_action_target_get(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -127,6 +134,7 @@ static GX_WIDGET *gx_studio_action_target_find(GX_WIDGET *current, GX_CONST GX_S return target; } +#if (GX_ANIMATION_POOL_SIZE > 0) static GX_WIDGET *gx_studio_action_parent_find(GX_WIDGET *current, GX_CONST GX_STUDIO_ACTION *action) { GX_WIDGET *parent = GX_NULL; @@ -192,6 +200,7 @@ static VOID gx_studio_animation_execute(GX_WIDGET *current, GX_CONST GX_STUDIO_A } } } +#endif UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CONST GX_STUDIO_EVENT_PROCESS *record) { @@ -293,9 +302,11 @@ UINT gx_studio_auto_event_handler(GX_WIDGET *widget, GX_EVENT *event_ptr, GX_CON } break; +#if (GX_ANIMATION_POOL_SIZE > 0) case GX_ACTION_TYPE_ANIMATION: gx_studio_animation_execute(widget, action); break; +#endif case GX_ACTION_TYPE_WINDOW_EXECUTE: if((action->flags & GX_ACTION_FLAG_POP_TARGET) ||