Compare commits

..

582 Commits

Author SHA1 Message Date
WerWolv
d76e92933a feat: Added custom application delegate 2025-01-26 14:24:22 +01:00
WerWolv
403104dda1 fix: Properly scale unifont glyphs 2025-01-26 14:21:17 +01:00
WerWolv
8334fbb236 fix: Properly apply backing scaling to pixel perfect default font 2025-01-26 14:18:20 +01:00
WerWolv
0a0323ce5d git: Run CI on feature branches 2025-01-26 13:42:19 +01:00
WerWolv
726d36ba3d git: Fix creation of ARM64 DMG trying to enter wrong path 2025-01-26 11:26:04 +01:00
WerWolv
8bb1521963 git: Fix ARM64 .app path 2025-01-26 10:54:26 +01:00
WerWolv
9457c1f2b9 git: Install ImageMagick so create-dmg can make a pretty volume icon 2025-01-26 10:45:26 +01:00
WerWolv
2b24330f9f build: Updated ImHex icons in MSI installer 2025-01-26 10:40:53 +01:00
WerWolv
9329170e59 git: Ignore missing signature when building DMG 2025-01-26 10:32:37 +01:00
WerWolv
98f3de828a git: Add create-dmg to PATH 2025-01-26 10:27:09 +01:00
WerWolv
3f38f42259 git: Produce nicer looking DMG file for macOS 2025-01-26 10:19:05 +01:00
WerWolv
058a8cdc15 fix: Missing <cstdlib> include 2025-01-26 09:22:53 +01:00
WerWolv
d0c1213ea0 fix: Crash on systems where XDG_SESSION_TYPE isn't defined 2025-01-25 23:30:00 +01:00
WerWolv
30967bac6d fix: Modifier keys not working correctly on X11 2025-01-25 23:24:56 +01:00
WerWolv
09c9bcb046 fix: Pattern data filter not working correctly without a compare value 2025-01-25 23:17:03 +01:00
WerWolv
93f1f5d076 impr: Better font scaling with larger backing scale factors 2025-01-25 22:27:59 +01:00
WerWolv
93e5d62782 fix: Web build scaling 2025-01-25 20:12:21 +01:00
Bananchiki
4d7021ece1 lang: Added Russian translation (#1964)
<!--
Please provide as much information as possible about what your PR aims
to do.
PRs with no description will most likely be closed until more
information is provided.
If you're planing on changing fundamental behaviour or add big new
features, please open a GitHub Issue first before starting to work on
it.
If it's not something big and you still want to contact us about it,
feel free to do so !
-->

### Description
This pull request introduces a complete Russian translation for ImHex,
ensuring that Russian-speaking users can navigate and utilize the
software in their native language. The translation covers all user
interface elements, menus, dialogs, and messages, providing a seamless
experience for Russian users.

### Testing
The translation has been thoroughly tested to ensure accuracy and
completeness. All translated text has been reviewed for grammatical
correctness and contextual appropriateness.

### Screenshots

![image](https://github.com/user-attachments/assets/455ca03d-0b33-45d2-9ed5-ddb404bd0728)

![image](https://github.com/user-attachments/assets/a7ebdb40-806f-43d9-ab36-deea730505c1)

![image](https://github.com/user-attachments/assets/29c5d21b-7443-4751-9129-e5fa054066d3)

Co-authored-by: Lemon4ksan <senya20151718@gmail.com>
2025-01-25 20:06:18 +01:00
WerWolv
f976988c75 impr: Try to detect backing scaling factor on the web build 2025-01-25 19:08:56 +01:00
WerWolv
1eee31fdbb fix: Debug mode only being enabled after everything has been initialized already 2025-01-25 16:54:16 +01:00
paxcut
048c483903 fix: Pattern Editor shortcuts not working correctly on different languages (#2085)
Fixes #2084 

Error in text editor prevented using shortcuts when language other than
English was chosen.

The code was mistakenly using localized name to test which window had
focus a execute the shortcut.

Fixed it by switching the name of the child window to the constant value
used to check the windows focused identity.
2025-01-25 16:34:27 +01:00
Wolf
b646ece14b impr: Refactor and restructure Event Manager (#2082)
### Problem description
This PR addresses issue #2013 that described a cluttered Event Manager.

This is a DX issue and should not impact the users whatsoever.

### Implementation description
The changes revolve around three main points:

1. the Event Manager (`event_manager.hpp`) was split into four
categories: GUI, Interaction, Lifecycle, and Provider, and two types:
Events, and Requests. This results in the following files:
    - `events_gui.hpp`
    - `events_interaction.hpp`
    - `events_lifecycle.hpp`
    - `events_provider.hpp`
    - `requests_gui.hpp`
    - `requests_interaction.hpp`
    - `requests_lifecycle.hpp`
    - `requests_provider.hpp`

2. Every event and request now has its own piece of documentation, with
a `@brief`, accompanied by a longer comment if needed, and gets its
`@param`s described.

3. The old `event_manager.hpp` import was removed and replaced by the
correct imports wherever needed, as to reduce spread of those files only
to where they are truly useful.

### Additional things
The commits have been split into (chrono-)logical steps:
- `feat`: split the Event Manager, and replace the imports
- `refactor`, `chore`: make various small changes to match the required
structure
- `docs`: add documentation for events and requests

Hopefully, this will help to review the PR.
*Note: Beware of very long rebuild times in between the commits, use
them sparingly! The Actions will ensure this PR builds anyways*

Closes #2013

---------

Signed-off-by: BioTheWolff <47079795+BioTheWolff@users.noreply.github.com>
Co-authored-by: Nik <werwolv98@gmail.com>
2025-01-25 15:32:07 +00:00
WerWolv
35e8acd69d impr: Only enable font config Apply button when setting has changed 2025-01-25 15:50:52 +01:00
WerWolv
de4135d1ad fix: ID collision with multiple items of the same name in the Accept Pattern popup 2025-01-25 15:47:09 +01:00
WerWolv
a44959ce1b feat: Added option to enable debug features in release builds 2025-01-25 15:38:57 +01:00
WerWolv
f4bad0053a fix: Linking errors in the web build 2025-01-25 15:24:44 +01:00
WerWolv
26af5987a5 fix: Properly check if distro info exists before printing it 2025-01-25 15:24:25 +01:00
WerWolv
9cf3250751 impr: Replace GitBook AI garbage with simple search API 2025-01-24 22:31:49 +01:00
WerWolv
acc77205bb fix: Image visualizer data processor nodes not working
Fixes #2081
2025-01-24 21:36:29 +01:00
WerWolv
a6b4f62d75 fix: Opening files in existing instance not working 2025-01-23 19:22:40 +01:00
WerWolv
69c5d553b5 fix: Disable postprocessing shaders in Web version 2025-01-22 19:55:17 +01:00
WerWolv
637cdd7084 git: Only generate attestation on main repo 2025-01-22 19:19:19 +01:00
WerWolv
8978e193db impr: Better OS-specific handling of system exceptions 2025-01-21 23:28:22 +01:00
WerWolv
242b100aa3 fix: Properly detect Windows 10 2025-01-20 21:45:53 +01:00
WerWolv
3a888d48df fix: ID collision with color inline visualizer 2025-01-20 21:25:00 +01:00
WerWolv
721de39dbb impr: Make icon context menu use MenuItemEx for its icons 2025-01-20 21:24:49 +01:00
WerWolv
07e29f2030 feat: Added support for OpenGL post processing shaders 2025-01-20 21:24:25 +01:00
WerWolv
c117d9b3e5 fix: Crash when changing DPI 2025-01-19 23:07:53 +01:00
WerWolv
16eae89151 fix: Save/Save As toolbar items being missing by default 2025-01-19 21:49:34 +01:00
WerWolv
95cb6d8ee6 patterns: Updated pattern language 2025-01-19 19:23:48 +01:00
WerWolv
af27c09204 fix: I guess we can still not use std::views::enumerate 2025-01-19 17:54:18 +01:00
WerWolv
5e3532267c fix: Missing glfw include 2025-01-19 17:52:32 +01:00
WerWolv
7c0331df65 impr: Hide window on macOS when close button is pressed 2025-01-19 17:04:31 +01:00
WerWolv
04ab87cd8e patterns: Updated pattern language 2025-01-19 14:42:02 +01:00
WerWolv
91f5e84250 impr: Don't insert a new line at the end of settings pages 2025-01-19 10:56:00 +01:00
WerWolv
b1edd95ebc impr: Shortcut code cleanup 2025-01-19 10:55:27 +01:00
WerWolv
758738da5c fix: Default font not being the default font 2025-01-19 10:34:54 +01:00
WerWolv
41c8be275b fix: Assert when selecting selectable text 2025-01-19 00:26:26 +01:00
WerWolv
117eb1e2a7 feat: Added more granular font settings
Fixes #1260
2025-01-18 23:34:43 +01:00
WerWolv
3129d6e8fd impr: Simplified custom font selection 2025-01-18 19:03:55 +01:00
WerWolv
2ba7db184b build: Fix favicon transparency for ImHex Web 2025-01-18 17:47:36 +01:00
WerWolv
2cb0df4080 build: Properly optimize web build 2025-01-18 16:53:11 +01:00
WerWolv
3adc2c44e6 fix: Font customization not unlocking correctly 2025-01-18 16:05:11 +01:00
WerWolv
6d3ff64894 fix: ImHex using a lot of CPU 2025-01-18 14:57:06 +01:00
WerWolv
cf84ad6196 fix: Added back old constructor for Widgets::DropDown 2025-01-18 14:56:53 +01:00
WerWolv
6259190ad9 impr: Make localization fall back to english if it doesn't exist 2025-01-18 14:40:10 +01:00
WerWolv
181be1a58e fix: Missing paste behaviour option translations 2025-01-18 14:36:31 +01:00
WerWolv
771e191f28 fix: Windows icon not being transparent anymore 2025-01-18 14:11:49 +01:00
WerWolv
d4d6893eb3 git: Make sure PORTABLE flag is created correctly 2025-01-18 13:58:20 +01:00
WerWolv
9e75562662 build: Fix RPM icon path 2025-01-18 13:45:57 +01:00
WerWolv
2b3168163b git: Extract PDBs for for portable version properly 2025-01-18 13:45:32 +01:00
WerWolv
252c06eb12 build: Extract PDBs from build files 2025-01-18 13:26:12 +01:00
WerWolv
2a51d8169a build: Move icon to correct location 2025-01-18 13:18:33 +01:00
WerWolv
7405c4b411 build: Updated disassembler library 2025-01-18 13:06:31 +01:00
WerWolv
309ae7b619 build: Fixed disassembler library git messup 2025-01-18 12:38:20 +01:00
WerWolv
64ef56a0df git: Fixed Windows PDB extraction process 2025-01-18 12:04:46 +01:00
WerWolv
fbfe7b0d25 impr: Unlock frame rate for the first few seconds after startup 2025-01-18 11:58:49 +01:00
WerWolv
8c7e1a3b2d impr: Replace icon with Papyrus icon.
Special thanks to @varlesh and @morganist
See https://github.com/PapirusDevelopmentTeam/papirus-icon-theme/issues/3909
2025-01-18 11:55:17 +01:00
WerWolv
bf249cdafe build: Updated disassembler library 2025-01-18 11:07:28 +01:00
WerWolv
59ba6f50cc build: Disable install targets of libfmt to fix Windows WIX installer 2025-01-18 11:03:51 +01:00
WerWolv
8d6e7c7d44 fix: Decompressor compile errors 2025-01-18 10:28:20 +01:00
WerWolv
52934ae166 feat: Make decompress functions return number of read bytes 2025-01-18 10:14:47 +01:00
WerWolv
56c4f2aa47 fix: ID collision with multiple banners on screen 2025-01-17 23:12:09 +01:00
WerWolv
a1d8cbd7ba fix: Properly update window position during resize 2025-01-17 23:11:53 +01:00
Nik
63a219a32b build: Added ARM64 AppImage build (#2073) 2025-01-17 22:55:41 +01:00
WerWolv
14fb256a6a build: Updated dependencies 2025-01-17 21:09:56 +01:00
WerWolv
95df7a23c3 build: Add new SDK files to Fedora package 2025-01-17 20:41:49 +01:00
WerWolv
bb17690cf5 build: Fix cv2pdb extraction errors 2025-01-17 19:56:25 +01:00
WerWolv
a943b02e43 build: Make sure unzip is installed on the CI 2025-01-17 19:50:41 +01:00
WerWolv
199f78347f build: Move PDB extraction to CI 2025-01-17 19:44:33 +01:00
WerWolv
d3d9a42d57 build: Added library plugin files to SDK 2025-01-17 19:32:52 +01:00
WerWolv
1fa45a8c84 fix: Replace bookmark comment Text Editor with multi-line text input
Closes #2056, Closes #2055
2025-01-17 17:28:13 +01:00
WerWolv
0b6316ea23 fix: Added back deleted variable to make web build work again 2025-01-17 17:26:46 +01:00
WerWolv
466a843263 build: Fix backwards compat with older cmake versions 2025-01-17 13:01:40 +01:00
WerWolv
b6ade8b101 fix: Shortcuts not working in detached windows 2025-01-17 12:39:55 +01:00
WerWolv
ff66b97e90 build: Get rid of some cmake warnings 2025-01-17 12:39:39 +01:00
WerWolv
c604ec8fb9 patterns: Updated pattern language 2025-01-16 21:23:22 +01:00
WerWolv
7564651dd5 patterns: Updated pattern language 2025-01-16 19:52:45 +01:00
WerWolv
cad17ddefd fix: Banners being misplaced on macOS 2025-01-16 19:27:22 +01:00
WerWolv
25d2f209e5 patterns: Updated pattern language 2025-01-16 19:15:39 +01:00
WerWolv
8d660c3ffe fix: Missing <numbers> include 2025-01-16 17:37:51 +01:00
WerWolv
209055d0b0 impr: Show a banner about degraded performance in debug mode 2025-01-16 17:09:17 +01:00
WerWolv
599b55965a impr: Improve the shadow of banners 2025-01-16 17:09:04 +01:00
WerWolv
69a9af5322 patterns: Added error pattern to pattern drawer 2025-01-16 17:08:49 +01:00
WerWolv
0303cd0ad0 patterns: Updated pattern language 2025-01-16 17:08:23 +01:00
WerWolv
8eb7e9fb05 fix: ID collision in provider data information section 2025-01-15 20:34:25 +01:00
WerWolv
6a1de5fc4e build: Updated ImGui to v1.91.7 2025-01-15 19:52:24 +01:00
WerWolv
a4af55cb66 build: Rename imgui_custom to imgui_backend 2025-01-15 19:52:19 +01:00
paxcut
1e17422f5e fix: Pattern Editor Find and Replace history (#2064)
The previous implementation seems to have been broken by Imgui updates. 

There is also some improvement in focus handling and also a bug in
replace where the last match was not being replaced has been fixed.

Fixed also slowdown in large files when only one char was typed by not
searching until enter has been pressed.

Added key repetitions for enter and arrows to be able to handle large
number of matches and fixed some formatting problems.
2025-01-15 19:40:12 +01:00
paxcut
8abaafab79 fix: Crash in 3D Visualizer, improved error messages (#2062)
The recently added data checks allowed invalid sized vertex arrays to be
used as if they were valid making ImHex crash.

Moved all the error messages into localization strings for translation.
2025-01-15 19:38:38 +01:00
WerWolv
71e1465524 fix: Image visualizer node trying to create texture in non-main thread 2025-01-15 19:34:58 +01:00
WerWolv
3d2ea3753b fix: Missing <clocale> include 2025-01-15 19:31:33 +01:00
Nik
88530eff8b git: Updated screenshots in readme 2025-01-15 18:31:41 +01:00
WerWolv
df3decf71b build: Updated libwolv 2025-01-15 18:08:45 +01:00
WerWolv
565ee4cb2d fix: Banner positions with multi-viewports enabled 2025-01-15 18:08:05 +01:00
WerWolv
40fc325ba9 fix: Disable bogus Keypad to function key conversions on macOS 2025-01-15 17:59:57 +01:00
WerWolv
6aca16102d impr: Move up the right column on the welcome screen to avoid a scrollbar at default size 2025-01-15 17:54:35 +01:00
WerWolv
cb11b57ab1 feat: Added banners, replace some modals with them 2025-01-15 17:54:07 +01:00
WerWolv
d504937d50 fix: Empty regions in Intel Hex and Motorola SREC files not being displayed correctly 2025-01-14 23:54:07 +01:00
WerWolv
6bfdb7ca4e fix: Make sure provider switch buttons and close button don't overlap 2025-01-14 22:10:58 +01:00
WerWolv
e1637824c6 impr: Make strings in the data information view selectable and copyable 2025-01-14 22:05:29 +01:00
WerWolv
e36f2f2bcb fix: Replace "data processor" text with "data inspector" for the custom data inspector row hint 2025-01-14 17:51:26 +01:00
WerWolv
1a54e08f11 fix: Remove constexpr from functions that really aren't constexpr 2025-01-14 17:50:48 +01:00
WerWolv
ecc86ee429 fix: ImNodes not being deinitialized correctly 2025-01-14 17:50:29 +01:00
WerWolv
185a593bc2 fix: AllowWhileTyping shortcuts only working while typing 2025-01-14 17:50:06 +01:00
WerWolv
4a916ebb89 feat: Added New File option to the GNOME launcher and a --new cli option 2025-01-14 17:49:48 +01:00
WerWolv
1c305ca762 fix: Icons still following custom font size when using default font 2025-01-13 22:34:30 +01:00
WerWolv
17fff56fa0 impr: Make sure Windows title icon is scaled correctly 2025-01-13 22:31:24 +01:00
WerWolv
ec1b1c2b7d impr: More constexpr 2025-01-13 22:31:06 +01:00
WerWolv
7bae22f56f fix: Font selector still saying "Custom Font Path" 2025-01-13 22:20:53 +01:00
WerWolv
21e5eeef16 impr: Reduce default font size slightly, adjust element sizes on welcome screen 2025-01-13 22:17:14 +01:00
WerWolv
bf5eea80f6 impr: Make font size setting use points instead of pixels 2025-01-13 22:04:55 +01:00
WerWolv
9f9a6d9827 impr: Move Jetbrains mono into regular font selector, allow it to be scaled 2025-01-13 22:04:44 +01:00
WerWolv
ae622e6d75 git: Merge WebAssembly build into main build artifacts script, add to releases 2025-01-12 23:08:09 +01:00
WerWolv
68fbff631f git: Fix github pages artifact name 2025-01-12 22:50:39 +01:00
WerWolv
6cdce75095 git: Upload artifact for ImHex Web build 2025-01-12 22:03:50 +01:00
WerWolv
f699e76c56 build: Fix comment causing issues with docker 2025-01-11 21:41:14 +01:00
WerWolv
a729329cd4 impr: Added missing [[nodiscard]]s 2025-01-11 21:40:42 +01:00
WerWolv
d5020ce9bb impr: Rename Jump To option to Follow Selection to avoid confusion with Go To 2025-01-11 21:40:26 +01:00
WerWolv
126868c251 fix: Hang when filtering for a large number of items in the pattern data view 2025-01-11 17:22:53 +01:00
WerWolv
b206e9fc95 fix: Copy-paste error with "Extend selection left" shortcut name 2025-01-11 16:42:00 +01:00
WerWolv
4b6ff68464 git: Fixed CI permissions 2025-01-11 16:28:29 +01:00
WerWolv
b23a0febb5 git: Added build provenance attestation for most artifacts 2025-01-11 16:17:27 +01:00
WerWolv
05ad547341 git: Use zstd to compress .deb builds 2025-01-11 15:57:42 +01:00
paxcut
f10af882a7 fix: Text Editor find option jumping to the wrong location (#2060)
After successfully finding matches and setting the cursor to them, the
screen would jump to the original window location upon closing the
window.

The error was caused by the wrong assumption that the scroll location
should be restored when window is closed. Instead, the right amount of
scrolling needs to be calculated to account for the window no longer
covering part of the text editor. Unused variable was discarded.

Another unrelated error is that the history of search names cannot be
accessed which will be addressed at a later PR.
2025-01-09 18:39:00 +01:00
WerWolv
98f32ebcad impr: Made interactive help api easier to use 2025-01-09 18:34:39 +01:00
WerWolv
e2c302836f feat: Added support for scanning binaries for UTF-8 strings 2025-01-09 18:33:45 +01:00
WerWolv
f1d9642cf6 impr: Better color picker widgets in the settings 2025-01-07 21:46:26 +01:00
WerWolv
5c58e5b545 fix: Selection highlight color setting not working
Fixes #2059
2025-01-07 18:09:56 +01:00
WerWolv
803cb335e1 feat: Added interface accent colors 2025-01-07 00:06:52 +01:00
WerWolv
ae4dde8255 impr: Unlock frame rate in more cases to make the UI feel more responsive 2025-01-06 20:34:00 +01:00
WerWolv
cb34f68b1b patterns: Updated pattern language 2025-01-06 20:15:21 +01:00
WerWolv
96ef983cfb fix: ASCII column not getting highlighted anymore 2025-01-06 20:14:27 +01:00
WerWolv
d8c3d67dfe build: Disable romfs compression in web build 2025-01-05 21:25:28 +01:00
WerWolv
5de5153663 impr: Simplify hex editor class API 2025-01-05 21:24:13 +01:00
WerWolv
1e747b6831 patterns: Updated pattern language 2025-01-05 19:18:46 +01:00
WerWolv
fbe9d16073 build: Updated libromfs 2025-01-05 17:52:04 +01:00
WerWolv
d02c0073a0 build: Ignore pdb copy file errors 2025-01-05 15:27:54 +01:00
WerWolv
1090b9879c build: Make pdb copy operation happen at install time 2025-01-05 15:20:03 +01:00
WerWolv
5a6af976cd build: Rename output pdb file if necessary 2025-01-05 15:14:25 +01:00
WerWolv
55e39a5d30 build: Fix dwarf stripping logic 2025-01-05 15:00:45 +01:00
WerWolv
c9b1ddfb59 build: Updated libromfs 2025-01-05 14:56:16 +01:00
WerWolv
f7dd696ffc build: Silence stupid brew errors 2025-01-05 14:51:03 +01:00
WerWolv
70f210ac5d build: Updated libromfs 2025-01-05 14:37:39 +01:00
WerWolv
cad1c11f8b build: Updated dependencies 2025-01-05 14:17:54 +01:00
WerWolv
f7fa305e82 build: Generate pdb file for libpl, significantly reduce binary size 2025-01-05 12:06:32 +01:00
WerWolv
f96c51e854 impr: Added shortcut for Copy as -> Custom Encoding 2025-01-05 11:12:56 +01:00
WerWolv
c19705d3e5 git: Try to silence brew error messages again 2025-01-05 10:42:29 +01:00
WerWolv
1190511994 impr: Cleanup frame rate unlocking code 2025-01-04 23:43:10 +01:00
WerWolv
69ee7ef63c build: Updated libwolv 2025-01-04 23:42:56 +01:00
WerWolv
fc95e5a9a8 impr: Unlock frame rate when scrolling or focusing 2025-01-04 22:00:26 +01:00
WerWolv
6ecc495d43 feat: Added visibility toggle to hide bookmark highlighting 2025-01-04 21:40:18 +01:00
WerWolv
6e861001cf impr: Allow all highlights to overlap each other 2025-01-04 21:40:03 +01:00
WerWolv
c56af08c7e impr: Allow highlights of multiple overlapping bookmarks to render 2025-01-04 20:46:56 +01:00
WerWolv
e68abefe48 impr: Use info icon for more help hovers 2025-01-04 19:21:22 +01:00
WerWolv
fd0635cb82 fix: Hex editor right click menu not working on macOS 2025-01-04 19:08:37 +01:00
WerWolv
baa3cfb354 fix: User folders being added twice 2025-01-04 18:30:57 +01:00
iTrooz
aea9bab853 build: Make MacOS arm64 build use clang 19 (#2050) 2025-01-04 18:10:48 +01:00
WerWolv
48de609f53 impr: Added telemetry about whether ImHex runs on a corporate machine 2025-01-04 16:11:35 +01:00
WerWolv
71f4f87288 impr: Make sure init tasks always get executed 2025-01-04 16:11:05 +01:00
WerWolv
48b202c56b patterns: Updated pattern language 2025-01-04 15:38:20 +01:00
Nik
d975019a7b impr: Revamp frame rate limiting system to make ImHex feel less laggy in certain cases (#2049) 2025-01-04 15:35:19 +01:00
Nik
6009b5013b feat: Let ImHex use the native menu bar on macOS (#2048) 2025-01-04 15:35:06 +01:00
WerWolv
24979d7fbd impr: Other Providers -> Other Data Sources 2025-01-04 14:06:03 +01:00
WerWolv
b4bf42e377 fix: Unit test build error due to changed Provider::getTypeName() signature 2025-01-04 13:57:48 +01:00
WerWolv
f94819351a impr: Make maximum in-memory file size setting easier to use. Bump value to 512MiB 2025-01-04 13:56:20 +01:00
WerWolv
8da69c11d9 impr: Remove the word "Provider" from places where it doesn't fit 2025-01-04 13:28:35 +01:00
WerWolv
635a825095 fix: Signed/Unsigned comparison error 2025-01-04 13:03:38 +01:00
WerWolv
bbffdbf56f feat: Allow #pragma magic to index from the end of the data with negative addresses
Closes #2047
2025-01-04 12:49:14 +01:00
WerWolv
1c30533d19 fix: Off-by-one when calculating hashes of selected regions
Fixes #2046
2025-01-04 00:15:35 +01:00
WerWolv
dcd80fe6ad impr: Properly scale window on wayland 2025-01-03 15:09:06 +01:00
WerWolv
525ab8d945 fix: Settings not being saved correctly anymore 2025-01-03 14:07:09 +01:00
WerWolv
d8fb3f526a fix: Shortcut migration not working correctly in some cases
Fixes #2045
2025-01-03 10:16:22 +01:00
WerWolv
a55df1d111 fix: Exception being thrown when custom disassembler folders didn't exist 2025-01-03 00:15:52 +01:00
WerWolv
2cf32ba38d fix: Default smooth font not being scaled correctly 2025-01-03 00:15:28 +01:00
AlexGuo1998
c82907153e fix: Set LZMA decompressor memory limit to 1GiB (#2044)
<!--
Please provide as much information as possible about what your PR aims
to do.
PRs with no description will most likely be closed until more
information is provided.
If you're planing on changing fundamental behaviour or add big new
features, please open a GitHub Issue first before starting to work on
it.
If it's not something big and you still want to contact us about it,
feel free to do so !
-->

### Problem description
<!-- Describe the bug that you fixed/feature request that you
implemented, or link to an existing issue describing it -->

See #2033 (`hex::dec::lzma_decompress` reports an error when
decompressing a small buffer).

### Implementation description
<!-- Explain what you did to correct the problem -->

Set the LZMA decompressor memory limit to 1GiB fixed. Print a warning
when exceeded, and abort with returning `false`.

### Screenshots
<!-- If your change is visual, take a screenshot showing it. Ideally,
make before/after sceenshots -->

Normal result when decompressing a small buffer


![image](https://github.com/user-attachments/assets/5b9e6b07-464e-41f6-bdc7-f5b1cd351069)

Warning message when `memlimit` is exceeded: (Set to 64B here for a
demo)
> W: lzma_decompress memory usage 1114168 bytes would exceed the limit
(64 bytes), aborting


![image](https://github.com/user-attachments/assets/04abf3ef-1d29-4846-bb41-214695c7d09c)

### Additional things
<!-- Anything else you would like to say -->

Is the warning wording OK? I'm not a native English speaker so please
change it if you want to.
2025-01-02 08:42:28 +00:00
WerWolv
165403da67 fix: ImHex freezing on AMD GPUs when resizing
Fixes #1842
2025-01-01 20:39:12 +01:00
WerWolv
0e4d94946e fix: Disable recent files on web build since they can't work there 2025-01-01 17:08:31 +01:00
WerWolv
9f9c5abf35 impr: Prevent window from being moved while hovering over items on macOS 2025-01-01 16:45:11 +01:00
WerWolv
6a3b10111f feat: Highlight main menu item when using a shortcut 2025-01-01 16:19:38 +01:00
WerWolv
0a55f4bf83 patterns: Updated pattern language
Fixes #2042
2025-01-01 11:36:04 +01:00
WerWolv
493d66d991 fix: Crash when using hex editor when provider == nullptr 2024-12-31 21:30:05 +01:00
WerWolv
268b495a29 fix: Make capstone use little endian by default 2024-12-31 21:17:19 +01:00
WerWolv
180f4926f8 impr: Make disassembly view contain data per-provider 2024-12-31 21:16:27 +01:00
WerWolv
c853349b78 impr: Force reset window decoration to expected value after exiting full screen mode 2024-12-31 21:04:09 +01:00
WerWolv
ee555e0da9 fix: Make sure WM_NCCALCSIZE never tries to sleep a negative amount of time
#1842
2024-12-31 18:06:31 +01:00
WerWolv
3dec4cc698 fix: Signed/Unsigned integer compare 2024-12-31 17:21:37 +01:00
WerWolv
d7b2b94cec impr: Reduce jittering when changing the number of hex columns 2024-12-31 17:04:32 +01:00
WerWolv
c9e88586aa feat: Added option to fit hex columns to screen width 2024-12-31 11:35:09 +01:00
WerWolv
1d641504b1 fix: Format string issues 2024-12-31 10:01:01 +01:00
WerWolv
655e068b9b impr: Added changed data information to diff view table 2024-12-31 00:47:32 +01:00
WerWolv
67a9f314cc impr: Added icons to more context menus 2024-12-31 00:45:47 +01:00
WerWolv
ff2b58e8a3 fix: Copy paste errors 2024-12-30 23:58:34 +01:00
WerWolv
a1482cb40e fix: Tooltips not being hidden when disabling hex editor highlights 2024-12-30 23:45:48 +01:00
WerWolv
89111059f9 feat: Added setting to disable hex editor highlights entirely 2024-12-30 23:24:59 +01:00
WerWolv
0ae823716a feat: Added a preview to the Edit -> Copy as options
Closes #2026
2024-12-30 23:16:11 +01:00
WerWolv
dab3f722e8 feat: Added "Jump to address" option to data inspector row context menu 2024-12-30 22:32:06 +01:00
WerWolv
0dc1af0747 feat: Added option to change radix of numbers in hex editor view 2024-12-30 21:00:43 +01:00
WerWolv
021206e052 impr: Added icons to pattern editor context menu 2024-12-30 12:18:55 +01:00
WerWolv
cb09cf3734 feat: Added context menu and next/previous buttons to the data inspector 2024-12-30 12:07:21 +01:00
WerWolv
f0525d6463 fix: Building issues with the web build 2024-12-30 10:10:38 +01:00
WerWolv
e22424ffa4 fix: Settings not being saved correctly on the web version 2024-12-29 23:53:23 +01:00
WerWolv
6e666c64e8 patterns: Updated pattern language 2024-12-29 22:42:32 +01:00
WerWolv
5f5f6ac539 feat: Added option to move selection back to hex editor footer
Closes #2024
2024-12-29 21:08:08 +01:00
WerWolv
3024c79f4f impr: Allow the favorite column in the pattern data view to be hidden 2024-12-29 20:38:51 +01:00
WerWolv
ba96d86dc2 impr: Properly align favorite icons inside of the buttons in the pattern drawer 2024-12-29 20:38:25 +01:00
WerWolv
40ec7195d1 patterns: Updated pattern language 2024-12-29 15:20:57 +01:00
WerWolv
f10dfa0c20 patterns: Updated pattern language 2024-12-29 14:40:51 +01:00
WerWolv
6a5473f6fe impr: Moved Windows DPI awareness to manifest file, added detached console allocation
Closes #1543
2024-12-28 23:47:42 +01:00
WerWolv
f79de6fbe8 fix: Web build not starting fully anymore 2024-12-28 22:48:06 +01:00
Nik
ec4ee3132b git: Added note about launching assertion failures when launching the AppImage (#2038) 2024-12-28 22:31:34 +01:00
WerWolv
1298f2b688 impr: Refactor previous commits to work with other environments too 2024-12-28 21:37:45 +01:00
WerWolv
534a2f1d28 impr: Apply framebuffer scaling to SVGs as well 2024-12-28 20:52:49 +01:00
WerWolv
c8e95cf3c3 impr: Keep default font at whole-integer sizes 2024-12-28 20:46:26 +01:00
WerWolv
c4918a963c fix: Default font not being scaled on macOS 2024-12-28 20:45:12 +01:00
WerWolv
bf6f738d2e impr: Make text look super pretty on macOS finally 2024-12-28 20:42:05 +01:00
Nik
1605904eb1 git: Updated more runners to Ubuntu 24.04 2024-12-28 16:49:33 +01:00
Nik
138517f116 git: Updated system requirements and compile info in the readme 2024-12-28 16:48:32 +01:00
WerWolv
d4a4cb2e80 fix: Crash when providing invalid version string to semantic version class
Fixes #2036
2024-12-28 15:59:13 +01:00
WerWolv
9a9dc328e3 build: Switch to custom lunasvg repo to allow offline builds 2024-12-28 13:39:07 +01:00
WerWolv
50eea0a4f1 impr: Replace Firacode with JetbrainsMono font 2024-12-28 12:43:34 +01:00
WerWolv
528a8b5b46 fix: Exception being thrown when getting version parts from invalid version 2024-12-28 11:45:05 +01:00
WerWolv
0db0bc53fa revert: Make pattern editor scroll bar look more like all other scrollbars 2024-12-28 00:39:10 +01:00
WerWolv
0297c267e9 impr: Display "ImHex" in title bar when null provider is open 2024-12-27 23:56:14 +01:00
WerWolv
5af85f24f6 impr: Allow command palette to be closed by clicking on the menu bar 2024-12-27 23:53:55 +01:00
WerWolv
5110a7578e fix: Rendering issues with text editor in bookmark view 2024-12-27 23:36:21 +01:00
WerWolv
5af28670f0 fix: Ctrl sometimes getting stuck when pressing ALT GR and other keys at the same time
#2019
2024-12-27 23:15:20 +01:00
WerWolv
efa2b781dd impr: Better create hash popup size 2024-12-27 23:14:39 +01:00
WerWolv
979f151181 fix: Don't show library plugins in --plugins subcommand 2024-12-27 20:06:17 +01:00
WerWolv
6f125f18c3 impr: Make pattern editor scroll bar look more like all other scrollbars 2024-12-27 20:01:00 +01:00
WerWolv
edba7051f0 impr: Make interactive tutorials select windows when they're highlighted 2024-12-27 19:41:45 +01:00
WerWolv
fa1ae8d746 fix: Tutorial highlights not working anymore correctly 2024-12-27 18:28:22 +01:00
WerWolv
a476617432 build: Fix remaining build issues 2024-12-27 00:02:37 +01:00
WerWolv
ffac13bfef disasm: Updated disassembler library 2024-12-26 23:28:38 +01:00
WerWolv
f877bf21ba fix: Warning on macOS about wrong format argument 2024-12-26 23:01:19 +01:00
WerWolv
4bc4882b1f disasm: Updated disassembler library 2024-12-26 23:00:59 +01:00
WerWolv
084c17dc26 fix: Missing endian setting in ARM64 disassembler 2024-12-26 22:39:57 +01:00
WerWolv
26c39d6822 fix: ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback -> ImGui_ImplGlfw_InstallEmscriptenCallbacks 2024-12-26 20:19:55 +01:00
WerWolv
aefc173227 fix: Wrong --reset-settings subcommand description 2024-12-26 20:05:07 +01:00
WerWolv
bf44a1cce6 feat: Added initial support for custom disassemblers 2024-12-26 20:04:45 +01:00
WerWolv
a76c6c653d impr: Refactor disassembler system to make it more modular 2024-12-26 18:41:34 +01:00
WerWolv
f11205bba7 build: Updated more dependencies 2024-12-26 14:41:43 +01:00
WerWolv
72d9c5019c build: Updated dependencies 2024-12-26 14:30:52 +01:00
WerWolv
58d66e3e97 fix: Added migration routine to fix shortcuts 2024-12-26 14:01:54 +01:00
WerWolv
43c88a2fab feat: Added system to handle version migrations 2024-12-26 14:01:46 +01:00
paxcut
9ce64ec6e1 fix: Pattern Editor console scroll jumping. (#2029)
Some issues related to the padding added to scroll past the end for
console that has padding added.
Added a shortcut to scroll editors one pixel at a time.
Fixed whole lines always drawn at the top even if scroll value is chosen
so that only a portion of the top line is visible. This caused errors in
horizontal scrolling.
Fixed Ctrl-F Ctrl-G and Ctrl-H messing the editor display. 
Fixed the end of the line could not be clicked with mouse 
Fixed line numbers and their lines could be displayed at different
heights.
Made numbers that represented lines floats instead of integers to allow
partial line display.
2024-12-25 18:51:58 +01:00
WerWolv
c749d6a7dc fix: Disable ImGui assert that causes random crashes on resize 2024-12-25 18:49:50 +01:00
WerWolv
f3e6d35c98 build: Updated ImGui glfw backend 2024-12-25 18:44:43 +01:00
WerWolv
0be539b8a5 feat: Added option to copy data as escaped string
#2026
2024-12-25 16:45:34 +01:00
WerWolv
0454a369e5 fix: Crashes when disassembling data
Fixes #2025
2024-12-25 16:36:53 +01:00
WerWolv
010025cbfa fix: Wrong localStorage key for achievements 2024-12-25 16:21:38 +01:00
WerWolv
61cae0a9f8 fix: Missing emscripten include 2024-12-25 16:19:50 +01:00
WerWolv
9e83d9e68c fix: Disable browser ctrl + S in web build 2024-12-25 16:17:51 +01:00
WerWolv
248acd5e26 fix: Properly save achievements in web version 2024-12-25 16:17:33 +01:00
WerWolv
42c1f5601a fix: Saving files in web version not working correctly 2024-12-25 15:57:54 +01:00
WerWolv
9c1a673047 impr: Force update all installed content store items after an update 2024-12-25 14:29:41 +01:00
WerWolv
99b90f90ac fix: Unused variable in wasm build 2024-12-25 13:03:55 +01:00
WerWolv
6ead8d8b49 fix: Certain shortcuts not being captured by ImHex Web 2024-12-25 12:36:06 +01:00
WerWolv
9b12232e9f revert: Broken fix for cursor not being set at end of line 2024-12-25 01:41:50 +01:00
WerWolv
c1ed1baaad fix: Shortcuts not working correctly in Web build 2024-12-25 01:34:11 +01:00
WerWolv
ab34312089 fix: Clicking past end of line in text editor putting cursor before last character 2024-12-25 01:33:41 +01:00
WerWolv
a25d92fbb7 build: Bumped version to 1.37.0.WIP 2024-12-25 01:33:36 +01:00
WerWolv
6005af1595 build: Bumped version to 1.36.0 2024-12-24 13:43:04 +01:00
WerWolv
9a4329807a patterns: Updated pattern language 2024-12-24 13:07:26 +01:00
WerWolv
8e01da4c12 lang: Fixed settings language string in hashes view 2024-12-24 13:06:38 +01:00
WerWolv
eb8ea520c7 build: Make ImGui use old CRC algorithm 2024-12-24 11:09:45 +01:00
WerWolv
512fcd361b impr: Modernize the disassembler, hashes and yara view 2024-12-24 10:57:09 +01:00
WerWolv
aad6f6bcbe build: Updated ImGui to v1.91.6 2024-12-24 00:37:04 +01:00
WerWolv
0af21505d7 git: Add retry mechanism for creating dmg on x86 mac 2024-12-24 00:00:22 +01:00
WerWolv
2ae69e8e72 feat: Allow command palette to work with previous results 2024-12-23 23:42:45 +01:00
WerWolv
9274fac8e1 build: Updated libwolv
Fixes #2007
2024-12-23 23:24:38 +01:00
WerWolv
e2f82c60e6 fix: Crash when using text editor as last item in a window 2024-12-23 23:17:19 +01:00
WerWolv
bfddf24204 impr: Added hints to various input fields 2024-12-23 23:16:55 +01:00
WerWolv
382599dcf6 fix: Better icon text input width calculation 2024-12-23 23:16:35 +01:00
WerWolv
5f2c07f2d8 fix: Icon text inputs not being the same length as other items 2024-12-23 21:48:47 +01:00
WerWolv
914024c0b5 impr: Added note about adding new data inspector row 2024-12-23 21:47:16 +01:00
WerWolv
c5d3387962 impr: Replaced centered text notes with overlays 2024-12-23 21:30:31 +01:00
WerWolv
7cc99c6fc9 impr: Added better notes to the settings tabs in the pattern editor view 2024-12-23 21:26:22 +01:00
WerWolv
a29b502a33 impr: Made pattern editor resize separator taller 2024-12-23 20:15:50 +01:00
paxcut
20cb74364f fix: Jumpy text editor scrolling (#2023)
Two major improvements:
1) see through scrollbars when not hovered.
2) un-scrollable line numbers.

Also enlarged display region by eliminating padding. There is still a
problem with lines jumping when the scrollbar is dragged but it is
limited to one line and probably due to floating point error for scroll
bar number. It is much less noticeable than the previous jumping which
could involve several pages.

---------

Co-authored-by: WerWolv <werwolv98@gmail.com>
2024-12-23 20:14:42 +01:00
WerWolv
1c5a50c8d8 impr: Added better file open error messages to the file provider 2024-12-23 14:07:35 +01:00
WerWolv
470523cc86 fix: Jittery scrolling in Text Editor 2024-12-23 11:44:34 +01:00
WerWolv
f6bc3d4650 impr: Replace more assert() calls with IM_ASSERT() 2024-12-23 11:22:20 +01:00
WerWolv
41b1228d31 fix: Make sure all text editor members are correctly initialized 2024-12-23 11:21:39 +01:00
paxcut
2cb4462274 impr: Better top margin handling for text editor. (#2021)
The top margin changes when popups block some portion on the screen.
Previously it was implemented adding blank lines at the bottom which
created problems if the windows was scrolled all the way to the bottom
and the popups were issued. The newer implementation doesn't use spaces
and simply resets the top of the window to be higher making the popup
interaction with the window more natural (no text disappears on the
lines the popup overlaps the text). changes can be identified form the
variables mTopMargin,mOldTopMargin and mNewTopMargin.

Unfortunately those changes revealed problems in cursor navigation that
needed to be addressed. Namely, the window will scroll up and down on
the line before last/second line at the top and similar problems for the
left and right. Those changes correspond to the function
EnsureCUrsorVisible()

Fixing those reveled yet more problems with scrolling past the end of
the file using the keyboard which required adding some more variables
and functions to support the correct handling, You find those changes in
the function MoveDown.

I also renamed some variables that had the wrong casing and fixed the
pasting but that is missing one line.
2024-12-23 10:35:53 +01:00
WerWolv
810cd40ccd impr: Replace strerror with C++ functions 2024-12-23 01:42:06 +01:00
WerWolv
f931beb49a impr: Make inserting bytes at the start of the file with insert mode work better 2024-12-23 01:33:52 +01:00
WerWolv
1c3dfc9b2f fix: ID collision in Jump To menu 2024-12-23 01:00:58 +01:00
WerWolv
a1d4545e29 fix: Don't allow negative regions in region widgets 2024-12-23 01:00:41 +01:00
WerWolv
8865db2007 lang: Added missing memory file rename key 2024-12-23 01:00:13 +01:00
WerWolv
d2056d9409 fix: Crash on exit 2024-12-23 00:59:55 +01:00
Nik
74e74ddc38 git: Make CodeQL CI use ninja 2024-12-23 00:06:59 +01:00
WerWolv
5fcb737559 fix: Only update widgets of settings that were changed
Fixed crashing on exit and speeds up settings writes
2024-12-20 21:23:19 +01:00
Nik
9303025427 git: Just disable coverage generation for now 2024-12-18 22:56:44 +01:00
WerWolv
680985fc13 git: Update gcovr filters 2024-12-18 21:57:40 +01:00
WerWolv
5a360eb614 patterns: Updated pattern language 2024-12-18 20:33:05 +01:00
paxcut
4a74bd78fd fix: Console either printed no newlines or printed extra ones. (#2016)
The reason for the error were the text preprocessor added to deal with
tabs was created to process entire files, not just lines or words. In
that context it cleaned trailing new lines if any existed but in the new
role that's not only unwanted but erroneous.

### Problem description
After that was fixed the console started to add two empty lines between
each output line. When splitting a string using new lines you need to
not add a new line to the last line created. Even if the text ends in an
end line, the split screen code is set to not discard empty lines.

### Implementation description
The fixes are straightforward.
2024-12-18 20:19:18 +01:00
WerWolv
0f53656952 build: Small ImPlot3D fixes to make it build on all platforms 2024-12-18 20:18:27 +01:00
WerWolv
9ca40d3651 build: Added ImPlot3D 2024-12-17 23:51:45 +01:00
WerWolv
ab12503f62 patterns: Drastically improved time it takes to find favorites 2024-12-17 23:37:39 +01:00
paxcut
b446d7fd4a impr: Make scrolling in pattern editor feel less janky (#2009)
I have implemented a fix that makes the scrollbars behave like they do
in VScode. Vertically you can scroll past the end of the file until only
the last line can be seen at the top. The horizontal bar behaves as if
every line was the same length which is the length of the longest line
in the file. Not only this creates a better user experience, but it also
fixes the annoying flicker that occurs when scrolling through large
files. Also, I have switched all the old draw calls to render text to
regular TextUnformatted calls which adds extra stability to the
resulting display.

To implement the behavior I added a dummy widget with the desired
dimensions.
2024-12-17 22:44:40 +01:00
WerWolv
fd46d85762 git: Another attempt fixing gcovr 2024-12-17 22:42:48 +01:00
WerWolv
fa421afb00 git: Ignore all gcov errors related to missing files 2024-12-17 22:07:16 +01:00
paxcut
a79d3e28ca fix: Crashes when getting tabs into text editor (#2008)
This time it may be for good. 


### Implementation description
As requested I added the preprocessing functionality into the pattern
editor. I had to duplicate a few functions and update the c++ library to
version 20. but now I can make sure the pattern editor doesn't see a tab
again. I also removed the preprocessor from where it was before because
it is not needed anymore. The changes were tested using a file that used
tabs for all its white space. The file was pasted into the pattern
editor and imported as well. I both cases no crashes occurred and the
files had no tabs on them.
2024-12-17 21:36:00 +01:00
WerWolv
fbb4f65735 patterns: Updated pattern language 2024-12-17 21:34:18 +01:00
WerWolv
00c62c90f6 git: Try to fix coverage scan 2024-12-17 21:33:53 +01:00
WerWolv
384aa6e6a9 fix: Narrow to wide type compare in loop in timestamp visualizer 2024-12-16 22:17:58 +01:00
WerWolv
1c755249ec git: Use ninja for building everything 2024-12-16 22:10:22 +01:00
WerWolv
2c303b5bf2 build: Actually fixed unit tests 2024-12-16 21:47:40 +01:00
WerWolv
415e3b4a93 impr: Added commit hash and branch to nightly popup on welcome screen 2024-12-16 21:37:34 +01:00
WerWolv
8d9b056c8c build: Fixed building of unit tests 2024-12-16 21:37:11 +01:00
WerWolv
a527a7f0b0 patterns: Updated pattern language 2024-12-16 21:32:19 +01:00
WerWolv
d78d955d11 impr: Better ellipsis usage in menus 2024-12-16 21:27:57 +01:00
BioTheWolff
9375a60cd9 feat: Implement paste behaviour popup when pasting over one-byte regions (#2004)
### Problem description
This PR implements the feature request described in #1995, that
describes a problem with the `Paste` vs `Paste all` commands. Users
could be thrown off by having `Ctrl+V` act as a simple "Paste over
selection", whereas it's generally accepted as a "Paste all".

### Implementation description
<!-- Explain what you did to correct the problem -->
This PR introduces a new setting, called "Paste behaviour" (under the
"Hex Editor" category).
This setting has three values:
- `Paste over selection`: the current implementation for ImHex. Pastes
only over the selection region, in this case pasting only one byte;
- `Paste everything`: allows ImHex's `Paste` to behave like a `Paste
all` when selecting one-byte regions;
- `Ask me next time`: prompts the user for a choice of behaviour
(default value).

*Note: as users generally use `Paste all` when selecting one-byte
regions, calling `Paste` when selecting over two or more bytes is not
affected by this change, and will still behave like the usual `Paste`
command.*

When selecting a one-byte region, and calling the Paste command, users
that have not defined a preferred behaviour in the settings will be
prompted to choose one, using a brand new popup. The popup also allows
the user to cancel, which will not change the settings' value, and will
cancel the paste action altogether.

### Screenshots
The new popup:

![image](https://github.com/user-attachments/assets/2b0fd532-d4e7-4209-9dd7-8a79278692ea)

The new setting:

![image](https://github.com/user-attachments/assets/2644c35e-7332-422e-8fae-ae8ad0507126)

### Additional things
I'm not very good with long descriptions, so I'm open to any suggestions
regarding the text that is included in the popup!
I do think however that we should keep a hint indicating that `Paste
all` is always an option, which could solve the issue altogether for
very new users.

---------

Signed-off-by: BioTheWolff <47079795+BioTheWolff@users.noreply.github.com>
Co-authored-by: Nik <werwolv98@gmail.com>
2024-12-16 20:35:48 +01:00
WerWolv
bb99b9a0ef fix: Shortcuts acting as duplicates in settings 2024-12-16 20:26:04 +01:00
WerWolv
313e59d7f9 fix: Shortcuts applying to multiple views at once 2024-12-16 20:14:26 +01:00
WerWolv
e34e0e62f2 patterns: Fixed json builtin types throwing non-patternlanguage exceptions 2024-12-15 23:13:43 +01:00
paxcut
212f75f1cb fix: Tabs messing up content of text editor (#2005)
<!--
Please provide as much information as possible about what your PR aims
to do.
PRs with no description will most likely be closed until more
information is provided.
If you're planing on changing fundamental behaviour or add big new
features, please open a GitHub Issue first before starting to work on
it.
If it's not something big and you still want to contact us about it,
feel free to do so !
-->

### Problem description
<!-- Describe the bug that you fixed/feature request that you
implemented, or link to an existing issue describing it -->

### Implementation description
<!-- Explain what you did to correct the problem -->

### Screenshots
<!-- If your change is visual, take a screenshot showing it. Ideally,
make before/after sceenshots -->

### Additional things
<!-- Anything else you would like to say -->
2024-12-15 23:08:26 +01:00
WerWolv
a07c79efcb fix: Pattern editor shortcuts being set to use CTRL on macOS 2024-12-15 22:39:24 +01:00
WerWolv
89090b25e3 impr: Various shortcut improvements 2024-12-15 21:44:43 +01:00
WerWolv
721164e562 fix: Deinitialization order 2024-12-15 21:44:36 +01:00
BioTheWolff
b8ba980a20 fix: Chinese (Simplified) translation showing up twice (#2006)
### Problem description
As described in issue #1841, there was a duplicate on the `Chinese
(Simplified)` translation.
After closer inspection, this came from an i18n file (Script loader,
specifically) having a bad ISO code (`zh_CN` instead of the expected
`zh-CN`).

This also caused a big impact on end users, as loading the latter
(`zh_CN`) would cause the whole UI to be displayed in English (the
fallback language), and only the script loader being translated into
Chinese.

### Implementation description
Fixed the i18n code in the Script loader file.

### Additional things
Closes issue #1841

Signed-off-by: BioTheWolff <47079795+BioTheWolff@users.noreply.github.com>
2024-12-15 17:20:04 +01:00
WerWolv
79ded38434 patterns: Updated pattern language 2024-12-15 14:12:27 +01:00
WerWolv
f52db884a9 lang: Update casing of next provider / previous provider options 2024-12-15 12:16:57 +01:00
WerWolv
ee4bb33b0a impr: Display sub menus for shortcut settings 2024-12-15 11:54:10 +01:00
WerWolv
caf8fa8e25 impr: Show byte relationship diagrams side by side if there's enough space 2024-12-15 11:46:54 +01:00
WerWolv
c46dea4c9e impr: Update settings menu values when settings are changed 2024-12-15 11:12:56 +01:00
WerWolv
002b7b4f87 impr: Make Copy as ASCII string use ALT + C to be more consistent 2024-12-15 11:02:34 +01:00
WerWolv
0a6a8c671f impr: Better naming for various menu entries 2024-12-15 11:02:20 +01:00
WerWolv
36014b706d fix: Wrong header location in disassembler view 2024-12-15 10:52:11 +01:00
paxcut
df5e01d4eb impr: Better 3D Visualizer error messages, wrap long visualizer errors (#1969)
### Problem description
Long error messages were forcing the width of the window to span the
entire screen.

### Implementation description
The fix was sending the long message to the log and outputting a short
message to the 3d visualizer window.

---------

Co-authored-by: WerWolv <werwolv98@gmail.com>
2024-12-15 10:12:14 +01:00
WerWolv
c6f1525f55 git: Silence last brew call 2024-12-15 10:01:24 +01:00
WerWolv
5511259f2d git: Updated more workflows 2024-12-15 00:44:32 +01:00
WerWolv
f2ea7ca5d1 git: Silence brew github actions annotations 2024-12-15 00:28:22 +01:00
WerWolv
6184bbeae2 build: Updated libwolv 2024-12-14 23:55:04 +01:00
WerWolv
21506578f5 impr: Removed more instanced of codecvt 2024-12-14 22:39:07 +01:00
WerWolv
f39f395393 impr: Replace codecvt with libwolv conversion functions 2024-12-14 22:20:48 +01:00
WerWolv
ed0a94659e impr: Added load and base address to instruction pl types 2024-12-14 21:52:19 +01:00
WerWolv
7f75706584 impr: Replace hex::unused with std::ignore 2024-12-14 21:35:54 +01:00
WerWolv
3f316e42f2 build: Remove unavailable warning flags from gcc builds 2024-12-14 21:35:42 +01:00
WerWolv
4a331c0331 git: Replace gcc-toolset-12 with gcc-toolset-14 fir EL9 runner 2024-12-14 20:36:32 +01:00
WerWolv
6a28de100c impr: Rename font definition files 2024-12-14 20:36:09 +01:00
WerWolv
992f18b94b impr: Optimize build times a bit 2024-12-14 19:15:49 +01:00
Nik
040a606b39 feat: Added various custom built-in types to the pattern language (#1991) 2024-12-14 16:52:36 +01:00
BioTheWolff
13e079d1b8 feat: Add capability to paste as string literal in files (#1998)
### Problem description
As suggested in #1904, ImHex could benefit from having the capability of
pasting text directly into the editor.
This also complements the "Copy as... ASCII string" capability already
implemented in the software.

### Implementation description
A new shortcut called `Paste all as string` (to resemble the naming of
the `ASCII string` copy option) now allows to paste plaintext directly.
This shortcut is mapped to the `CTRL + ALT + SHIFT + V` keybind.

Internally, a new flag called `asPlainText` has been added to the
`pasteBytes` function, to minimise code changes and streamline code
readability.
The buffer is a simple type cast of the clipboard, without any
modification applied, which is then handed to the provider's `write`
function.

### Screenshots
The new shortcut is visible in the menu, just below the other paste
options:

![image](https://github.com/user-attachments/assets/41a2a512-5c39-4984-bab6-114c58266351)

---------

Signed-off-by: BioTheWolff <47079795+BioTheWolff@users.noreply.github.com>
2024-12-14 16:52:14 +01:00
Roman
d9a7f40eb4 fix: Shortcuts not being disabled correctly when menu items are disabled (#1992)
Fix crash on UNDO/REDO shortcut press when in "title screen"

### Problem description
ImHex crashes when (by default CTRL + Z/Y) undo/redo is pressed when on
"title"/"starting" screen (no file open, tested on Windows release build
and Linux [WSL] from-source build).

This is due to the shortcut's callback being called even if the
`provider` is `nullptr`. (see `createEditMenu` function).
Theoretically, this is prevented by the `enabledCallback` function
passsed to `addMenuItem`. In this case, though,
`addMenuItem` correctly propagates `enabledCallback` to menu item
creation but does not pass `enabledCallback` to
shortcut creation. Thus, when handling shortcuts, `enabledCallback` is
not used at all and the shortcut's callback
can be called in contradiction with its preconditions. (specified by
`enabledCallback`)

### Implementation description
The implementation wraps the callback in a check that decides whether
the shortcut is enabled or not.

(see changed files)
```c++
        auto callbackIfEnabled  = [enabledCallback, function]{ if (enabledCallback()) { function(); } };
```

This function is then passed along instead of the `function` (shortcut's
callback).

Alternatively, we can check for `nullptr` in the callback directly. This
would require modification of `createEditMenu`'s contents.
(I did not choose this implementation because I do not think it
addresses the root of the issue).

### Screenshots
None

### Additional things
I'm not sure how big of a deal it is but I am unsure whether I can
capture (`[enabledCallback, function]`) by reference or not.
2024-12-14 16:51:40 +01:00
paxcut
8d123da847 feat: Added goto line popup to text editors (#1984)
Since the popup is fairly small I opted for a straight addition parallel
to the find/replace. To make code more clear the functions that create
each popup were coalesced and made their interface simpler. That forced
a reorganization of the data processing which translates to a larger
number of changes than usual. Most of those changes are just moving some
action from one function to another.

The old method to identify popups using the size and position of the
window was dropped in favor of one based on child windows and using
their names for a much easier and robust identification.

Added specialized functions to text editor to jump to a line or to given
coordinates with a simple interface that simplifies older code that
performed the same task.

Because this PR modifies heavily the same code as the previous PR (1983)
it is also included here to make merging easier.

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2024-12-14 16:50:45 +01:00
Nik
093310a9e5 git: Updated CI to latest available compilers and distros (#2003) 2024-12-13 00:07:46 +01:00
WerWolv
21b315b97e impr: Added image load and image base address to disassembler
#1994
2024-12-10 20:33:28 +01:00
Nik
c70cc3a6f1 git: Disable AppArmor to make fedpkg not fail anymore (#1997) 2024-12-10 13:34:39 +01:00
WerWolv
1e71d8afc0 feat: Added Disassemble selection option to the Edit menu
#1994
2024-12-09 21:35:08 +01:00
WerWolv
cb6b74b269 fix: Use after free when deleting data processor nodes with errors 2024-12-09 14:40:07 +01:00
WerWolv
a1e399aa1a fix: Use after free in Text Editor when copying ErrorHoverBoxes 2024-12-09 14:39:46 +01:00
WerWolv
e1dfdd9400 fix: Missing include 2024-12-09 00:05:36 +01:00
iTrooz
6ab2e81f1c chore: Add documentation about popup opening 2024-12-06 23:40:05 +01:00
paxcut
cf09029847 feat: Added clickable links to error messages in the pattern editor (#1988)
Errors printed in the console can be clicked to have the cursor jump to
the source code line where the error is at.

The mouse cursor changes its shape to indicate which parts of the error
message can be clicked on the console. When the cursor jumps, the text
editor takes the focus away from the console and it scrolls the window
to make the line with the error is visible if it isn't. This code uses
the function created for the go-to PR but adds code to switch focus to
the target. When the codes are merged please keep both the part that
jumps the cursor and the part that sets the focus.

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2024-12-06 22:45:36 +01:00
WerWolv
d02e170dac fix: Build issue on systems where size_t is not u64 2024-12-06 22:03:12 +01:00
WerWolv
2b715bb0de impr: Batch fills into larger chunks 2024-12-06 10:15:32 +01:00
BioTheWolff
2dcaf2c77b fix: Various achievements issues (Edit the Hex, ROM Hacks) (#1985)
### Problem description
As described in #1846:
- the `Edit the Hex` achievement doesn't unlock when it should
- the `ROM Hacks` achievement is not using event-driven architecture
(the functions call `unlockAchievement` themselves)

### Implementation description
Firstly, for the `Edit the Hex` achievement:
- replaced the old event listener on `EventPatchCreated` with a listener
on `EventProviderDataModified`, which picks up bytes changes
- ensured the provider data change comes from a File provider, else
unlocking the achievement wouldn't make sense
- *Note*: a discovered side effect is that the "Fill" function modifies
the provider byte per byte (with a for loop)
- there is no use in testing the size of the data change, as it is
always 1 byte
- the Fill function could probably be reworked to fill in whole regions
at a time?

About the `ROM Hacks` achievement:
- implemented the new, still unused `EventPatchCreated` event.
- signal signature is `const unsigned char *, u64, const IPSKind`:
buffer pointer, buffer size, and IPS kind (IPS/IPS32)
- make use of the `::post` and `::subscribe` methods on said event to
unlock the achievement
- **WARNING::behaviour change**: the event's `post` signal has been
moved in the success branch of the IPS generation condition, meaning
that achievement will only unlock if IPS patch export has worked. I felt
it would make more sense than unlocking an achievement on an error, if
there was any to raise.

---------

Signed-off-by: BioTheWolff <47079795+BioTheWolff@users.noreply.github.com>
2024-12-06 00:36:42 +01:00
BioTheWolff
1b9f4f33de feat: Added export disassembler results to ASM file (#1987)
### Problem description
<!-- Describe the bug that you fixed/feature request that you
implemented, or link to an existing issue describing it -->
This PR implements the feature request #1781, that suggests adding a
button to export disassembled instructions into an ASM file.

### Implementation description
This adds a button to export the current disassembled instructions to an
ASM file. Said file is suffixed by an `.asm` extension if not specified
at file creation.

*Note: the file is written to for every `Disassembly` item in the
vector, as it was the easiest and most memory-conservative way of doing
it.*

The file creation task is implemented based on IPS patch exports, so it
fits the same pattern.
A `ToastError` is raised when the ASM export could not complete
successfully.

Translations have been implemented for both `en_US` and `de_DE` for the
two new keys:
- `hex.disassembler.view.disassembler.export`: file export button
- `hex.disassembler.view.disassembler.export.popup.error`: error popup
text

### Screenshots
The button is disabled when the disassembler is working, or when the
disassembly vector is empty.

Here is a complete breakdown of the visual changes:

![image](https://github.com/user-attachments/assets/af0ce701-9d77-45f1-9a5a-90d68d00bb0d)

### Additional things
As expected, the exporter writes every item's `mnemonic` and `operators`
to the file, producing an output like this:

`example.asm`
```asm
.byte 0x7f, 0x45, 0x4c, 0x46
andeq r0, r1, r2, lsl #2
andeq r0, r0, r0
andeq r0, r0, r0
eorseq r0, lr, r3
andeq r0, r0, r1
andeq r1, r0, r0, asr #32
andeq r0, r0, r0
andeq r0, r0, r0, asr #32
```

---------

Signed-off-by: BioTheWolff <47079795+BioTheWolff@users.noreply.github.com>
2024-12-05 23:04:38 +01:00
Justus Garbe
3c73f88a52 fix: AES ECB mode in Data processor not working at all (#1986)
Fix the AES ECB mode in the data processor along with some other misc
fixes:
- Fixed nullpointer node not working
- Fixed crypto module incorrectly using mbedtls api
- Fixed crypto module ignoring mbedtls errors
- Fixed silently ignoring of errors in AES node
2024-12-05 20:56:43 +01:00
paxcut
8acdc19be4 fix: Pattern Editor context menus being entries greyed out when they shouldn't be (#1983)
Some context menu entries that were available as shortcuts were greyed
out. This PR aims to fix them and improve how context menus work for the
text editor and the console. The improvements include:
- automatic focus on right click
- automatic selection on right click. If selected text is right-clicked
then copy, cut and find will use the selection, if no selection is
clicked but there is text were right-clicked, then the word will be
selected and used. If right-clicking empty space copy and cut will be
greyed out and find will start empty.
- similar functionality now exists for the console as well except the
menu has fewer options due to it being read-only.
- added esc to close console context menu
2024-12-05 19:34:51 +01:00
WerWolv
22252d9044 fix: Patterns in pattern data view not being editable in providers that are not writable from the start 2024-12-05 16:37:31 +01:00
WerWolv
5948a74ad1 fix: Multiple memory corruption issues 2024-12-05 16:36:27 +01:00
alexkar598
e46d9d7650 fix: HexII visualisation does not allow hex characters in the edit field (#1982)
### Problem description
At the moment, attempting to edit files using HexII data visualization
is impossible as the editing fields only allow numeric characters but is
interpreted as a hex value

### Implementation description
I yoinked the params used for the hex visualization edit field. 

### Screenshots

![image](https://github.com/user-attachments/assets/2d61bf61-9893-4cfb-a2bf-6ff954aef903)

### Additional things
Ideally this should instead accept the format used by HexII, but I have
what scientists describe as a skill issue and this at least makes it
possible to use HexII without switching back to hex for editing.
2024-12-03 23:05:00 +01:00
Justus Garbe
813276c907 feat: Add constant data input to buffer node (#1981)
Added a hex data input field to the buffer node in the data processor.


![image](https://github.com/user-attachments/assets/a98e1174-7d35-4130-b9f7-9ef5d0703bc7)
2024-12-03 23:03:04 +01:00
BioTheWolff
7032473ecf impr: Added MIME types for project files on UNIX systems (#1980)
<!--
Please provide as much information as possible about what your PR aims
to do.
PRs with no description will most likely be closed until more
information is provided.
If you're planing on changing fundamental behaviour or add big new
features, please open a GitHub Issue first before starting to work on
it.
If it's not something big and you still want to contact us about it,
feel free to do so !
-->

### Problem description
<!-- Describe the bug that you fixed/feature request that you
implemented, or link to an existing issue describing it -->
This PR addresses issue #491 regarding the inability to open ImHex
project files (`.hexproj`) directly from various UNIX Desktop
Environments.

_NB: This PR's scope is limited to UNIX systems, as I have no access to
MacOS systems and could not find a way to automatically create file
associations on Windows._

### Implementation description
<!-- Explain what you did to correct the problem -->
In order for project files to be recognised as such, we need to create a
new MIME type. According to [RFC 6838 section
3.2](https://www.rfc-editor.org/rfc/rfc6838#section-3.2), additional
application MIME types should be defined with a vendor prefix.
_NB: This is preferred over the deprecated `x-` prefix, although RFC
6838 states that the vendor should be "a well known producer"_

This PR proposes a new mime type for ImHex project files:
`application/vnd.imhex.proj`, and associates it with the file format
`*.hexproj`.

It also implements small changes in the Arch Linux and RPM builds, in
order to correctly ship the MIME XML file during installation.

### Additional things
<!-- Anything else you would like to say -->
The implemented change has been manually tested in the following UNIX
systems and graphical environments:
- Arch Linux, with Gnome 47.2
- Arch Linux, with XFCE4
- Fedora 41 Workstation Edition, with Gnome 47.0
- Fedora 41 Plasma, with KDE Plasma 24.08.2
- Ubuntu 22.04.5, with Gnome 42.9

Which tests the functionality of the following build types:
- Arch Linux's `.zst` packages
- Debian `.deb` packages
- RPM packages

For Arch Linux and RPM packages, this has been tested to ensure that
post-installation hooks (such as regeneration of the MIME database) is
correctly executed (which it is). No further changes than those
implemented in the PR are needed.

---------

Signed-off-by: BioTheWolff <47079795+BioTheWolff@users.noreply.github.com>
2024-12-03 23:02:40 +01:00
WerWolv
807f1fb561 patterns: Updated pattern language 2024-12-02 21:16:35 +01:00
WerWolv
296f80ffe5 fix: Data information sections getting duplicated in NullProvieders 2024-12-02 21:16:20 +01:00
paxcut
d45e0d1cac impr: Replace all asserts with IM_ASSERT in the Text Editor (#1979)
All asserts in TextEditor.cpp were replaced with IM_ASSERTs so that if
they are hit ImHex won't crash and give a nice popup message instead.
2024-12-02 20:21:57 +01:00
WerWolv
4b8f9984d5 fix: Get rid of ranges again because still not all compilers support it 2024-12-02 20:21:15 +01:00
WerWolv
7623610704 build: Updated dependencies 2024-12-01 23:24:57 +01:00
WerWolv
a7fe384a31 feat: Added entropy drop/spike annotations to the entropy graph 2024-12-01 22:27:04 +01:00
WerWolv
485ce887ea patterns: Updated pattern language 2024-12-01 17:38:59 +01:00
Nik
2a0bb79513 fix: Potential overflow when calculating audio sample index
Fixes
[https://github.com/WerWolv/ImHex/security/code-scanning/223](https://github.com/WerWolv/ImHex/security/code-scanning/223)

To fix the problem, we need to ensure that the multiplication is
performed using a larger integer type to avoid overflow. This can be
achieved by casting one of the operands to `u64` before performing the
multiplication. This way, the multiplication will be done in the larger
type, preventing overflow.

We will modify the line `index += frameCount *
device->playback.channels;` to cast `frameCount` to `u64` before the
multiplication.


_Suggested fixes powered by Copilot Autofix. Review carefully before
merging._

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2024-12-01 16:07:24 +01:00
paxcut
21ae88702f fix: Empty text editor has no cursor. (#1976)
Even if focus is given to the pattern editor the cursor will not show
until the editor contains printable chars.

### Problem description
I was using the wrong condition to enter the loop that skipped the
default empty document.

### Implementation description
The fix was to check if there are lines of text that need to be
processed even if they are empty.
2024-12-01 09:58:37 +01:00
BobSmun
0ff1bb392c fix: CRC64 parameters being limited to 32bit (#1975)
This addresses #1974
2024-11-30 18:35:03 +01:00
WerWolv
01af2f364c patterns: Updated pattern language 2024-11-30 13:49:27 +01:00
paxcut
a639dddd19 impr: Turned static variables into member variable in the Text Editor (#1973)
to avoid potential problems in the future if opening several popup
windows at the same time becomes possible.
2024-11-29 20:44:56 +01:00
WerWolv
71ec6c5061 fix: Separator stride setting displaying incorrect values 2024-11-29 20:44:04 +01:00
WerWolv
8c4c4f5e8b impr: Hide segment number in hex editor when holding down shift 2024-11-29 20:43:37 +01:00
WerWolv
2c2d3b2de3 feat: Display visualizers in pattern tooltips 2024-11-29 20:23:36 +01:00
WerWolv
caae5c9711 fix: Move visualizer drawer to correct library 2024-11-29 17:37:02 +01:00
paxcut
72822d03aa fix: Stereo sound visualizations (#1970)
Even tough the sound visualizer has `channels` as one of its parameters
it wasn't using it properly.

### Problem description
The biggest problem is that at each frame the index was being advanced
per channel frame_count increments. The number of channels also
determines how many graph will be needed to display the graphs of the
visualized sound files. Besides these two problems there were many
others like incorrect playback time, cracking audio, etc. which will not
be mentioned.

### Implementation description
To sample the signal a channel sampler was created based on the one used
previously that returns as many sampled signals as there are channels.
This PR aims hopefully at fixing all the problems encountered, and it
has been tested extensively using `Audacity` exported samples to ensure
the visualizer fidelity on playback and graph appearance.

### Screenshots

![image](https://github.com/user-attachments/assets/03453860-693f-4af4-b6c6-e828a102c389)
2024-11-29 17:22:22 +01:00
paxcut
9de3dd89c5 feat: Added support for inline visualizers in custom data inspectors (#1966)
### Problem description
This PR aims at making inline visualizers work on the data inspector so
that more rgb encodings can be added as custom pattern language
inspector rows. This was never setup to work because the inline
visualizer rendering function was a private member function.

### Implementation description
In order to be accessible from the inspector class the rendering
function was made public.

### Additional things
Missing still is the tooltip to make it behave like other color entries.
2024-11-29 17:20:28 +01:00
dependabot[bot]
bcb69b9855 git: bump dawidd6/action-download-artifact from 3 to 6 (#1972)
Bumps
[dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact)
from 3 to 6.

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-29 13:55:41 +01:00
paxcut
6d2761f141 feat: Added multiline search/replace and fixed various crashes. (#1911)
### Problem description
Previous implementation ignored everything after the first newline.
Other changes include:
- Added isEmpty() function that checks if editor has no content.
- replaced asserts with default behavior to avoid unneeded crashes.
- fixed off by one error in DeleteRange()
- some crashes occurred because readily available corrective actions
were not being taken. For example start/end being -1 in DeleteRange().
- At the heart of search/replace is the ability to translate from
indices into the text string to line/column coordinates used for
everything. To this end a function (StringIndexToCoordinates) was added
to do the translation taking utf-8 chars into account. This made the
recently added Utf8BytesToChars function unneeded, so it was removed.
- Removed commented out code that is not useful anymore. Also removed
tooltip code which is also unused.
- Removed unused parameter wrapAround to FindNext().
2024-11-29 09:37:05 +01:00
WerWolv
05c25b6aff patterns: Updated pattern language 2024-11-28 21:27:02 +01:00
WerWolv
9be9eb90f6 feat: Added hex editor segment separators 2024-11-28 21:26:55 +01:00
WerWolv
71f2f3a5fc patterns: Updated pattern language 2024-11-27 20:44:14 +01:00
WerWolv
862b1d407c patterns: Updated pattern language 2024-11-26 21:27:09 +01:00
WerWolv
5da0da48c8 build: Fix building for webassembly 2024-11-25 00:08:08 +01:00
WerWolv
3f1a51e350 patterns: Updated pattern language 2024-11-24 23:48:13 +01:00
WerWolv
d167e43252 impr: Optimization for searching for favorite and group patterns 2024-11-24 23:21:23 +01:00
WerWolv
fe9eecd031 build: Updated ImGui to v1.91.5 2024-11-24 18:55:56 +01:00
WerWolv
ded8cff415 build: Update to macOS 13 in more places 2024-11-24 15:51:22 +01:00
WerWolv
3497716a00 git: Bumped macOS runners to macOS 13 2024-11-24 15:33:55 +01:00
WerWolv
c78b4a3343 patterns: Updated pattern language 2024-11-24 15:16:06 +01:00
WerWolv
17359be58a build: Fixed remaining build issues 2024-11-24 14:16:48 +01:00
paxcut
382a62343d fix: Fixes for breakpoints (#1923)
WARNING: this PR won't compile unless [PR 132 from pattern language
repository](https://github.com/WerWolv/PatternLanguage/pull/132) is
merged first. Some changes here are shared by at least another PR to
this repository but there should not be any conflicts as the shared
changes are identical.

### Problem description
fix: Editing patterns with breakpoints sets behaves unexpectedly. As a
simple example, set a breakpoint and insert a blank line somewhere
before the breakpoint location. The breakpoint will appear to move but
in reality it hasn't. To see this set another breakpoint elsewhere in
the file and the old one will be displayed where it is really located
at.

The reason for this and many other problems with breakpoints is that
currently ImHex keeps two set of breakpoints in text editor and in
evaluator that are independent of each other, ie, changes to one don't
affect the other. This PR aims at synchronizing the two sets through the
per provider breakpoints that exist in view pattern editor.

### Implementation description

It accomplishes this by making the text editor version of breakpoints
the principal source of vectors and the ones in evaluator the effective
version. The first allows one to modify the text around and at the
breakpoint and notify others that the changes have induced changes in
the breakpoint locations. The effective breakpoints allow the insertion
and deletion of breakpoints.

View pattern editor is where breakpoints are updated. It receives
notifications from text editor about changes and then makes sure the
version in evaluator is updated with those changes. View pattern editor
also manages breakpoint addition and deletion so before making changes
it gets a copy of the current ones from text editor, sets the ones in
evaluator, uses the evaluator functions to add or delete breakpoints and
finally sets the text editor version with the new version.
2024-11-24 12:06:44 +01:00
paxcut
7e0f60615b fix: Achievements resetting after restart (#1965)
### Problem description
Loading a file on the command line or using the context menu in windows
was triggering an achievement before the achievements file was loaded.
This resulted on the achievements.json file to be overwritten with all
the achievements reset except for the one to open files.

### Implementation description
This PR fixes the problem by introducing a boolean that is used to check
if the file has been loaded.

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2024-11-24 11:34:44 +01:00
Kirill R.
e1a49b38a7 build: Fix macos blurry flicker (#1956)
<!--
Please provide as much information as possible about what your PR aims
to do.
PRs with no description will most likely be closed until more
information is provided.
If you're planing on changing fundamental behaviour or add big new
features, please open a GitHub Issue first before starting to work on
it.
If it's not something big and you still want to contact us about it,
feel free to do so !
-->

### Problem description
<!-- Describe the bug that you fixed/feature request that you
implemented, or link to an existing issue describing it -->

seem to fix #1809. I couldn't build the app, so hoping that's the right
place to update resulting `Info.plist`

### Implementation description
<!-- Explain what you did to correct the problem -->

### Screenshots
<!-- If your change is visual, take a screenshot showing it. Ideally,
make before/after sceenshots -->

### Additional things
<!-- Anything else you would like to say -->
2024-11-24 11:31:30 +01:00
paxcut
4333b8c351 fix: Text cursor not moving to the correct location with ctrl+c -> ctrl+v (#1951)
This code fixes issue #1950 This PR depends on PR [#27
](https://github.com/WerWolv/libwolv/pull/27) on libwolv repo


### Problem description
See description of the problem on the issue linked above

### Implementation description
The code in the PR uses function added to the libwolv repository to
remove tabs if they exist on the provider. Additionally, any pasted tab
on the pattern editor will be translated to spaces automatically. This
code was tested successfully using the pattern posted in the issue.
2024-11-24 11:31:06 +01:00
paxcut
6464377a89 impr: Added code so that when debugger pauses at a line, the line is highlighted (#1932)
regardless of the method used to pause the evaluation at that line.
2024-11-24 11:29:08 +01:00
Shubhankar Sarangi
4fcf732814 impr: Reserve space to avoid multiple allocations when loading scripts (#1929)
std::forward ensures that the arguments are perfectly forwarded to
loadScript
By reserving space in the features vector based on the size of scripts,
we can avoid multiple memory allocations during the loop. If an
exception occurs, returning an empty vector immediately clarifies that
no scripts were loaded. Without reservation, each call to emplace_back
could potentially trigger a reallocation if the current capacity is
exceeded, which is costly in terms of performance. This leads to more
efficient memory management and can significantly speed up the execution
time when dealing with a large number of scripts.


![image](https://github.com/user-attachments/assets/3e290162-fb8b-4f00-a71b-6009494b2dab)
2024-11-24 11:28:45 +01:00
paxcut
0d4f3e5735 fix: ImHex hangs when pressing F5 while in a breakpoint (#1920)
### Problem description
fix: pressing F5 (start pattern execution ) while being in a break point
hangs ImHex.


The reason for hanging ImHex was that the shortcut procedure was not
checking if the pattern was already running, and it attempted to start
another one. This makes ImHex wait indefinitely for a lock to be
released

### Implementation description

To fix the hanging of ImHex we check the runtime for current evaluation
and if detected we stop it. In all cases the evaluation is started
again.
2024-11-24 11:24:42 +01:00
paxcut
1f2e453e20 fix: Various pattern editor settings not being per-provider (#1917)
### Problem description
Fixes provided for the following unreported bugs.

- Environment variables are set to be per provider but used as if they
are not. When a project is loaded all the environment variables for each
provider are assigned to the first provider making it impossible to add
new ones to the other providers.

- When switching providers, the text editor selection, the text editor
breakpoints, the console text, the console selection and the console
cursor position of the old provider are being assigned to the new
provider

### Implementation description

This PR aims at fixing both errors by:
- using variable defined to be per provider so that they affect their
provider only when necessary.

- creating new per provider variables and using them so that each
provider has their own console, selections and breakpoints.

In order to support the newly added per provided features new functions
were added to the text processor for selections and breakpoints. All the
new per provider variables are defined and used in view pattern editor.
2024-11-24 11:24:14 +01:00
Paulo Casaretto
5236c7b468 fix: Use machine headers to auto select arch for macOS process memory provider (#1910)
Fixes https://github.com/WerWolv/ImHex/issues/1807

### Problem description

Build fails for MacOS x86-64 due to using a wrong architecture header.

### Implementation description

Used the headers for mach that auto select the correct architecture.

### Additional things

This is being used in https://github.com/NixOS/nixpkgs/pull/330303 as a
patch

Co-authored-by: Nik <werwolv98@gmail.com>
2024-11-24 11:21:29 +01:00
Ikko Eltociear Ashimine
1738e8883f fix: Typo in tar.hpp (#1909)
occured -> occurred
2024-11-24 11:20:51 +01:00
paxcut
cc4563afb0 impr: Added back missing runtime error markers (#1907)
### Problem description
Moving error markers to be underwaved created s couple of errors: 
- Markers that were 1 char long and located at the end of the line
didn't show on text editor.
- Markers that had zero length or no stack trace didn't show on text
editor.

### Implementation description

- The first error was caused by an off by one error in the column index.
- There was no implementation for errors that had no location or zero
length. Now errors with no location will be shown at the beginning of
the line where they occur. Errors with zero length will be marked from
their location to the end of the line, therefore, errors with no stack
trace will be marked from the beginning to the end of the line.
2024-11-24 11:20:15 +01:00
paxcut
4b3bf2f358 fix: Textures, uv coordinates and light source not updating properly. (#1872)
### Problem description
The only time textures would update was through the file picker. Once UV
coordinates were used, disabling them didn't have any effect because the
vertex array didn't invalidate the corresponding buffer array. When
`shouldUpdate` is true, the light source needs to know as well,
otherwise it will set the location at 0,0.

### Implementation description

Textures were fixed by creating a member variable that holds the file
name of the texture used in the last model rendering.

Instead of invalidating buffer arrays it is much simpler to define a
default UV coordinate set for the case when no UV is specified. if a
texture is not present then the values of UV will not be used. If there
is a texture it must be a minimum of 1 pixel in size. So we choose the
UV coordinates so that every vertex gets assigned the color at the 0,0
coordinate of the texture.

When `shouldUpdate` is on, we also turn `shouldUpdateLightSource` on.

Also included are some formatting changes that are purely aesthetic.

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2024-11-24 11:18:19 +01:00
WerWolv
80084f5c5a patterns: Updated pattern language 2024-11-24 11:17:29 +01:00
descawed
6d14b3f6bd Fix process memory provider on Linux (#1933)
### Problem description
The process memory provider currently doesn't function correctly on
Linux due to incorrect handling of the special procfs file
`/proc/<pid>/maps`. I don't know if some of this behavior could vary by
distro and/or kernel version, but I've observed the following issues in
my Ubuntu 24.04 environment.

- The current code in master calls `file.readString()` which attempts to
determine the size of the file by [seeking to the
end](https://github.com/WerWolv/libwolv/blob/master/libs/io/source/io/file_unix.cpp#L148).
However, procfs files don't have a defined size, so this fails with a
return of -1. libwolv [interprets this as the file size and attempts to
allocate an enormous
buffer](https://github.com/WerWolv/libwolv/blob/master/libs/io/source/io/file.cpp#L30),
which results in an exception, so ultimately the process memory provider
is unusable on the current code.
- The previous version of the code that went out in 1.35.4 was calling
`readString` with a fixed maximum size of `0xF'FFFF`. This avoids the
seek issue, but when working with special files, a single `read` call
isn't guaranteed to read the requested number of bytes even if that many
bytes are available. In practice, on my machine, this call only ever
reads the first few dozen lines of the file. So the feature works in
this version, but it's unable to see the vast majority of the process'
address space.
- On a more minor note, on rows in the `maps` file that have a filename,
the filenames are visually aligned by padding spaces between the inode
column and filename column. ImHex includes these spaces as part of the
filename, resulting in most of the path being pushed out of the visible
area of the window.

### Implementation description

- To ensure the entire `maps` file is read, I've changed the code to
read from the file in a loop until we stop getting data. I've also set a
fixed limit on the maximum number of bytes to read in one go to avoid
issues with trying to determine the file size.
- I've added a `trim` call to remove any padding around the filename.

### Screenshots
Exception in `file.readString()` in current code (for some reason this
also causes the window to become transparent):

![mem_regions_exception](https://github.com/user-attachments/assets/ac9f472b-3d60-446d-be9c-b028b041e547)

Abridged memory region list in 1.35.4:

![mem_regions_truncated](https://github.com/user-attachments/assets/44e60b23-49f8-41b9-a56b-54cb5c82ee72)

Complete memory region list after this PR:

![mem_regions_working](https://github.com/user-attachments/assets/bdb42dc6-bcd3-42b1-b605-a233b98e8d2e)

### Additional things
I was focused on fixing this ImHex feature here, but I wonder if some of
this should be addressed in libwolv. Maybe `readBuffer` in file_unix.cpp
should read in a loop until it has the requested number of bytes or
encounters EOF/error?

---------

Co-authored-by: Justus Garbe <55301990+jumanji144@users.noreply.github.com>
2024-11-07 13:41:04 +01:00
iTrooz
592f613a61 fix: re-enable C/C++ languages in CMake (#1942) 2024-10-24 08:14:07 +02:00
WerWolv
3739bcc40c fix: Multiple race conditions with pattern sorting 2024-10-22 16:20:08 +02:00
WerWolv
101c7a36fb patterns: Updated pattern language 2024-09-18 23:54:56 +02:00
WerWolv
21be959cba fix: Another text editor merge issue 2024-09-15 16:14:43 +02:00
WerWolv
b3a0ebe7b6 fix: Some merge issues 2024-09-15 15:55:21 +02:00
paxcut
96a588bd86 fix: F3 failed to locate the correct set of matches if file was edited after doing a search (#1867)
### Problem description
The bug can be reproduced as follows:
1) Using Ctrl-F do a search for a term that occurs several times in the
file. and press F3 to visit them.
2) Go back to the fop of the file and insert 3 blank lines. 
3) Pressing F3 once or many times will not find the term entered above.


### Implementation description
The reason for this bug is that the positions of the matches are not
being reset when changes can potentially move them.
The fix consists on resetting the search locations when changing the
contents of the file and redoing the search after the changes are made.
The bug was specially problematic when doing replace because the
replacement position would be identified as a match. This PR fixes
replace as well.

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2024-09-15 15:32:10 +02:00
paxcut
866b956680 feat: Added per provider cursor position for the Pattern editor (#1861)
### Problem description
Currently, the pattern editor does not remember where the cursor is
located in each provider. For example, suppose you have 2 providers in
your project, and you scrolled down to line 200 in the first pattern to
make some changes and remembered that the code you want to insert is in
the second provider. Then you switch to the second provider, look for
the code and find it in line 235. Switch back to the first one, and you
are at the beginning of the file. So you again look for the line to edit
paste it to realize that it needs code a few lines before the place you
found it. You switch to the second provider, and you are at the top
again. This gets annoying very fast.

### Implementation description

This PR ensures that, when you return to the pattern in the editor for
any of the opened providers, the cursor will still be at the same place
it was when you switched to a different one. Each provider pattern saves
its cursor position and returns to it when you switch to that provider.
It does that by creating a PerProvider variable and using it when
providers are first opened to set it to the origin and when switching
providers it first saves the position of the old provider and then loads
and sets the saved position of the new provider.

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2024-09-15 15:28:37 +02:00
paxcut
d88252c6fd fix: Unable to resize 3d-visualizer window in x-direction (#1860)
changes needed were:
1) add an extra dummy empty widget so that width of child and parent are
not always the same. 2) Width of reset button needs to be adjusted when
the width of the child is decreased so that the parent is decreased too.

<!--
Please provide as much information as possible about what your PR aims
to do.
PRs with no description will most likely be closed until more
information is provided.
If you're planing on changing fundamental behaviour or add big new
features, please open a GitHub Issue first before starting to work on
it.
If it's not something big and you still want to contact us about it,
feel free to do so !
-->

### Problem description
<!-- Describe the bug that you fixed/feature request that you
implemented, or link to an existing issue describing it -->

### Implementation description
<!-- Explain what you did to correct the problem -->

### Screenshots
<!-- If your change is visual, take a screenshot showing it. Ideally,
make before/after sceenshots -->

### Additional things
<!-- Anything else you would like to say -->
2024-09-15 15:27:39 +02:00
paxcut
414e7d36a0 fix: Double-clicking a string selects the closing double quotes (#1862)
This is a simple fix for a simple issue. Just check if the last char in
the selection is a double quote and if it is, make the selection one
char shorter.

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2024-09-15 15:27:24 +02:00
paxcut
e0b4931a54 fix: 3D visualizer running very slowly with energy saving enabled (#1866)
### Problem description
The bug described in #1663 was caused by an optimization of the display
rendering that uses drawlists to detect changes. The changes in the 3-d
visualizer don't contain drawlists when axes are turned off.

### Implementation description
The fix is to identify the 3d visualizer among the command lists of the
main window and, if found, avoid skipping frames regardless of the
result of the comparison of drawlists.

Closes #1663
2024-09-15 15:23:58 +02:00
paxcut
a587c5ff74 feat: Added a quarter precision (8 bits) button to IEEE 745 tool (#1868)
Per discussions on Discord.
2024-09-15 15:22:35 +02:00
paxcut
0b2eca3066 fix: LZMA decompressor memory errors (#1873)
<!--
Please provide as much information as possible about what your PR aims
to do.
PRs with no description will most likely be closed until more
information is provided.
If you're planing on changing fundamental behaviour or add big new
features, please open a GitHub Issue first before starting to work on
it.
If it's not something big and you still want to contact us about it,
feel free to do so !
-->

### Problem description
I was unable to use the LZMA de-compressor even though 7zip was able to
identify them as LZMA compressed and decompress them without a problem.
Under the debugger the `lzma_code()` call was returning
`LZMA_MEMLIMIT_ERROR`.
### Implementation description
I found online that the error can be fixed using `lzma_memlimit_set()`
using a value obtained with `lzma_memusage()`. I tried to avoid having
to call `lzma_code()` twice but if the functions are called before the
first `lzma_code()`the values of memory obtained fall short and error
occurs again.

I suspect that there are better ways to deal with this other than the
code proposed in this PR, but I haven't been able to find any.

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2024-09-15 15:20:17 +02:00
paxcut
fa28052958 fix: Avoid crashing ImHex when passing invalid data to the 3D visualizer (#1874)
### Problem description
There are some obvious constrains in the various array data sizes that
we can use to determine if their sizes and in some cases their values
are correct.

### Implementation description
To test their validity, the most important of the various arrays are the
indices, so their definition and use has been simplified a great deal.
In order to treat all variables in a similar manner the changes to the
uv variable posted in an earlier PR were also added here.

With this one, all the recently opened PR's combined should contain
exactly the same changes and fixes as the older 3-d visualizer PR #1850
which I will close shortly after this one is opened.

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2024-09-15 15:19:41 +02:00
paxcut
54f5bd1d80 feat: Added underwaved text functions (#1889)
### Problem description
Currently when errors are found the entire line where the error occurred
is highlighted and one has to look at the error message in order to find
where the error is located on the line. With this PR the line will no
longer be highlighted and the location of the error will be marked with
an red waved line under the error location. Hovering over the text where
the error occurred produces an error overlay so if several errors occur
on the same line they can all be seen separately.

### Implementation description
The definition of error marker was switched to include column and size
as well as line and message like before.
This change required changing the way view pattern editor draws the
error markers because the errors themselves don't have size information.
Also, a new errorHoverBoxes type was defined to help in the detection of
the floating error messages when error is hovered.

Note that the underwave code depends on having a monospaced. If font is
not monospaced the underwaved text can be short/long or displaced.


### Screenshots

![image](https://github.com/user-attachments/assets/f0b08e10-612c-404a-8863-d4f00054d198)


![image](https://github.com/user-attachments/assets/911fcacb-2a1e-431f-bbc8-8e05bcd61341)
2024-09-15 15:19:04 +02:00
paxcut
4b3bbb4a97 impr: Moved pattern editor shortcuts to the Shortcut manager (#1892)
### Problem description
There are some recent issues about Mac keys not configured properly for
the pattern editor. This PR moves all the shortcuts to the shortcut
manager, so they can be edited at will. Even if the key is not
identified correctly it should be possible to use preferred keys for any
action.

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2024-09-15 15:18:50 +02:00
xtex
187d90e8f2 lang: Update Chinese (Simplified) translations (#1894)
Co-authored-by: JustFor <35858818+zhongqingsong@users.noreply.github.com>
2024-09-15 15:17:25 +02:00
rockisch
2f60f61c15 impr: Add streaming decompression to zstd_decompress (#1898)
<!--
Please provide as much information as possible about what your PR aims
to do.
PRs with no description will most likely be closed until more
information is provided.
If you're planing on changing fundamental behaviour or add big new
features, please open a GitHub Issue first before starting to work on
it.
If it's not something big and you still want to contact us about it,
feel free to do so !
-->

### Problem description

https://github.com/WerWolv/ImHex/issues/1895

### Implementation description

Added code that handles streamed zstd data. It is based around the
[official
documentation](http://facebook.github.io/zstd/zstd_manual.html) and the
[example](https://github.com/facebook/zstd/blob/dev/examples/simple_decompression.c)
provided at the main zstd repo.

The loop around the non-streamed version was also removed because I
don't think it was doing anything (no `continue`s, `sourceSize` was
always being set to 0).

### Additional things

To test, I generated streamed zstd data with this python script:

```py
import io; import pyzstd;
with open("data.zstd", "wb") as f:
    pyzstd.compress_stream(io.BytesIO(b'ab' * 100), f)
```

And then I ran this pattern script:
```
import std.mem;
import hex.dec;

u8 data[while(!std::mem::eof())] @ 0x00;
std::mem::Section data_sec = std::mem::create_section("data_sec");
hex::dec::zstd_decompress(data, data_sec);
```

Inspecting the section shows the correct data:

![image](https://github.com/user-attachments/assets/83fc9d4c-e6fa-49ee-9923-29dc0c280739)

Co-authored-by: Nik <werwolv98@gmail.com>
2024-09-15 15:16:57 +02:00
paxcut
057543da15 feat: Extended bitmap visualizer to handle indexed colormaps (#1901)
### Problem description
Older image format use to store color values in a small lookup table so
that the image could simply store an index to the table. The pattern
language is not designed to handle this sort of operation which makes
this extension necessary to be able to visualize images of this type.

### Implementation description

The changes add an optional parameter to the bitmap visualizer which
holds the color lookup table. If the image contains values that are
outside the range of possible colors then the first color in the map is
chosen. The dimensions of the image can be equal to or smaller than
rows*columns depending on how the indices to the color map are stored.
For example, you can use 4 bit indices which would make the image half
the size (in bytes) but that limits the number of colors to 16. To store
colors in sizes larger than one byte use an array of the appropriate
sized integers.

### Screenshots


![image](https://github.com/user-attachments/assets/d068cb7e-3ff3-450d-8ac2-1bfc6e38043f)
2024-09-15 15:16:36 +02:00
paxcut
3c060cc57a fix: Finding utf-8 strings failed to select their location. (#1902)
other separate, but closely related fixes are:

- fix: The previous fix also solved the (unreported) bug of being unable
to select utf-8 works by double-clicking.
- fix: The move to next/previous word (Ctr-arrow) behaved differently
depending on the direction. I made both the move left/right functions
share a much simpler algorithm and rewrote the find start/end of word
functions share the same code structure.


### Problem description
The code was using the byte index of the match into the utf-8 string to
store the match locations, but the code that sets the selection uses the
char index into the utf-8 string instead. Another problem was that the
search uses the byte index to determine if it needs to find more
matches.

### Implementation description
Both problems were solved by introducing two functions to switch from
coordinates in units of bytes to coordinates in units of chars and vice
versa.

Co-authored-by: Nik <werwolv98@gmail.com>
2024-09-15 15:16:19 +02:00
paxcut
928b4c6c4c fix: Reset cursor blink when moving selection (#1903)
### Problem description
When this feature was implemented the text editor handled all the
keyboard input so the blink reset function could be called in one place
for all the key presses. Now that shortcuts are done in the shortcut
manager we need to reset the blink state inside all the functions that
can affect cursor movement.

### Implementation description
Every function that moves the cursor now calls the blink state reset
function at the very start. There may be more functions that need this
that haven't been merged but git should show merging conflicts so it
should be easy to deal with.
2024-09-15 15:15:14 +02:00
WerWolv
871a0d535c build: Fix building issues on macOS with clang 18 2024-09-08 10:45:38 +02:00
WerWolv
87db9def32 build: Updated libwolv 2024-09-03 11:09:01 +02:00
WerWolv
04763eaeea patterns: Updated pattern language 2024-08-23 21:37:46 +02:00
JustFor
b6c08a1a11 lang: Updated zh_CN language definition (#1827)
### Problem description
1. Old Chinese text json, the order is chaotic. It doesn't compare well
with English.
2. Missing a batch of new English strings.

### Implementation description
1. Synchronize the key sequence of English files.
2. Added a missing batch of text, and translate to CN.

### Screenshots
None

### Additional things
None
2024-08-20 20:31:33 +02:00
xtex
811c995047 build: Find boost with name "Boost" (#1840)
On many distributions like AOSC OS, Alpine Linux, Arch Linux, etc.,
boost should be searched with name "Boost".

This should fix the packaging issue on AOSC OS.

### Problem description
CMake fails to find system boost when `USE_SYSTEM_BOOST` is set to ON.

### Implementation description
Find Boost.

Signed-off-by: xtex <xtexchooser@duck.com>
2024-08-20 20:29:03 +02:00
WerWolv
7011df2ced fix: Reading entire file content of base64 file into memory not working 2024-08-20 20:27:08 +02:00
WerWolv
a24692b4be fix: Revert ndf-extended changes for now to fix file dialogs on Linux 2024-08-20 20:08:01 +02:00
WerWolv
0e7a32470b patterns: Updated pattern language 2024-08-20 20:04:52 +02:00
WerWolv
212d2f9db4 patterns: Updated pattern language 2024-08-10 09:17:41 +02:00
Colin Snover
0263d3538e fix: Don't supress stderr anymore (#1822)
### Problem description

Typing `--help` causes ImHex to exit without outputting anything.
Diagnostic messages from glib, ASan, other libraries that might have
something important to say, etc. are also suppressed.

### Implementation description

This effectively reverts 7c1e33dde6, which
was partially reverted only on Windows by code that was left commented
out in f114239f51.

Allowing other libraries to print to stderr may make the output ‘ugly’,
but lots of things print to stderr that are important for figuring out
why something is bugged, like ASan and glib.

### Additional things


![image](https://github.com/user-attachments/assets/fa6771e2-da2e-45ea-93cd-06c3f6bfd3bf)
2024-08-09 22:15:34 +02:00
WerWolv
63c6028522 build: Updated ImGui to v1.91.0 2024-08-03 23:49:47 +02:00
WerWolv
075ece2da7 impr: Clean up windows window code 2024-08-03 22:18:16 +02:00
WerWolv
e9fb02285e impr: Allow tasks to be created without getting the task handle as parameter 2024-08-03 22:01:18 +02:00
WerWolv
5dfd8c89a3 feat: Display pattern descriptions in file chooser and pattern popup 2024-08-03 22:00:47 +02:00
WerWolv
e9f7908afb git: Increase stale issue operations to 200 2024-08-03 20:10:09 +02:00
WerWolv
fafce72c01 fix: Errors causing #pragma magic to not work as expected 2024-08-03 20:09:10 +02:00
WerWolv
c3d15157ad git: Silence brew commands spewing errors into the CI log 2024-08-03 18:41:17 +02:00
WerWolv
e0712f73c2 git: Better build CI script formatting 2024-08-03 18:40:56 +02:00
WerWolv
3dd5b2365a git: Increased stale issue operations per run to 100 2024-08-03 18:39:26 +02:00
WerWolv
b523f55984 git: Kill XProtect on git runners to work around race condition 2024-08-03 18:32:45 +02:00
Nik
79b8b77b25 git: Allow inactive issues ci to be triggered manually 2024-08-03 18:24:31 +02:00
WerWolv
c6065808a7 git: Skip codecov CI step if token isn't set 2024-08-03 18:22:15 +02:00
Justus Garbe
d69ae39b6f git: Added stale issues action (#1836)
Added stale issues action:
- Runs on cron every 30 days
- Marks issues as stale after 11 months
- Closes issues marked as stale after 1 month
2024-08-03 18:22:11 +02:00
WerWolv
35739d6d0d feat: Display pattern description on the accept pattern popup 2024-08-03 18:15:30 +02:00
WerWolv
e726fce360 patterns: Updated pattern language
Fixes #1835
2024-08-03 17:56:13 +02:00
WerWolv
0a038fecff impr: Re-parse patterns only when the user stopped typing 2024-08-03 17:00:23 +02:00
WerWolv
0184bf9a7d impr: Only mark providers dirty when they're not dirty already 2024-08-03 17:00:09 +02:00
WerWolv
60663babc8 impr: Optimize hovering over patterns in the hex editor 2024-08-03 16:50:30 +02:00
WerWolv
a7115d4300 fix: Race condition during data processor execution 2024-08-03 15:17:35 +02:00
WerWolv
29558c9910 impr: Remove superfluous concatenation operators for Lang strings 2024-08-03 11:35:36 +02:00
WerWolv
7c1d643f97 patterns: Updated pattern language 2024-08-03 11:33:15 +02:00
WerWolv
b2fc80f970 impr: Fix various issues with runtime-generated language strings 2024-08-03 11:32:17 +02:00
WerWolv
efee128c1c patterns: Updated pattern language 2024-07-28 10:43:15 +02:00
WerWolv
c3ddd68866 fix: Correct more language strings 2024-07-27 16:54:05 +02:00
WerWolv
3cde4472c8 impr: Jump to selection in main hex editor as well when clicking on diff entries 2024-07-27 16:52:15 +02:00
WerWolv
4c38fe261d feat: Make diff table resizable 2024-07-27 16:51:43 +02:00
WerWolv
33f7191c0d fix: Copy paste error 2024-07-27 16:46:10 +02:00
WerWolv
cda9ad3b30 patterns: Updated pattern language 2024-07-27 16:33:37 +02:00
WerWolv
1a7bd49361 impr: Make all task names properly translatable 2024-07-27 16:29:06 +02:00
WerWolv
cf2e189049 fix: Building issues on Fedora 2024-07-27 15:55:59 +02:00
WerWolv
d5f5ba941a patterns: Updated pattern language 2024-07-27 14:16:01 +02:00
WerWolv
9a973be7ba fix: Background service thread names 2024-07-27 14:15:51 +02:00
WerWolv
d8e1284946 fix: Task names not displaying correctly anymore 2024-07-27 14:09:52 +02:00
WerWolv
ce26fe1db7 impr: Move language string interpretation to compile time 2024-07-27 11:23:21 +02:00
WerWolv
a8ad045248 fix: Parent offset calculation with non-zero base addresses 2024-07-26 19:43:15 +02:00
WerWolv
d097f6ada0 impr: Make pattern tooltips more appropriately sized 2024-07-26 19:38:21 +02:00
WerWolv
1b26db40f7 feat: Added parent offset to pattern hover tooltip 2024-07-26 19:38:01 +02:00
WerWolv
602b946fc9 patterns: Updated pattern language 2024-07-24 19:52:03 +02:00
WerWolv
48fc1a7a1e fix: Allow ImHex to build under wayland again 2024-07-24 19:41:34 +02:00
WerWolv
416889f49d impr: Optimize time it takes to find favorites in patterns 2024-07-24 19:41:12 +02:00
WerWolv
5ca3222e5b patterns: Updated pattern language
Fixes #1828
2024-07-24 19:40:27 +02:00
WerWolv
d49d82e982 fix: Building with latest pattern language changes 2024-07-23 20:32:16 +02:00
WerWolv
a4d5679219 fix: Crash when opening hex editor popups 2024-07-23 20:32:04 +02:00
WerWolv
bead103f3d patterns: Updated pattern language 2024-07-23 18:29:37 +02:00
Jean-François Nguyen
e50b6733c4 fix: Segfault when hashing regions spanning multiple MiBs (#1804)
### Problem description

Attempting to do an MD5 hash of a large region (e.g. 2 MiB, ``u8
data[0x200000]``) crashes with a segfault.

### Implementation description

In ``hex::plugin::hashes::hashProviderRegionWithHashLib()``,
``hashFunction->TransformBytes()`` is called with an offset of 0,
because it iterates over ``data`` and not the entire region.
2024-07-21 20:35:38 +02:00
xndcn
75e5dbaaa4 build: Fix incorrect name case in FindmbedTLS.cmake (#1817)
Corrected MBEDTLS_FIND_REQUIRED to mbedTLS_FIND_REQUIRED, since the
package name is "mbedTLS" for case sensitive environment
2024-07-21 20:34:23 +02:00
xndcn
965113c2b4 fix: Fix lzma stream end constant name (#1818)
Corrected BZ_STREAM_END to LZMA_STREAM_END.
Also removed redundant condition of LZMA_STREAM_END for error checking.
2024-07-21 20:33:46 +02:00
checkraisefold
3bddaf509d fix: Textures provided through the pattern language not rendering in the 3D visualizer (#1819)
<!--
Please provide as much information as possible about what your PR aims
to do.
PRs with no description will most likely be closed until more
information is provided.
If you're planing on changing fundamental behaviour or add big new
features, please open a GitHub Issue first before starting to work on
it.
If it's not something big and you still want to contact us about it,
feel free to do so !
-->

### Problem description
Because of `s_drawTexture` never being set to true, textures rarely or
never drew in the 3D visualizer.

### Implementation description
Set `s_drawTexture` to true when correct (valid texture file/object).
2024-07-21 20:33:05 +02:00
Colin Snover
c1c51e0baf feat: Enumerate fonts on Linux using Fontconfig when available (#1821)
### Problem description

The fonts list on Linux does not show all system fonts, and does not
show font names at all.

### Implementation description

Use Fontconfig to make the list less bad if Fontconfig headers are
available.

### Additional things

I like fonts.

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2024-07-21 20:28:37 +02:00
WerWolv
09b6c2ab5b fix: Error log spamming when viewing invalid regions in process memory provider on linux 2024-07-21 20:24:26 +02:00
Colin Snover
13fd956039 fix: Do not connect to api on startup when server contact setting is disabled (#1823)
### Problem description

ImHex asks users whether they wish to opt-in to network connections on
start (excellent!), then ignores that and tries to connect to the
network anyway when the welcome screen loads (less excellent!).

### Implementation description

Also don’t connect to the network on the welcome screen if it is
supposed to not do that.
2024-07-21 20:14:02 +02:00
WerWolv
b6f0ee90af fix: Sidebar panels not being resizable anymore properly 2024-07-16 18:15:28 +02:00
WerWolv
90e11e1c5d fix: Crash when parsing process memory provider regions 2024-07-16 18:11:06 +02:00
WerWolv
fc40e8ba70 fix: Process memory provider region parsing skipping unnamed regions 2024-07-16 17:58:49 +02:00
WerWolv
7652b4a5b8 fix: Compiling on Linux with older glfw versions 2024-07-16 17:58:19 +02:00
Colin Snover
fb249767f1 fix: Crash on exit when using custom font from file (#1815)
### Problem description
WerWolv/ImHex#1814

### Implementation description
1. Remove the flag that wrongly tells `ImFontAtlas` that it owns font
data, and remove that parameter from the function signature entirely
since now it is always `false`.
2. Rename `takeAtlas` to `getAtlas` since it no longer transfers
ownership as of b652565b57.
2024-07-15 22:22:02 +02:00
WerWolv
d7ed311bcf impr: Don't auto-scale the framebuffer on Linux 2024-07-12 17:34:20 +02:00
WerWolv
8422965d0b impr: Run data processor in a worker task 2024-07-11 23:30:54 +02:00
WerWolv
7975edade4 feat: Added loop data processor node 2024-07-11 20:38:33 +02:00
WerWolv
1e18935513 impr: Handle demangling of identifiers without leading underscore 2024-07-11 20:38:22 +02:00
WerWolv
c311b5315f patterns: Updated pattern language 2024-07-11 18:02:48 +02:00
WerWolv
26a73e0fba patterns: Updated pattern language 2024-07-11 17:40:18 +02:00
WerWolv
07c259c9c1 fix: Multiple issues causing visualizers to crash when used _slightly_ incorrectly 2024-07-10 20:50:58 +02:00
WerWolv
9e1c2d5a2c build: Fix copy-paste bug 2024-07-10 20:50:20 +02:00
WerWolv
d7fb1b737f fix: Occasional crash when closing providers 2024-07-09 19:01:49 +02:00
iTrooz
84c9c69fa3 fix: Remove DSA key from AUR deploy action (#1806) 2024-07-09 09:23:33 +00:00
WerWolv
12ca4e29cf fix: Multiple definitions errors with plugin features 2024-07-08 21:34:47 +02:00
WerWolv
27b1a5dc98 impr: Make highlight hovering more efficient 2024-07-08 21:34:27 +02:00
WerWolv
de36cc8445 impr: Disable pattern debug mode after evaluation has finished 2024-07-08 19:49:31 +02:00
WerWolv
03d344c0a2 build: Streamline definition on plugin features 2024-07-08 18:12:46 +02:00
WerWolv
39f01538c7 git: Update Mesa3D link for Windows NoGPU version 2024-07-07 16:17:03 +02:00
WerWolv
28c57cf666 patterns: Updated pattern language 2024-07-07 15:47:58 +02:00
WerWolv
59d120537d feat: Added non-frame lz4 compression support to the pattern language 2024-07-07 15:23:18 +02:00
WerWolv
66d18e9475 patterns: Updated pattern language 2024-07-07 13:59:56 +02:00
WerWolv
1f5e4ceb0c feat: Added basic support for lz4 decompression to the pattern language 2024-07-07 10:26:24 +02:00
Sébastien Szymanski
0cbc65a52f build: Fix Gentoo ebuild (#1787)
### Problem description
Ebuild is invalid, i.e:
```
# ebuild ImHex-9999.ebuild manifest
Error(s) in metadata for 'app-editors/ImHex-9999':
  RDEPEND: Invalid atom (dbus), token 5
```

### Implementation description
* mbedtls is in net-libs category
* RDEPEND must contain atoms (category/packagename)

Signed-off-by: Sébastien Szymanski <sebastien.szymanski@armadeus.com>
Co-authored-by: Nik <werwolv98@gmail.com>
2024-07-07 10:25:10 +02:00
WerWolv
2b0367cca6 impr: Better handling of the scaling warning when using custom fonts 2024-07-06 11:30:59 +02:00
WerWolv
1f01f480e0 impr: Enable native scaling by default again 2024-07-06 11:29:52 +02:00
WerWolv
7a167962d6 fix: Font scaling not always being applied consistently 2024-07-06 11:29:14 +02:00
WerWolv
dae028d25d fix: Build issue due to uncaptured this pointer 2024-07-05 21:03:24 +02:00
WerWolv
88e2fa04e7 fix: Crash on macOS when dirtying or undirtying a provider from a thread
Fixes #1799
2024-07-05 20:59:20 +02:00
WerWolv
bb0a8047ea fix: Hex editor popups getting transparent when hovering over combo box popup 2024-07-05 19:26:08 +02:00
WerWolv
b652565b57 feat: Added DPI awareness on Windows, added FiraCode as optional default font 2024-07-05 17:39:07 +02:00
WerWolv
9aaf6f3105 web: Trigger right click when long touching area 2024-07-04 23:15:33 +02:00
WerWolv
c26eccfe28 web: Fix canvas to the top left of the screen 2024-07-04 21:37:51 +02:00
WerWolv
9fd547112d impr: Only handle SIGINT on release builds so IDEs can fast-kill ImHex 2024-07-04 21:28:43 +02:00
WerWolv
14bfc8af72 fix: Remove unnecessary touch padding 2024-07-04 21:18:46 +02:00
WerWolv
20f3458e37 patterns: Updated pattern language 2024-07-04 21:18:34 +02:00
WerWolv
6326e2d141 web: Improve logo size on mobile 2024-07-03 22:35:47 +02:00
WerWolv
23ca3c1d2d patterns: Updated pattern language 2024-07-03 22:35:47 +02:00
WerWolv
0656ab4b88 fix: Make sure welcome screen always stays in the background 2024-07-03 22:35:47 +02:00
WerWolv
90bb5d187c web: Fix touch input 2024-07-03 22:35:47 +02:00
WerWolv
75a62e2bde fix: Wrong start/end offset and size for static array entries in pattern data view 2024-07-03 16:58:56 +02:00
WerWolv
7cd36b80eb impr: Added tooltips to toolbar buttons 2024-07-03 16:58:25 +02:00
Bernard Teo
dd607621d7 build: Update nativefiledialog and keep dialogs on top (#1771)
This PR updates the nativefiledialog submodule and uses its new feature
to set the ImHex main window as the parent of the dialog window. This
ensures that the dialog stays on top of the main window. This is
currently supported by NFDe on Windows, macOS, and Linux/X11.
Linux/Wayland behaves as it did previously due to limitations in NFDe.

Note that macOS file dialogs have already been parented properly as NFDe
previously used the key window (the window currently receiving keyboard
events) on macOS. However, it's probably better to do the correct thing
and pass the main window to NFDe even on macOS.

### Problem description
The file dialog go behind the main window if the main window is clicked
while the file dialog is open.

### Implementation description
Update nativefiledialog and pass the `GLFWwindow*` of the main window to
the library function.

### Screenshots
Before:


https://github.com/WerWolv/ImHex/assets/6948096/589c3401-702a-4b0a-99ed-02d3e4d9080e

After:


https://github.com/WerWolv/ImHex/assets/6948096/8fef4900-eedc-48d5-8a4e-7bd81e37e3c0

### Additional things
I have tested this on Windows and Linux/X11, but did not test this on
macOS. It would be ideal if someone can help with this. (But as far as
NFDe is concerned, macOS `NSWindow*` handles have been tested (with
SDL2) and works.)

Co-authored-by: Nik <werwolv98@gmail.com>
2024-07-03 05:53:55 +00:00
WerWolv
2595febf14 patterns: Updated pattern language 2024-07-02 23:46:06 +02:00
WerWolv
dc058c4cf3 fix: Remove interactive help debug code 2024-07-02 23:17:12 +02:00
WerWolv
25824e1821 patterns: Updated pattern language 2024-07-02 23:16:32 +02:00
WerWolv
381c2d52ee web: Improved canvas webgl creation logic 2024-07-02 23:16:19 +02:00
WerWolv
4020ac9843 impr: Added nicer console warning when .NET runtime isn't installed 2024-07-02 23:15:54 +02:00
WerWolv
b3b7a19df4 fix: Wrong end address for bitfield fields in pattern data view 2024-07-02 17:38:53 +02:00
WerWolv
313e3e748f impr: Improved size display in pattern data view 2024-07-02 17:38:39 +02:00
WerWolv
09b9f26e6f patterns: Updated pattern language 2024-07-02 17:37:47 +02:00
WerWolv
01b9cc64d6 impr: Disable tab overlines 2024-07-01 23:53:14 +02:00
WerWolv
97bf1dc850 fix: Potential race condition with sorting in the pattern drawer 2024-07-01 23:36:17 +02:00
WerWolv
f94794fe3e patterns: Updated pattern language 2024-07-01 22:14:51 +02:00
WerWolv
68e528dd3a impr: Added Boost.Regex to about page 2024-07-01 22:01:28 +02:00
WerWolv
06ab1d34aa build: Updated ImGui, libfmt and libyara 2024-07-01 22:00:08 +02:00
WerWolv
2f2717e9aa impr: Completely eradicate Window resize flickering on Windows 2024-07-01 20:50:10 +02:00
WerWolv
88d24c2a03 web: Fix ImHex logo and progress bar default fill 2024-07-01 20:36:55 +02:00
WerWolv
ec2a2a6fbb git: Improve GPU information in the readme 2024-07-01 20:09:30 +02:00
WerWolv
60b81e714b impr: Prevent canvas flickering in web build 2024-07-01 20:09:16 +02:00
WerWolv
2cd8b13c1d build: Use ninja to build web version 2024-07-01 20:07:21 +02:00
Ikko Eltociear Ashimine
4afedb5131 chore: Fixed typo in cmake script (#1783)
<!--
Please provide as much information as possible about what your PR aims
to do.
PRs with no description will most likely be closed until more
information is provided.
If you're planing on changing fundamental behaviour or add big new
features, please open a GitHub Issue first before starting to work on
it.
If it's not something big and you still want to contact us about it,
feel free to do so !
-->

### Problem description
<!-- Describe the bug that you fixed/feature request that you
implemented, or link to an existing issue describing it -->
Accomodate -> Accommodate
### Implementation description
<!-- Explain what you did to correct the problem -->

### Screenshots
<!-- If your change is visual, take a screenshot showing it. Ideally,
make before/after sceenshots -->

### Additional things
<!-- Anything else you would like to say -->
2024-07-01 08:24:59 +02:00
WerWolv
71880ad2ad git: Checkout correct repositories in plugin test CI 2024-06-30 22:35:15 +02:00
WerWolv
a30cce4cbc git: Checkout ImHex main repo in plugin template test runner 2024-06-30 22:25:09 +02:00
WerWolv
08b4f60ead git: Added CI runner to test plugin template building 2024-06-30 22:15:04 +02:00
WerWolv
11498bd09b build: Properly look for boost and libimhex library in sdk again 2024-06-30 21:55:29 +02:00
Nik
7384c88ad6 git: Update resource requirement in readme 2024-06-30 10:46:00 +02:00
WerWolv
6f22d70d59 fix: Updater executable not being launched correctly when path had spaces in it
Fixes #1780
2024-06-30 07:59:25 +02:00
WerWolv
adc279d681 impr: Further try to improve window resize flickering on Windows 2024-06-29 23:32:44 +02:00
WerWolv
f90dc5d619 fix: ImHex hanging at startup in certain cases 2024-06-29 21:13:04 +02:00
WerWolv
6fd594c1f4 fix: Don't delete font atlas after passing it to ImGui 2024-06-29 20:26:46 +02:00
WerWolv
b94a4288bf fix: Standard magic file not getting bundled into executable correctly 2024-06-29 19:43:24 +02:00
WerWolv
cbf415256b fix: Default folders still not being created correctly on Linux 2024-06-29 19:15:09 +02:00
WerWolv
4b1884944d fix: Exception when opening a null provider 2024-06-29 18:49:23 +02:00
WerWolv
5ff752c9af build: Bumped version to 1.36.0.WIP 2024-06-29 18:48:36 +02:00
WerWolv
0e331a7cd1 build: Bumped version to 1.35.1 2024-06-29 13:01:53 +02:00
WerWolv
10970d170c fix: Default folders not being created correctly anymore 2024-06-29 13:01:25 +02:00
424 changed files with 33065 additions and 9691 deletions

View File

@@ -8,7 +8,7 @@ on:
jobs:
codeql:
name: 🐛 CodeQL
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
permissions:
actions: read
contents: read
@@ -49,7 +49,7 @@ jobs:
set -x
mkdir -p build
cd build
CC=gcc-12 CXX=g++-12 cmake \
CC=gcc-14 CXX=g++-14 cmake \
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
-DCMAKE_INSTALL_PREFIX="$PWD/install" \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
@@ -57,8 +57,9 @@ jobs:
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
-DIMHEX_PATTERNS_PULL_MASTER=ON \
-G Ninja \
..
make -j 4 install
ninja install
- name: 🗯️ Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2

View File

@@ -6,6 +6,7 @@ on:
- 'master'
- 'releases/**'
- 'tests/**'
- 'feature/**'
pull_request:
workflow_dispatch:
@@ -18,11 +19,18 @@ jobs:
win:
runs-on: windows-2022
name: 🪟 Windows MINGW64
defaults:
run:
shell: msys2 {0}
env:
CCACHE_DIR: "${{ github.workspace }}/.ccache"
permissions:
id-token: write
attestations: write
steps:
- name: 🧰 Checkout
uses: actions/checkout@v4
@@ -64,7 +72,7 @@ jobs:
cd build
cmake -G "Ninja" \
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
-DCMAKE_INSTALL_PREFIX="$PWD/install" \
-DIMHEX_GENERATE_PACKAGE=ON \
-DIMHEX_USE_DEFAULT_BUILD_SETTINGS=ON \
@@ -81,11 +89,64 @@ jobs:
run: |
cd build
ninja install
- name: 🪲 Create PDBs for MSI
run: |
cd build
mkdir cv2pdb
cd cv2pdb
wget https://github.com/rainers/cv2pdb/releases/download/v0.52/cv2pdb-0.52.zip
unzip cv2pdb-0.52.zip
cd ..
cv2pdb/cv2pdb.exe imhex.exe
cv2pdb/cv2pdb.exe imhex-gui.exe
cv2pdb/cv2pdb.exe libimhex.dll
cv2pdb/cv2pdb.exe libpl.dll
for plugin in plugins/*.hexplug; do
cv2pdb/cv2pdb.exe $plugin
done
rm -rf cv2pdb
- name: 📦 Bundle MSI
run: |
cd build
cpack
mv ImHex-*.msi ../imhex-${{env.IMHEX_VERSION}}-Windows-x86_64.msi
mv ImHex-*.msi ../imhex-${{ env.IMHEX_VERSION }}-Windows-x86_64.msi
echo "ImHex checks for the existence of this file to determine if it is running in portable mode. You should not delete this file" > $PWD/install/PORTABLE
- name: 🪲 Create PDBs for ZIP
run: |
cd build/install
mkdir cv2pdb
cd cv2pdb
wget https://github.com/rainers/cv2pdb/releases/download/v0.52/cv2pdb-0.52.zip
unzip cv2pdb-0.52.zip
cd ..
cv2pdb/cv2pdb.exe imhex.exe
cv2pdb/cv2pdb.exe imhex-gui.exe
cv2pdb/cv2pdb.exe libimhex.dll
cv2pdb/cv2pdb.exe libpl.dll
for plugin in plugins/*.hexplug; do
cv2pdb/cv2pdb.exe $plugin
done
rm -rf cv2pdb
- name: 🗝️ Generate build provenance attestations
uses: actions/attest-build-provenance@v2
if: github.event.pull_request.head.repo.full_name == github.repository
with:
subject-path: |
imhex-*.msi
- name: ⬆️ Upload Windows Installer
uses: actions/upload-artifact@v4
with:
@@ -119,9 +180,70 @@ jobs:
path: |
build/install/*
win-plugin-template-test:
runs-on: windows-2022
name: 🧪 Plugin Template Test
defaults:
run:
shell: msys2 {0}
needs: win
env:
IMHEX_SDK_PATH: "${{ github.workspace }}/out/sdk"
steps:
- name: 🧰 Checkout ImHex
uses: actions/checkout@v4
with:
path: imhex
- name: 🟦 Install msys2
uses: msys2/setup-msys2@v2
with:
msystem: mingw64
- name: ⬇️ Install dependencies
run: |
set -x
imhex/dist/get_deps_msys2.sh
- name: 🧰 Checkout ImHex-Plugin-Template
uses: actions/checkout@v4
with:
repository: WerWolv/ImHex-Plugin-Template
submodules: recursive
path: template
- name: ⬇️ Download artifact
uses: actions/download-artifact@v4
with:
name: Windows Portable x86_64
path: out
- name: 🛠️ Build
run: |
set -x
cd template
mkdir -p build
cd build
cmake -G "Ninja" \
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
-DIMHEX_USE_DEFAULT_BUILD_SETTINGS=ON \
-DUSE_SYSTEM_CAPSTONE=ON \
..
ninja
# MacOS build
macos:
runs-on: macos-12
macos-x86:
runs-on: macos-13
permissions:
id-token: write
attestations: write
strategy:
fail-fast: false
@@ -132,7 +254,7 @@ jobs:
- suffix: ""
custom_glfw: false
name: 🍎 macOS 12.0${{matrix.suffix}}
name: 🍎 macOS 13${{ matrix.suffix }}
steps:
- name: 🧰 Checkout
@@ -152,15 +274,19 @@ jobs:
max-size: 1G
- name: ⬇️ Install dependencies
env:
# Make brew not display useless errors
HOMEBREW_TESTS: 1
run: |
brew reinstall python || brew link --overwrite python || true
brew bundle --no-lock --file dist/Brewfile
brew reinstall python --quiet || true
brew link --overwrite --quiet python 2>/dev/null || true
brew bundle --no-lock --quiet --file dist/macOS/Brewfile || true
rm -rf /usr/local/Cellar/capstone
- name: ⬇️ Install classic glfw
if: ${{! matrix.custom_glfw}}
if: ${{! matrix.custom_glfw }}
run: |
brew install glfw || true
brew install --quiet glfw || true
- name: ⬇️ Install .NET
uses: actions/setup-dotnet@v4
@@ -168,7 +294,7 @@ jobs:
dotnet-version: '8.0.100'
- name: 🧰 Checkout glfw
if: ${{matrix.custom_glfw}}
if: ${{ matrix.custom_glfw }}
uses: actions/checkout@v4
with:
repository: glfw/glfw
@@ -176,7 +302,7 @@ jobs:
# GLFW custom build (to allow software rendering)
- name: ⬇️ Patch and install custom glfw
if: ${{matrix.custom_glfw}}
if: ${{ matrix.custom_glfw }}
run: |
set -x
cd glfw
@@ -186,7 +312,7 @@ jobs:
cd build
cmake -G "Ninja" \
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
-DBUILD_SHARED_LIBS=ON \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
@@ -201,14 +327,15 @@ jobs:
set -x
mkdir -p build
cd build
CC=$(brew --prefix gcc@12)/bin/gcc-12 \
CXX=$(brew --prefix gcc@12)/bin/g++-12 \
CC=$(brew --prefix llvm)/bin/clang \
CXX=$(brew --prefix llvm)/bin/clang++ \
OBJC=$(brew --prefix llvm)/bin/clang \
OBJCXX=$(brew --prefix llvm)/bin/clang++ \
PKG_CONFIG_PATH="$(brew --prefix openssl)/lib/pkgconfig":"$(brew --prefix)/lib/pkgconfig" \
cmake -G "Ninja" \
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
-DIMHEX_GENERATE_PACKAGE=ON \
-DIMHEX_SYSTEM_LIBRARY_PATH="$(brew --prefix llvm)/lib;$(brew --prefix llvm)/lib/unwind;$(brew --prefix llvm)/lib/c++;$(brew --prefix)/lib" \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
@@ -236,28 +363,43 @@ jobs:
cd build/install
chmod -R 755 ImHex.app/
- name: 🔫 Kill XProtect
run: |
# See https://github.com/actions/runner-images/issues/7522
echo Killing XProtect...; sudo pkill -9 XProtect >/dev/null || true;
echo Waiting for XProtect process...; while pgrep XProtect; do sleep 3; done;
- name: 📦 Create DMG
run: |
set -x
mkdir bundle
mv build/install/ImHex.app bundle
cd bundle
ln -s /Applications Applications
cd ..
hdiutil create -volname "ImHex" -srcfolder bundle -ov -format UDZO imhex-${{env.IMHEX_VERSION}}-macOS${{matrix.suffix}}-x86_64.dmg
brew install imagemagick
git clone https://github.com/sindresorhus/create-dmg
cd create-dmg
npm i && npm -g i
cd ../build/install
create-dmg ImHex.app || true
mv *.dmg ../../imhex-${{ env.IMHEX_VERSION }}-macOS${{ matrix.suffix }}-x86_64.dmg
- name: 🗝️ Generate build provenance attestations
uses: actions/attest-build-provenance@v2
if: github.event.pull_request.head.repo.full_name == github.repository
with:
subject-path: |
./*.dmg
- name: ⬆️ Upload DMG
uses: actions/upload-artifact@v4
with:
if-no-files-found: error
name: macOS DMG${{matrix.suffix}} x86_64
name: macOS DMG${{ matrix.suffix }} x86_64
path: ./*.dmg
macos-arm64-build:
runs-on: ubuntu-22.04
name: 🍎 macOS 12.1 arm64
macos-arm64:
runs-on: ubuntu-24.04
name: 🍎 macOS 13 arm64
outputs:
IMHEX_VERSION: ${{ steps.build.outputs.IMHEX_VERSION }}
steps:
- name: 🧰 Checkout
uses: actions/checkout@v4
@@ -298,11 +440,17 @@ jobs:
gh actions-cache delete "build-macos-arm64-cache" --confirm || true
macos-arm64-package:
runs-on: macos-12
name: 🍎 macOS 12.1 arm64 Packaging
needs: macos-arm64-build
runs-on: macos-13
name: 🍎 macOS 13 arm64 Packaging
needs: macos-arm64
env:
IMHEX_VERSION: ${{ needs.macos-arm64-build.outputs.IMHEX_VERSION }}
permissions:
id-token: write
attestations: write
steps:
- name: ⬇️ Download artifact
uses: actions/download-artifact@v4
@@ -329,15 +477,28 @@ jobs:
cd out
chmod -R 755 ImHex.app/
- name: 🔫 Kill XProtect
run: |
# See https://github.com/actions/runner-images/issues/7522
echo Killing XProtect...; sudo pkill -9 XProtect >/dev/null || true;
echo Waiting for XProtect process...; while pgrep XProtect; do sleep 3; done;
- name: 📦 Create DMG
run: |
set -x
mkdir bundle
mv out/ImHex.app bundle
cd bundle
ln -s /Applications Applications
cd ..
hdiutil create -volname "ImHex" -srcfolder bundle -ov -format UDZO imhex-${{env.IMHEX_VERSION}}-macOS-arm64.dmg
brew install imagemagick
git clone https://github.com/sindresorhus/create-dmg
cd create-dmg
npm i && npm -g i
cd ../out
create-dmg ImHex.app || true
mv *.dmg ../imhex-${{ env.IMHEX_VERSION }}-macOS${{ matrix.suffix }}-arm64.dmg
- name: 🗝️ Generate build provenance attestations
uses: actions/attest-build-provenance@v2
if: github.event.pull_request.head.repo.full_name == github.repository
with:
subject-path: |
./*.dmg
- name: ⬆️ Upload DMG
uses: actions/upload-artifact@v4
@@ -352,16 +513,20 @@ jobs:
fail-fast: false
matrix:
include:
- release_num: 22.04
- release_num: 24.04
- release_num: "24.04"
- release_num: "24.10"
name: 🐧 Ubuntu ${{ matrix.release_num }}
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
container:
image: "ubuntu:${{ matrix.release_num }}"
options: --privileged
permissions:
id-token: write
attestations: write
steps:
- name: ⬇️ Install setup dependencies
run: apt update && apt install -y git curl
@@ -374,8 +539,8 @@ jobs:
- name: 📜 Setup ccache
uses: hendrikmuhs/ccache-action@v1
with:
key: Ubuntu-${{matrix.release_num}}-ccache-${{ github.run_id }}
restore-keys: Ubuntu-${{matrix.release_num}}-ccache
key: Ubuntu-${{ matrix.release_num }}-ccache-${{ github.run_id }}
restore-keys: Ubuntu-${{ matrix.release_num }}-ccache
max-size: 1G
- name: ⬇️ Install dependencies
@@ -396,8 +561,8 @@ jobs:
git config --global --add safe.directory '*'
mkdir -p build
cd build
CC=gcc-12 CXX=g++-12 cmake -G "Ninja" \
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
CC=gcc-14 CXX=g++-14 cmake -G "Ninja" \
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
-DCMAKE_INSTALL_PREFIX="/usr" \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
@@ -419,8 +584,15 @@ jobs:
- name: 📦 Bundle DEB
run: |
cp -r build/DEBIAN build/DebDir
dpkg-deb -Zgzip --build build/DebDir
mv build/DebDir.deb imhex-${{env.IMHEX_VERSION}}-Ubuntu-${{ matrix.release_num }}-x86_64.deb
dpkg-deb -Zzstd --build build/DebDir
mv build/DebDir.deb imhex-${{ env.IMHEX_VERSION }}-Ubuntu-${{ matrix.release_num }}-x86_64.deb
- name: 🗝️ Generate build provenance attestations
uses: actions/attest-build-provenance@v2
if: github.event.pull_request.head.repo.full_name == github.repository
with:
subject-path: |
./*.deb
- name: ⬆️ Upload DEB
uses: actions/upload-artifact@v4
@@ -431,8 +603,26 @@ jobs:
# AppImage build
appimage:
runs-on: ubuntu-22.04
name: ⬇️ AppImage
strategy:
fail-fast: false
matrix:
include:
- architecture: "x86_64"
architecture_package: "amd64"
architecture_appimage_builder: "x86_64"
image: ubuntu-24.04
- architecture: "arm64"
architecture_package: "arm64"
architecture_appimage_builder: "aarch64"
image: ubuntu-24.04-arm
runs-on: ${{ matrix.image }}
name: ⬇️ AppImage ${{ matrix.architecture }}
permissions:
id-token: write
attestations: write
steps:
- name: 🧰 Checkout
uses: actions/checkout@v4
@@ -454,32 +644,45 @@ jobs:
- name: 🛠️ Build using docker
run: |
docker buildx build . -f dist/appimage/Dockerfile --progress=plain --build-arg "BUILD_TYPE=$BUILD_TYPE" \
--build-arg "GIT_COMMIT_HASH=$GITHUB_SHA" --build-arg "GIT_BRANCH=${GITHUB_REF##*/}" --output out
docker buildx build . -f dist/AppImage/Dockerfile --progress=plain --build-arg "BUILD_TYPE=$BUILD_TYPE" \
--build-arg "GIT_COMMIT_HASH=$GITHUB_SHA" --build-arg "GIT_BRANCH=${GITHUB_REF##*/}" \
--build-arg "ARCHITECTURE_PACKAGE=${{ matrix.architecture_package }}" --build-arg "ARCHITECTURE_FILE_NAME=${{ matrix.architecture }}" --build-arg "ARCHITECTURE_APPIMAGE_BUILDER=${{ matrix.architecture_appimage_builder }}" \
--output out
- name: 🗝️ Generate build provenance attestations
uses: actions/attest-build-provenance@v2
if: github.event.pull_request.head.repo.full_name == github.repository
with:
subject-path: |
out/*.AppImage
out/*.AppImage.zsync
- name: ⬆️ Upload AppImage
uses: actions/upload-artifact@v4
with:
if-no-files-found: error
name: Linux AppImage x86_64
name: Linux AppImage ${{ matrix.architecture }}
path: 'out/*.AppImage'
- name: ⬆️ Upload AppImage zsync
uses: actions/upload-artifact@v4
with:
if-no-files-found: error
name: Linux AppImage zsync x86_64
name: Linux AppImage zsync ${{ matrix.architecture }}
path: 'out/*.AppImage.zsync'
# ArchLinux build
archlinux-build:
name: 🐧 ArchLinux
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
container:
image: archlinux:base-devel
permissions:
id-token: write
attestations: write
steps:
- name: ⬇️ Update all packages
run: |
@@ -517,7 +720,7 @@ jobs:
mkdir -p build
cd build
CC=gcc CXX=g++ cmake -G "Ninja" \
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
-DCMAKE_INSTALL_PREFIX="/usr" \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
@@ -542,7 +745,7 @@ jobs:
- name: ✒️ Prepare PKGBUILD
run: |
cp dist/Arch/PKGBUILD build
sed -i 's/%version%/${{env.IMHEX_VERSION}}/g' build/PKGBUILD
sed -i 's/%version%/${{ env.IMHEX_VERSION }}/g' build/PKGBUILD
# makepkg doesn't want to run as root, so I had to chmod 777 all over
- name: 📦 Package ArchLinux .pkg.tar.zst
@@ -552,16 +755,23 @@ jobs:
# the name is a small trick to make makepkg recognize it as the source
# else, it would try to download the file from the release
tar -cvf imhex-${{env.IMHEX_VERSION}}-ArchLinux-x86_64.pkg.tar.zst -C installDir .
tar -cvf imhex-${{ env.IMHEX_VERSION }}-ArchLinux-x86_64.pkg.tar.zst -C installDir .
chmod -R 777 .
sudo -u nobody makepkg
# Replace the old file
rm imhex-${{env.IMHEX_VERSION}}-ArchLinux-x86_64.pkg.tar.zst
rm imhex-${{ env.IMHEX_VERSION }}-ArchLinux-x86_64.pkg.tar.zst
rm *imhex-bin-debug* # rm debug package which is created for some reason
mv *.pkg.tar.zst imhex-${{env.IMHEX_VERSION}}-ArchLinux-x86_64.pkg.tar.zst
mv *.pkg.tar.zst imhex-${{ env.IMHEX_VERSION }}-ArchLinux-x86_64.pkg.tar.zst
- name: 🗝️ Generate build provenance attestations
uses: actions/attest-build-provenance@v2
if: github.event.pull_request.head.repo.full_name == github.repository
with:
subject-path: |
build/imhex-${{ env.IMHEX_VERSION }}-ArchLinux-x86_64.pkg.tar.zst
- name: ⬆️ Upload imhex-archlinux.pkg.tar.zst
uses: actions/upload-artifact@v4
@@ -569,7 +779,7 @@ jobs:
if-no-files-found: error
name: ArchLinux .pkg.tar.zst x86_64
path: |
build/imhex-${{env.IMHEX_VERSION}}-ArchLinux-x86_64.pkg.tar.zst
build/imhex-${{ env.IMHEX_VERSION }}-ArchLinux-x86_64.pkg.tar.zst
# RPM distro builds
rpm-build:
@@ -581,29 +791,46 @@ jobs:
mock_release: rawhide
release_num: rawhide
mock_config: fedora-rawhide
- name: Fedora
mock_release: f41
release_num: 41
mock_config: fedora-41
- name: Fedora
mock_release: f40
release_num: 40
mock_config: fedora-40
- name: Fedora
mock_release: f39
release_num: 39
mock_config: fedora-39
- name: RHEL-AlmaLinux
mock_release: epel9
release_num: 9
mock_config: "alma+epel-9"
name: 🐧 ${{ matrix.name }} ${{ matrix.release_num }}
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
container:
image: "fedora:latest"
options: --privileged
image: "almalinux:9"
options: --privileged --pid=host --security-opt apparmor=unconfined
permissions:
id-token: write
attestations: write
steps:
- name: ⬇️ Install git-core
run: dnf install --disablerepo="*" --enablerepo="fedora" git-core -y
# This, together with the `--pid=host --security-opt apparmor=unconfined` docker options is required to allow
# fedpkg to work inside a Docker container running on Ubuntu again.
# GitHub seems to have enabled AppArmor on their Ubuntu CI runners which limits Docker in ways that cause
# programs inside it to fail.
# Without this, fedpkg will throw the unhelpful error message 'Insufficient Rights'
# This step uses nsenter to execute commands on the host that disable AppArmor entirely.
- name: 🛡️ Disable AppArmor on Host
run: |
nsenter -t 1 -m -u -n -i sudo systemctl disable --now apparmor.service
nsenter -t 1 -m -u -n -i sudo aa-teardown || true
nsenter -t 1 -m -u -n -i sudo sysctl --write kernel.apparmor_restrict_unprivileged_unconfined=0
nsenter -t 1 -m -u -n -i sudo sysctl --write kernel.apparmor_restrict_unprivileged_userns=0
- name: ⬇️ Install git-core and EPEL repo
run: dnf install git-core epel-release -y
- name: 🧰 Checkout
uses: actions/checkout@v4
@@ -622,8 +849,8 @@ jobs:
- name: ⬇️ Update all packages and install dependencies
run: |
set -x
dnf upgrade --disablerepo="*" --enablerepo="fedora,updates" -y
dnf install --disablerepo="*" --enablerepo="fedora,updates" -y \
dnf upgrade -y
dnf install -y \
fedpkg \
ccache
@@ -649,16 +876,16 @@ jobs:
- name: ✒️ Modify spec file
run: |
sed -i \
-e 's/Version: VERSION$/Version: ${{env.IMHEX_VERSION}}/g' \
-e 's/IMHEX_OFFLINE_BUILD=ON/IMHEX_OFFLINE_BUILD=OFF/g' \
-e '/IMHEX_OFFLINE_BUILD=OFF/a -D IMHEX_PATTERNS_PULL_MASTER=ON \\' \
-e '/BuildRequires: cmake/a BuildRequires: git-core' \
-e '/%files/a %{_datadir}/%{name}/' \
-e 's/Version: VERSION$/Version: ${{ env.IMHEX_VERSION }}/g' \
-e 's/IMHEX_OFFLINE_BUILD=ON/IMHEX_OFFLINE_BUILD=OFF/g' \
-e '/IMHEX_OFFLINE_BUILD=OFF/a -D IMHEX_PATTERNS_PULL_MASTER=ON \\' \
-e '/BuildRequires: cmake/a BuildRequires: git-core' \
-e '/%files/a %{_datadir}/%{name}/' \
$GITHUB_WORKSPACE/ImHex/dist/rpm/imhex.spec
- name: 📜 Fix ccache on EL9
if: matrix.mock_release == 'epel9'
run: sed -i '/\. \/opt\/rh\/gcc-toolset-12\/enable/a PATH=/usr/lib64/ccache:$PATH' $GITHUB_WORKSPACE/ImHex/dist/rpm/imhex.spec
run: sed -i '/\. \/opt\/rh\/gcc-toolset-14\/enable/a PATH=/usr/lib64/ccache:$PATH' $GITHUB_WORKSPACE/ImHex/dist/rpm/imhex.spec
- name: 🟩 Copy spec file to build root
run: mv $GITHUB_WORKSPACE/ImHex/dist/rpm/imhex.spec $GITHUB_WORKSPACE/imhex.spec
@@ -680,8 +907,15 @@ jobs:
- name: 🟩 Move and rename finished RPM
run: |
mv $GITHUB_WORKSPACE/results_imhex/${{env.IMHEX_VERSION}}/*/imhex-${{env.IMHEX_VERSION}}-0.*.x86_64.rpm \
$GITHUB_WORKSPACE/imhex-${{env.IMHEX_VERSION}}-${{matrix.name}}-${{matrix.release_num}}-x86_64.rpm
mv $GITHUB_WORKSPACE/results_imhex/${{ env.IMHEX_VERSION }}/*/imhex-${{ env.IMHEX_VERSION }}-0.*.x86_64.rpm \
$GITHUB_WORKSPACE/imhex-${{ env.IMHEX_VERSION }}-${{ matrix.name }}-${{ matrix.release_num }}-x86_64.rpm
- name: 🗝️ Generate build provenance attestations
uses: actions/attest-build-provenance@v2
if: github.event.pull_request.head.repo.full_name == github.repository
with:
subject-path: |
imhex-${{ env.IMHEX_VERSION }}-${{ matrix.name }}-${{ matrix.release_num }}-x86_64.rpm
- name: ⬆️ Upload RPM
uses: actions/upload-artifact@v4
@@ -689,4 +923,86 @@ jobs:
if-no-files-found: error
name: ${{ matrix.name }} ${{ matrix.release_num }} RPM x86_64
path: |
imhex-${{env.IMHEX_VERSION}}-${{matrix.name}}-${{matrix.release_num}}-x86_64.rpm
imhex-${{ env.IMHEX_VERSION }}-${{ matrix.name }}-${{ matrix.release_num }}-x86_64.rpm
webassembly-build:
runs-on: ubuntu-24.04
name: 🌍 Web
permissions:
pages: write
id-token: write
actions: write
steps:
- name: 🧰 Checkout
uses: actions/checkout@v4
with:
submodules: recursive
- name: 📁 Restore docker /cache
uses: actions/cache@v4
with:
path: cache
key: web-cache-${{ hashFiles('**/CMakeLists.txt') }}
- name: 🐳 Inject /cache into docker
uses: reproducible-containers/buildkit-cache-dance@v2
with:
cache-source: cache
cache-target: /cache
- name: 🛠️ Build using docker
run: |
docker buildx build . -f dist/web/Dockerfile --progress=plain --build-arg 'JOBS=4' --output out --target raw
- name: 🔨 Fix permissions
run: |
chmod -c -R +rX "out/"
- name: ⬆️ Upload artifacts
uses: actions/upload-pages-artifact@v3
with:
path: out/
- name: 🔨 Copy necessary files
run: |
cp dist/web/serve.py out/start_imhex_web.py
- name: ⬆️ Upload package
uses: actions/upload-artifact@v4
with:
if-no-files-found: error
name: ImHex Web
path: out/*
# See https://github.com/actions/cache/issues/342#issuecomment-1711054115
- name: 🗑️ Delete old cache
continue-on-error: true
env:
GH_TOKEN: ${{ github.token }}
run: |
gh extension install actions/gh-actions-cache || true
gh actions-cache delete "build-web-cache" --confirm || true
webassembly-deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
permissions:
pages: write
id-token: write
actions: write
name: 📃 Deploy to GitHub Pages
runs-on: ubuntu-24.04
if: ${{ github.ref == 'refs/heads/master' && github.event.repository.fork == false }}
needs: webassembly-build
steps:
- name: 🌍 Deploy WebAssembly Build to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
- name: 🗑️ Delete artifact
uses: geekyeggo/delete-artifact@v5
with:
name: github-pages

View File

@@ -1,80 +0,0 @@
name: Build for the web
on:
push:
branches:
- 'master'
- 'releases/**'
- 'tests/**'
pull_request:
workflow_dispatch:
env:
BUILD_TYPE: Release
permissions:
pages: write
id-token: write
actions: write
jobs:
build:
runs-on: ubuntu-22.04
name: 🌍 WebAssembly
steps:
- name: 🧰 Checkout
uses: actions/checkout@v4
with:
submodules: recursive
- name: 📁 Restore docker /cache
uses: actions/cache@v4
with:
path: cache
key: web-cache-${{ hashFiles('**/CMakeLists.txt') }}
- name: 🐳 Inject /cache into docker
uses: reproducible-containers/buildkit-cache-dance@v2
with:
cache-source: cache
cache-target: /cache
- name: 🛠️ Build using docker
run: |
docker buildx build . -f dist/web/Dockerfile --progress=plain --build-arg 'JOBS=4' --output out --target raw
- name: 🔨 Fix permissions
run: |
chmod -c -R +rX "out/"
- name: ⬆️ Upload artifacts
uses: actions/upload-pages-artifact@v2
with:
path: out/
# See https://github.com/actions/cache/issues/342#issuecomment-1711054115
- name: 🗑️ Delete old cache
continue-on-error: true
env:
GH_TOKEN: ${{ github.token }}
run: |
gh extension install actions/gh-actions-cache
gh actions-cache delete "build-web-cache" --confirm
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
name: 📃 Deploy to GitHub Pages
runs-on: ubuntu-latest
if: ${{ github.ref == 'refs/heads/master' && github.event.repository.fork == false }}
needs: build
steps:
- name: 🌍 Deploy
id: deployment
uses: actions/deploy-pages@v2

View File

@@ -10,7 +10,7 @@ on:
jobs:
release-update-repos:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
name: Release Update Repos
steps:
@@ -63,7 +63,7 @@ jobs:
token: ${{ secrets.RELEASE_TOKEN }}
release-upload-artifacts:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
name: Release Upload Artifacts
steps:
@@ -90,7 +90,7 @@ jobs:
run: tar --exclude-vcs -czvf Full.Sources.tar.gz ImHex
- name: ⬇️ Download artifacts from latest workflow
uses: dawidd6/action-download-artifact@v3
uses: dawidd6/action-download-artifact@v6
with:
github_token: ${{secrets.GITHUB_TOKEN}}
workflow: build.yml
@@ -117,6 +117,7 @@ jobs:
run: |
mv "Windows Portable x86_64.zip" imhex-${{ env.IMHEX_VERSION }}-Windows-Portable-x86_64.zip
mv "Windows Portable NoGPU x86_64.zip" imhex-${{ env.IMHEX_VERSION }}-Windows-Portable-NoGPU-x86_64.zip
mv "ImHex Web.zip" imhex-${{ env.IMHEX_VERSION }}-web.zip
- name: ⬆️ Upload everything to release
uses: softprops/action-gh-release@4634c16e79c963813287e889244c50009e7f0981
@@ -147,7 +148,7 @@ jobs:
commit_email: itrooz@protonmail.com
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
commit_message: Bump to version ${{ env.IMHEX_VERSION }}
ssh_keyscan_types: rsa,dsa,ecdsa,ed25519
ssh_keyscan_types: rsa,ecdsa,ed25519
release-update-winget:
name: Release update winget package

30
.github/workflows/stale_issues.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: Close inactive issues
on:
schedule:
- cron: "30 1 * * 0"
workflow_dispatch:
jobs:
close-issues:
runs-on: ubuntu-24.04
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v5
with:
operations-per-run: '200'
ascending: true
days-before-issue-stale: 334
days-before-issue-close: 30
stale-issue-label: "stale"
stale-issue-message: |
This issue is marked stale as it has been open for 11 months without activity.
Please try the latest ImHex version. (Avaiable here: https://imhex.download/ for release and https://imhex.download/#nightly for development version)
If the issue persists on the latest version, please make a comment on this issue again
Without response, this issue will be closed in one month.
close-issue-message: ""
days-before-pr-stale: -1
days-before-pr-close: -1
repo-token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -6,6 +6,7 @@ on:
- 'master'
- 'releases/**'
- 'tests/**'
- 'feature/**'
pull_request:
branches:
- 'master'
@@ -15,7 +16,7 @@ on:
jobs:
tests:
name: 🧪 Unit Tests
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
permissions:
actions: read
contents: read
@@ -38,14 +39,13 @@ jobs:
run: |
sudo apt update
sudo bash dist/get_deps_debian.sh
sudo apt install gcovr -y
- name: 🛠️ Build
run: |
set -x
mkdir -p build
cd build
CC=gcc-12 CXX=g++-12 cmake \
CC=gcc-14 CXX=g++-14 cmake \
-DCMAKE_BUILD_TYPE=Debug \
-DIMHEX_ENABLE_UNIT_TESTS=ON \
-DIMHEX_ENABLE_PLUGIN_TESTS=ON \
@@ -54,8 +54,10 @@ jobs:
-DCMAKE_C_FLAGS="-fuse-ld=lld -fsanitize=address,leak,undefined -fno-sanitize-recover=all --coverage" \
-DCMAKE_CXX_FLAGS="-fuse-ld=lld -fsanitize=address,leak,undefined -fno-sanitize-recover=all --coverage" \
-DIMHEX_OFFLINE_BUILD=ON \
-G Ninja \
..
make -j4 unit_tests
ninja unit_tests
ninja imhex_all
- name: 🧪 Perform plcli Integration Tests
run: |
@@ -68,16 +70,24 @@ jobs:
ctest --output-on-failure
# Generate report from all gcov .gcda files
- name: 🧪 Generate coverage report
run: |
gcovr --gcov-executable /usr/bin/gcov-12 -r . build --xml coverage_report.xml --verbose
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}
file: coverage_report.xml
#- name: 🧪 Generate coverage report
# run: |
# sudo apt install python3-pip python3-venv
# python3 -m venv venv
# . venv/bin/activate
# pip3 install gcovr
# cd build
# gcovr --gcov-executable /usr/bin/gcov-14 --exclude '.*/yara_rules/' --exclude '.*/third_party/' --exclude '.*/external/' --root .. --xml coverage_report.xml --verbose --gcov-ignore-errors all
#
#- name: Upload coverage reports to Codecov
# env:
# CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
# if: ${{ env.CODECOV_TOKEN }}
# uses: codecov/codecov-action@v4
# with:
# fail_ci_if_error: true
# token: ${{ secrets.CODECOV_TOKEN }}
# file: build/coverage_report.xml
langs:
name: 🧪 Langs

1
.gitignore vendored
View File

@@ -6,6 +6,7 @@ cmake-build-*/
build*/
local/
venv/
.cache/
*.mgc
*.kdev4

7
.gitmodules vendored
View File

@@ -28,7 +28,7 @@
ignore = dirty
[submodule "lib/third_party/lunasvg"]
path = lib/third_party/lunasvg
url = https://github.com/sammycage/lunasvg
url = https://github.com/WerWolv/lunasvg
ignore = dirty
[submodule "lib/external/libromfs"]
@@ -43,4 +43,7 @@
[submodule "lib/third_party/HashLibPlus"]
path = lib/third_party/HashLibPlus
url = https://github.com/WerWolv/HashLibPlus
url = https://github.com/WerWolv/HashLibPlus
[submodule "lib/external/disassembler"]
path = lib/external/disassembler
url = https://github.com/WerWolv/Disassembler

View File

@@ -32,13 +32,14 @@ include("${IMHEX_BASE_FOLDER}/cmake/ide_helpers.cmake")
# Basic compiler and cmake configurations
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_INCLUDE_DIRECTORIES_BEFORE ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include("${IMHEX_BASE_FOLDER}/cmake/build_helpers.cmake")
# Setup project
loadVersion(IMHEX_VERSION IMHEX_VERSION_PLAIN)
setVariableInParent(IMHEX_VERSION ${IMHEX_VERSION})
configureCMake()
configureCMake()
project(imhex
LANGUAGES C CXX
VERSION ${IMHEX_VERSION_PLAIN}
@@ -72,16 +73,18 @@ addPluginDirectories()
# Add unit tests
if (IMHEX_ENABLE_UNIT_TESTS)
enable_testing()
add_subdirectory(tests EXCLUDE_FROM_ALL)
if (NOT TARGET unit_tests)
enable_testing()
add_custom_target(unit_tests)
add_subdirectory(tests EXCLUDE_FROM_ALL)
endif ()
endif ()
# Configure more resources that will be added to the install package
generatePDBs()
generateSDKDirectory()
# Handle package generation
createPackage()
# Accomodate IDEs with FOLDER support
# Accommodate IDEs with FOLDER support
tweakTargetsForIDESupport()

View File

@@ -27,6 +27,11 @@ chmod +x imhex-*.AppImage
./imhex-*.AppImage
```
If you're experiencing glib / libgtk assertion failures, you might need to setup your `XDG_DATA_DIRS` env var correctly. In this case, run the following command before executing the AppImage. (See issue [ImHex/#2038](https://github.com/WerWolv/ImHex/issues/2038))
```bash
export XDG_DATA_DIRS="/usr/local/share:/usr/share"
```
#### Flatpak
To install the Flatpak, make sure you have the Flathub repository added to your system. Then simply run the following command:

View File

@@ -38,8 +38,8 @@ If you like my work, please consider supporting me on GitHub Sponsors, Patreon o
</p>
## Screenshots
![Hex editor, patterns and data information](https://github.com/WerWolv/ImHex/assets/10835354/4f358238-2d27-41aa-9015-a2c6cc3708cf)
![Bookmarks, disassembler and data processor](https://github.com/WerWolv/ImHex/assets/10835354/183bc2cc-2439-4ded-b4c5-b140e19fc92f)
![Hex editor, patterns and data information](https://github.com/user-attachments/assets/902a7c4c-410d-490f-999e-14c856fec027)
![Bookmarks, data information, find view and data processor](https://github.com/user-attachments/assets/58eefa1f-31c9-4bb8-a1c1-8cdd8ddbd29f)
<details>
<summary><strong>More Screenshots</strong></summary>
@@ -314,23 +314,26 @@ To use ImHex, the following minimal system requirements need to be met.
> ImHex requires a GPU with OpenGL 3.0 support in general.
> There are releases available (with the `-NoGPU` suffix) that are software rendered and don't require a GPU, however these can be a lot slower than the GPU accelerated versions.
>
> If possible at all, make ImHex use the dedicated GPU on your system instead of the integrated one (especially Intel HD GPUs are known to cause issues).
> If possible at all, make ImHex use the dedicated GPU on your system instead of the integrated one.
> ImHex will usually run fine with integrated GPUs as well but certain Intel HD GPU drivers on Windows are known to cause graphical artifacts.
- **OS**:
- **Windows**: Windows 7 or higher (Windows 10/11 recommended)
- **macOS**: macOS 12.1 (Monterey) or higher,
- Lower versions are supported, but you'll need to compile ImHex yourself
- **macOS**: macOS 13 (Ventura) or higher,
- Lower versions should still work too, but you'll need to compile ImHex yourself. The release binaries will NOT work.
- The macOS build is not signed and will require you to manually allow them in the Security & Privacy settings.
- **Linux**: "Modern" Linux. The following distributions have official releases available. Other distros are supported through the AppImage and Flatpak releases.
- Ubuntu 22.04/23.04
- Fedora 36/37
- RHEL/AlmaLinux 9
- Ubuntu and Debian
- Fedora
- RHEL/AlmaLinux
- Arch Linux
- **CPU**: x86_64 (64 Bit)
- Basically any other distro will work as well when compiling ImHex from sources.
- **CPU**: Officially supported are x86_64 and ARM64, though any Little Endian 64 bit CPU should work.
- **GPU**: OpenGL 3.0 or higher
- Intel HD drivers are really buggy and often cause graphic artifacts
- Integrated Intel HD iGPUs are supported, however certain drivers are known to cause various graphical artifacts, especially on Windows. Use at your own risk.
- In case you don't have a GPU available, there are software rendered releases available for Windows and macOS
- **RAM**: 256MB, more may be required for more complicated analysis
- **Storage**: 100MB
- **RAM**: ~150MiB, more is required for more complex analysis
- **Storage**: 150MiB
## Installing
@@ -339,8 +342,10 @@ Information on how to install ImHex can be found in the [Install](/INSTALL.md) g
## Compiling
To compile ImHex on any platform, GCC (or Clang) is required with a version that supports C++23 or higher.
On macOS, Clang is also required to compile some ObjC code.
All releases are being built using latest available GCC.
Windows and Linux releases are being built using latest available GCC.
MacOS releases are being built using latest available LLVM Clang.
Important to note is, the MSVC and AppleClang compilers are both **NOT** supported since they're both generally severely outdated and lack features GCC and LLVM Clang have.
> [!NOTE]
> Many dependencies are bundled into the repository using submodules so make sure to clone it using the `--recurse-submodules` option.

View File

@@ -1 +1 @@
1.35.4
1.37.0.WIP

View File

@@ -1,3 +1,17 @@
# Some libraries we use set the BUILD_SHARED_LIBS variable to ON, which causes CMake to
# display a warning about options being set using set() instead of option().
# Explicitly set the policy to NEW to suppress the warning.
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
set(CMAKE_POLICY_DEFAULT_CMP0063 NEW)
if (POLICY CMP0177)
set(CMAKE_POLICY_DEFAULT_CMP0177 OLD)
cmake_policy(SET CMP0177 OLD)
endif()
set(CMAKE_WARN_DEPRECATED OFF CACHE BOOL "Disable deprecated warnings" FORCE)
include(FetchContent)
if(IMHEX_STRIP_RELEASE)
@@ -225,7 +239,8 @@ macro(createPackage)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE DESTINATION ${CMAKE_INSTALL_PREFIX}/share/licenses/imhex)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dist/imhex.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resources/icon.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/pixmaps RENAME imhex.png)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dist/imhex.mime.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/mime/packages RENAME imhex.xml)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resources/icon.svg DESTINATION ${CMAKE_INSTALL_PREFIX}/share/pixmaps RENAME imhex.svg)
downloadImHexPatternsFiles("./share/imhex")
# install AppStream file
@@ -239,6 +254,7 @@ macro(createPackage)
if (APPLE)
if (IMHEX_GENERATE_PACKAGE)
set(EXTRA_BUNDLE_LIBRARY_PATHS ${EXTRA_BUNDLE_LIBRARY_PATHS} "${IMHEX_SYSTEM_LIBRARY_PATH}")
include(PostprocessBundle)
set_target_properties(libimhex PROPERTIES SOVERSION ${IMHEX_VERSION})
@@ -307,9 +323,6 @@ endfunction()
macro(configureCMake)
message(STATUS "Configuring ImHex v${IMHEX_VERSION}")
# Enable C and C++ languages
enable_language(C CXX)
set(CMAKE_POSITION_INDEPENDENT_CODE ON CACHE BOOL "Enable position independent code for all targets" FORCE)
# Configure use of recommended build tools
@@ -371,18 +384,12 @@ macro(configureCMake)
message(WARNING "LTO is not supported: ${output_error}")
endif ()
endif ()
# Some libraries we use set the BUILD_SHARED_LIBS variable to ON, which causes CMake to
# display a warning about options being set using set() instead of option().
# Explicitly set the policy to NEW to suppress the warning.
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
set(CMAKE_POLICY_DEFAULT_CMP0063 NEW)
set(CMAKE_WARN_DEPRECATED OFF CACHE BOOL "Disable deprecated warnings" FORCE)
endmacro()
function(configureProject)
# Enable C and C++ languages
enable_language(C CXX)
if (XCODE)
# Support Xcode's multi configuration paradigm by placing built artifacts into separate directories
set(IMHEX_MAIN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/Configs/$<CONFIG>" PARENT_SCOPE)
@@ -573,7 +580,7 @@ macro(setupCompilerFlags target)
set(IMHEX_CXX_FLAGS "-fexceptions -frtti")
# Disable some warnings
set(IMHEX_C_CXX_FLAGS "-Wno-unknown-warning-option -Wno-array-bounds -Wno-deprecated-declarations -Wno-unknown-pragmas")
set(IMHEX_C_CXX_FLAGS "-Wno-array-bounds -Wno-deprecated-declarations -Wno-unknown-pragmas")
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
@@ -582,6 +589,13 @@ macro(setupCompilerFlags target)
endif ()
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND APPLE)
execute_process(COMMAND brew --prefix llvm OUTPUT_VARIABLE LLVM_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${LLVM_PREFIX}/lib/c++")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${LLVM_PREFIX}/lib/c++")
set(IMHEX_C_CXX_FLAGS "-Wno-unknown-warning-option")
endif()
# Disable some warnings for gcc
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
set(IMHEX_C_CXX_FLAGS "${IMHEX_C_CXX_FLAGS} -Wno-restrict -Wno-stringop-overread -Wno-stringop-overflow -Wno-dangling-reference")
@@ -640,6 +654,7 @@ macro(addBundledLibraries)
set(FPHSA_NAME_MISMATCHED ON CACHE BOOL "")
if(NOT USE_SYSTEM_FMT)
set(FMT_INSTALL OFF CACHE BOOL "Disable install targets for libfmt" FORCE)
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/fmt EXCLUDE_FROM_ALL)
set(FMT_LIBRARIES fmt::fmt-header-only)
else()
@@ -702,8 +717,8 @@ macro(addBundledLibraries)
endif()
if (USE_SYSTEM_BOOST)
find_package(boost REQUIRED)
set(BOOST_LIBRARIES boost::regex)
find_package(Boost REQUIRED)
set(BOOST_LIBRARIES Boost::regex)
else()
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/boost ${CMAKE_CURRENT_BINARY_DIR}/boost EXCLUDE_FROM_ALL)
set(BOOST_LIBRARIES boost::regex)
@@ -719,6 +734,7 @@ macro(addBundledLibraries)
endif()
add_subdirectory(${EXTERNAL_LIBS_FOLDER}/pattern_language EXCLUDE_FROM_ALL)
add_subdirectory(${EXTERNAL_LIBS_FOLDER}/disassembler EXCLUDE_FROM_ALL)
if (LIBPL_SHARED_LIBRARY)
install(
@@ -775,59 +791,6 @@ function(enableUnityBuild TARGET)
endif ()
endfunction()
function(generatePDBs)
if (NOT IMHEX_GENERATE_PDBS)
return()
endif ()
if (NOT WIN32 OR CMAKE_BUILD_TYPE STREQUAL "Debug")
return()
endif ()
include(FetchContent)
FetchContent_Declare(
cv2pdb
URL "https://github.com/rainers/cv2pdb/releases/download/v0.52/cv2pdb-0.52.zip"
DOWNLOAD_EXTRACT_TIMESTAMP ON
)
FetchContent_Populate(cv2pdb)
set(PDBS_TO_GENERATE main main-forwarder libimhex ${PLUGINS})
foreach (PDB ${PDBS_TO_GENERATE})
if (PDB STREQUAL "main")
set(GENERATED_PDB imhex)
elseif (PDB STREQUAL "main-forwarder")
set(GENERATED_PDB imhex-gui)
elseif (PDB STREQUAL "libimhex")
set(GENERATED_PDB libimhex)
else ()
set(GENERATED_PDB plugins/${PDB})
endif ()
if (IMHEX_REPLACE_DWARF_WITH_PDB)
set(PDB_OUTPUT_PATH ${CMAKE_BINARY_DIR}/${GENERATED_PDB})
else ()
set(PDB_OUTPUT_PATH)
endif()
add_custom_target(${PDB}_pdb DEPENDS ${CMAKE_BINARY_DIR}/${GENERATED_PDB}.pdb)
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/${GENERATED_PDB}.pdb
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND
(
${CMAKE_COMMAND} -E remove -f ${CMAKE_BINARY_DIR}/${GENERATED_PDB}.pdb &&
${cv2pdb_SOURCE_DIR}/cv2pdb64.exe $<TARGET_FILE:${PDB}> ${PDB_OUTPUT_PATH} &&
${CMAKE_COMMAND} -E remove -f ${CMAKE_BINARY_DIR}/${GENERATED_PDB}
) || (exit 0)
COMMAND_EXPAND_LISTS)
install(FILES ${CMAKE_BINARY_DIR}/${GENERATED_PDB}.pdb DESTINATION ".")
add_dependencies(imhex_all ${PDB}_pdb)
endforeach ()
endfunction()
function(generateSDKDirectory)
if (WIN32)
set(SDK_PATH "./sdk")
@@ -848,7 +811,7 @@ function(generateSDKDirectory)
if (NOT USE_SYSTEM_NLOHMANN_JSON)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/lib/third_party/nlohmann_json DESTINATION "${SDK_PATH}/lib/third_party")
endif()
if (NOT USE_SYSTEM_NLOHMANN_JSON)
if (NOT USE_SYSTEM_BOOST)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/lib/third_party/boost DESTINATION "${SDK_PATH}/lib/third_party")
endif()
@@ -856,6 +819,12 @@ function(generateSDKDirectory)
install(FILES ${CMAKE_SOURCE_DIR}/cmake/build_helpers.cmake DESTINATION "${SDK_PATH}/cmake")
install(DIRECTORY ${CMAKE_SOURCE_DIR}/cmake/sdk/ DESTINATION "${SDK_PATH}")
install(TARGETS libimhex ARCHIVE DESTINATION "${SDK_PATH}/lib")
install(DIRECTORY ${CMAKE_SOURCE_DIR}/plugins/ui DESTINATION "${SDK_PATH}/lib" PATTERN "**/source/*" EXCLUDE)
install(TARGETS ui ARCHIVE DESTINATION "${SDK_PATH}/lib")
install(DIRECTORY ${CMAKE_SOURCE_DIR}/plugins/fonts DESTINATION "${SDK_PATH}/lib" PATTERN "**/source/*" EXCLUDE)
install(TARGETS fonts ARCHIVE DESTINATION "${SDK_PATH}/lib")
endfunction()
function(addIncludesFromLibrary target library)

View File

@@ -0,0 +1,60 @@
find_path(LZ4_INCLUDE_DIR
NAMES lz4.h
HINTS "${LZ4_INCLUDEDIR}" "${LZ4_HINTS}/include"
PATHS
/usr/local/include
/usr/include
)
find_library(LZ4_LIBRARY
NAMES lz4 liblz4
HINTS "${LZ4_LIBDIR}" "${LZ4_HINTS}/lib"
PATHS
/usr/local/lib
/usr/lib
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args( LZ4 DEFAULT_MSG LZ4_LIBRARY LZ4_INCLUDE_DIR )
if( LZ4_FOUND )
include( CheckIncludeFile )
include( CMakePushCheckState )
set( LZ4_INCLUDE_DIRS ${LZ4_INCLUDE_DIR} )
set( LZ4_LIBRARIES ${LZ4_LIBRARY} )
cmake_push_check_state()
set( CMAKE_REQUIRED_INCLUDES ${LZ4_INCLUDE_DIRS} )
check_include_file( lz4frame.h HAVE_LZ4FRAME_H )
cmake_pop_check_state()
if (WIN32)
set ( LZ4_DLL_DIR "${LZ4_HINTS}/bin"
CACHE PATH "Path to LZ4 DLL"
)
file( GLOB _lz4_dll RELATIVE "${LZ4_DLL_DIR}"
"${LZ4_DLL_DIR}/lz4*.dll"
)
set ( LZ4_DLL ${_lz4_dll}
# We're storing filenames only. Should we use STRING instead?
CACHE FILEPATH "LZ4 DLL file name"
)
file( GLOB _lz4_pdb RELATIVE "${LZ4_DLL_DIR}"
"${LZ4_DLL_DIR}/lz4*.pdb"
)
set ( LZ4_PDB ${_lz4_pdb}
CACHE FILEPATH "LZ4 PDB file name"
)
mark_as_advanced( LZ4_DLL_DIR LZ4_DLL LZ4_PDB )
endif()
else()
set( LZ4_INCLUDE_DIRS )
set( LZ4_LIBRARIES )
endif()
mark_as_advanced( LZ4_LIBRARIES LZ4_INCLUDE_DIRS )
add_library( LZ4::lz4 INTERFACE IMPORTED )
set_property( TARGET LZ4::lz4 PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${LZ4_INCLUDE_DIRS} )
set_property( TARGET LZ4::lz4 PROPERTY INTERFACE_LINK_LIBRARIES ${LZ4_LIBRARIES} )

View File

@@ -55,9 +55,9 @@ IF(MBEDTLS_FOUND)
MESSAGE(STATUS " Crypto: ${MBEDCRYPTO_LIBRARY}")
ENDIF(NOT MBEDTLS_FIND_QUIETLY)
ELSE(MBEDTLS_FOUND)
IF(MBEDTLS_FIND_REQUIRED)
IF(mbedTLS_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find mbedTLS")
ENDIF(MBEDTLS_FIND_REQUIRED)
ENDIF(mbedTLS_FIND_REQUIRED)
ENDIF(MBEDTLS_FOUND)
MARK_AS_ADVANCED(
@@ -67,4 +67,4 @@ MARK_AS_ADVANCED(
MBEDTLS_LIBRARY
MBEDX509_LIBRARY
MBEDCRYPTO_LIBRARY
)
)

View File

@@ -11,31 +11,23 @@ AppDir:
exec_args: $@
apt:
arch:
- amd64
- "{{ARCHITECTURE_PACKAGE}}"
allow_unauthenticated: true
sources:
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ jammy main restricted
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ jammy-updates main restricted
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ jammy universe
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ jammy-updates universe
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ jammy multiverse
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ jammy-updates multiverse
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ jammy-backports main restricted
universe multiverse
- sourceline: deb http://security.ubuntu.com/ubuntu jammy-security main restricted
- sourceline: deb http://security.ubuntu.com/ubuntu jammy-security universe
- sourceline: deb http://security.ubuntu.com/ubuntu jammy-security multiverse
- sourceline: 'deb [arch=amd64] http://us.archive.ubuntu.com/ubuntu/ oracular main restricted universe multiverse'
- sourceline: 'deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ oracular main restricted universe multiverse'
include:
- librsvg2-common
- libbz2-1.0:amd64
- libcap2:amd64
- libdbus-1-3:amd64
- libgpg-error0:amd64
- liblzma5:amd64
- libnss-mdns:amd64
- libpcre3:amd64
- libselinux1:amd64
- libtinfo6:amd64
- libbz2-1.0
- libcap2
- libdbus-1-3
- libfontconfig1
- libgpg-error0
- liblzma5
- libnss-mdns
- libpcre3
- libselinux1
- libtinfo6
files:
include:
- /lib/x86_64-linux-gnu/libLLVM-13.so.1
@@ -132,6 +124,6 @@ AppDir:
- usr/share/doc/*/NEWS.*
- usr/share/doc/*/TODO.*
AppImage:
arch: x86_64
update-information: gh-releases-zsync|WerWolv|ImHex|latest|imhex-*-x86_64.AppImage.zsync
file_name: imhex-{{VERSION}}-x86_64.AppImage
arch: "{{ARCHITECTURE_APPIMAGE_BUILDER}}"
update-information: gh-releases-zsync|WerWolv|ImHex|latest|imhex-*-{{ARCHITECTURE_FILE_NAME}}.AppImage.zsync
file_name: imhex-{{VERSION}}-{{ARCHITECTURE_FILE_NAME}}.AppImage

View File

@@ -1,4 +1,4 @@
FROM ubuntu:22.04 as build
FROM ubuntu:24.10 as build
# Used to invalidate layer cache but not mount cache
# See https://github.com/moby/moby/issues/41715#issuecomment-733976493
@@ -14,24 +14,13 @@ apt update
# general deps
apt install -y ccache git wget
# appimage tools deps
apt install -y python3-pip python3-setuptools desktop-file-utils libgdk-pixbuf2.0-dev fuse ninja-build
apt install -y python3-pip python3-venv python3-setuptools desktop-file-utils libgdk-pixbuf2.0-dev fuse ninja-build
apt install -y squashfs-tools zsync
# imhex deps
/tmp/get_deps_debian.sh
EOF
RUN --mount=type=cache,target=/cache <<EOF
# Download appimage-builder
set -xe
mkdir -p /cache/bin
wget -nc https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage -O /cache/bin/appimagetool || true
chmod +x /cache/bin/appimagetool
pip3 install git+https://github.com/AppImageCrafters/appimage-builder@f38699e
EOF
ENV PATH="/cache/bin/:${PATH}"
# Copy Imhex source
@@ -41,13 +30,19 @@ ARG LTO=ON
ARG BUILD_TYPE=RelWithDebInfo
ARG GIT_COMMIT_HASH
ARG GIT_BRANCH
ARG ARCHITECTURE_PACKAGE
ARG ARCHITECTURE_FILE_NAME
ARG ARCHITECTURE_APPIMAGE_BUILDER
WORKDIR /build
SHELL ["bash", "-c"] # Ubuntu sh doesnt support string substitution
# Ubuntu sh doesnt support string substitution
SHELL ["bash", "-c"]
RUN <<EOF
# Prepare ImHex build
set -xe
CC=gcc-12 CXX=g++-12 cmake -G "Ninja" \
CC=gcc-14 CXX=g++-14 cmake -G "Ninja" \
-DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DCMAKE_INSTALL_PREFIX="/usr" \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
@@ -71,11 +66,23 @@ ccache -s
EOF
RUN <<EOF
# Package ImHex as AppImage
# Download appimage-builder
set -xe
mkdir -p /cache/bin
wget -nc https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage -O /cache/bin/appimagetool || true
chmod +x /cache/bin/appimagetool
python3 -m venv venv
. venv/bin/activate
pip3 install git+https://github.com/AppImageCrafters/appimage-builder@f38699e
# Package ImHex as AppImage
export VERSION=$(cat /imhex/VERSION)
appimage-builder --recipe /imhex/dist/AppImageBuilder.yml
export ARCHITECTURE_PACKAGE=${ARCHITECTURE_PACKAGE}
export ARCHITECTURE_FILE_NAME=${ARCHITECTURE_FILE_NAME}
export ARCHITECTURE_APPIMAGE_BUILDER=${ARCHITECTURE_APPIMAGE_BUILDER}
appimage-builder --recipe /imhex/dist/AppImage/AppImageBuilder.yml
EOF
FROM scratch

View File

@@ -13,6 +13,7 @@ RUN pacman -S --needed --noconfirm \
glfw-x11 \
file \
mbedtls \
fontconfig \
freetype2 \
curl \
dbus \

4
dist/Arch/PKGBUILD vendored
View File

@@ -8,7 +8,7 @@ pkgdesc="A Hex Editor for Reverse Engineers, Programmers and people who value th
arch=("x86_64")
url="https://github.com/WerWolv/ImHex"
license=('GPL2')
depends=(glfw mbedtls freetype2 libglvnd dbus gtk3 curl fmt yara nlohmann-json zlib bzip2 xz zstd)
depends=(glfw mbedtls fontconfig freetype2 libglvnd dbus gtk3 curl fmt yara nlohmann-json zlib bzip2 xz zstd)
makedepends=(git)
provides=(imhex)
conflicts=(imhex)
@@ -26,5 +26,5 @@ package() {
install -d "$pkgdir/usr/share/imhex"
cp -r "$srcdir/usr/share/imhex/"{constants,encodings,includes,magic,patterns} "$pkgdir/usr/share/imhex"
cp -r "$srcdir/usr/share/"{applications,licenses,pixmaps} "$pkgdir/usr/share"
cp -r "$srcdir/usr/share/"{applications,licenses,pixmaps,mime} "$pkgdir/usr/share"
}

View File

@@ -4,7 +4,7 @@ Section: editors
Priority: optional
Architecture: amd64
License: GNU GPL-2
Depends: libglfw3 | libglfw3-wayland, libmagic1, libmbedtls14, libfreetype6, libopengl0, libdbus-1-3, xdg-desktop-portal
Depends: libfontconfig1, libglfw3 | libglfw3-wayland, libmagic1, libmbedtls14, libfreetype6, libopengl0, libdbus-1-3, xdg-desktop-portal
Maintainer: WerWolv <hey@werwolv.net>
Description: ImHex Hex Editor
A Hex Editor for Reverse Engineers, Programmers and

View File

@@ -20,13 +20,14 @@ DEPEND=""
RDEPEND="${DEPEND}
media-libs/glfw
sys-apps/file
dev-libs/mbedtls
net-libs/mbedtls
dev-cpp/nlohmann_json
dbus
xdg-desktop-portal
sys-apps/dbus
sys-apps/xdg-desktop-portal
sys-libs/zlib
app-arch/bzip2
app-arch/lzma
app-arch/zstd
app-arch/bzip2
app-arch/lzma
app-arch/zstd
app-arch/lz4
"
BDEPEND="${DEPEND}"

View File

@@ -5,6 +5,7 @@ pacman -S $@ --needed \
gcc \
lld \
glfw \
fontconfig \
file \
mbedtls \
freetype2 \
@@ -18,4 +19,5 @@ pacman -S $@ --needed \
zlib \
bzip2 \
xz \
zstd
zstd \
lz4

View File

@@ -8,8 +8,8 @@ fi
apt install -y \
build-essential \
gcc-12 \
g++-12 \
gcc-14 \
g++-14 \
lld \
${PKGCONF:-} \
cmake \
@@ -18,6 +18,7 @@ apt install -y \
libglm-dev \
libmagic-dev \
libmbedtls-dev \
libfontconfig-dev \
libfreetype-dev \
libdbus-1-dev \
libcurl4-gnutls-dev \
@@ -26,4 +27,5 @@ apt install -y \
zlib1g-dev \
libbz2-dev \
liblzma-dev \
libzstd-dev
libzstd-dev \
liblz4-dev

View File

@@ -4,6 +4,7 @@ dnf install -y \
cmake \
dbus-devel \
file-devel \
fontconfig-devel \
freetype-devel \
libcurl-devel \
gcc-c++ \
@@ -16,4 +17,5 @@ dnf install -y \
libzstd-devel \
zlib-devel \
bzip2-devel \
xz-devel
xz-devel \
lz4-devel

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env sh
pacman -S --needed --noconfirm pactoys
pacman -S --needed --noconfirm pactoys unzip
pacboy -S --needed --noconfirm \
gcc:p \
lld:p \
@@ -17,4 +17,5 @@ pacboy -S --needed --noconfirm \
zlib:p \
bzip2:p \
xz:p \
zstd:p
zstd:p \
lz4:p

View File

@@ -3,8 +3,9 @@
zypper install \
cmake \
ninja \
gcc12 \
gcc12-c++ \
gcc14 \
gcc14-c++ \
fontconfig-devel \
freetype2-devel \
libcurl-devel \
dbus-1-devel \
@@ -16,4 +17,5 @@ zypper install \
libzstd-devel \
zlib-devel \
bzip3-devel \
xz-devel
xz-devel \
lz4-dev

7
dist/imhex.desktop vendored
View File

@@ -1,4 +1,5 @@
[Desktop Entry]
Version=1.0
Name=ImHex
Comment=ImHex Hex Editor
GenericName=Hex Editor
@@ -9,3 +10,9 @@ StartupNotify=true
Categories=Development;IDE;
StartupWMClass=imhex
Keywords=static-analysis;reverse-engineering;disassembler;disassembly;hacking;forensics;hex-editor;cybersecurity;security;binary-analysis;
MimeType=application/vnd.imhex.proj;
Actions=NewFile;
[Desktop Action NewFile]
Exec=imhex --new
Name=Create New File

8
dist/imhex.mime.xml vendored Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<mime-type type="application/vnd.imhex.proj">
<comment>ImHex Project</comment>
<glob pattern="*.hexproj"/>
</mime-type>
</mime-info>

16
dist/langtool.py vendored
View File

@@ -129,16 +129,19 @@ def main():
key in lang_data["translations"]
and lang_data["translations"][key] != INVALID_TRANSLATION
)
if not has_translation and not (
(command == "retranslate" or command == "untranslate")
and re.compile(args.keys).fullmatch(key)
if (
has_translation
and not (
(command == "retranslate" or command == "untranslate")
and re.compile(args.keys).fullmatch(key)
)
and not command == "fmtzh"
):
continue
if command == "check":
print(
f"Error: Translation {lang_data['code']} is missing translation for key '{key}'"
)
exit(2)
elif (
command == "translate"
or command == "retranslate"
@@ -148,7 +151,10 @@ def main():
continue
reference_tranlsation = (
" '%s'" % reference_lang_data["translations"][key]
if reference_lang_data
if (
reference_lang_data
and key in reference_lang_data["translations"]
)
else ""
)
print(

View File

@@ -6,7 +6,6 @@ brew "freetype2"
brew "libmagic"
brew "pkg-config"
brew "curl"
brew "gcc@12"
brew "llvm"
brew "glfw"
brew "ninja"

View File

@@ -1,7 +1,7 @@
# This base image is also known as "crosscompile". See arm64.crosscompile.Dockerfile
FROM ghcr.io/itrooz/macos-crosscompile:clang17-nosdk as build
FROM ghcr.io/itrooz/macos-crosscompile:clang19-nosdk as build
ENV MACOSX_DEPLOYMENT_TARGET 12.1
ENV MACOSX_DEPLOYMENT_TARGET 13.0
# -- DOWNLOADING STUFF
@@ -118,7 +118,7 @@ if [ "$CUSTOM_GLFW" ]; then
cd /mnt/glfw
mkdir build
cd build
CC=o64-gcc CXX=o64-g++ cmake -G "Ninja" \
CC=o64-clang CXX=o64-clang++ cmake -G "Ninja" \
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
-DBUILD_SHARED_LIBS=ON \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
@@ -126,7 +126,7 @@ if [ "$CUSTOM_GLFW" ]; then
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_INSTALL_PREFIX=/vcpkg/installed/arm-osx-mytriplet \
-DVCPKG_TARGET_TRIPLET=arm-osx-mytriplet -DCMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=/osxcross/target/toolchain.cmake -DCMAKE_OSX_SYSROOT=/osxcross/target/SDK/MacOSX14.0.sdk -DCMAKE_OSX_DEPLOYMENT_TARGET=12.1 \
-DVCPKG_TARGET_TRIPLET=arm-osx-mytriplet -DCMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=/osxcross/target/toolchain.cmake -DCMAKE_OSX_SYSROOT=/osxcross/target/SDK/MacOSX14.0.sdk -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 \
..
ninja -j $JOBS install
@@ -148,7 +148,7 @@ RUN --mount=type=cache,target=/cache --mount=type=cache,target=/mnt/ImHex/build/
`# ccache flags` \
-DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_OBJC_COMPILER_LAUNCHER=ccache -DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
`# MacOS cross-compiling flags` \
-DVCPKG_TARGET_TRIPLET=arm-osx-mytriplet -DCMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=/osxcross/target/toolchain.cmake -DCMAKE_OSX_SYSROOT=/osxcross/target/SDK/MacOSX14.0.sdk -DCMAKE_OSX_DEPLOYMENT_TARGET=12.1 \
-DVCPKG_TARGET_TRIPLET=arm-osx-mytriplet -DCMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=/osxcross/target/toolchain.cmake -DCMAKE_OSX_SYSROOT=/osxcross/target/SDK/MacOSX14.0.sdk -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 \
`# Override compilers for code generators` \
-DNATIVE_CMAKE_C_COMPILER=/usr/bin/clang -DNATIVE_CMAKE_CXX_COMPILER=/usr/bin/clang++ \
`# Normal ImHex flags` \

View File

@@ -1,4 +1,4 @@
# This image is is provided for reference, but a (probably more up to date) image should be available at https://github.com/iTrooz/macos-crosscompile
# This image is provided for reference, but a (probably more up to date) image should be available at https://github.com/iTrooz/macos-crosscompile
FROM ubuntu:22.04
ENV PATH $PATH:/osxcross/target/bin
@@ -68,19 +68,6 @@ RUN --mount=type=cache,target=/cache <<EOF
ccache -s
EOF
# Not needed, because we don't use gcc for cross-compiling anymore
# ## Install dependencies for gcc-13
# RUN apt install -y gcc g++ zlib1g-dev libmpc-dev libmpfr-dev libgmp-dev
# ## Build cross-compiler gcc-13
# RUN --mount=type=cache,target=/cache <<EOF
# set -xe
# ccache -zs
# cd /osxcross
# UNATTENDED=1 CC=/usr/lib/ccache/gcc CXX=/usr/lib/ccache/g++ GCC_VERSION=13.2.0 ./build_gcc.sh
# ccache -s
# EOF
ARG DELETE_SDK=1
RUN <<EOF

16
dist/rpm/imhex.spec vendored
View File

@@ -16,6 +16,7 @@ BuildRequires: cmake
BuildRequires: desktop-file-utils
BuildRequires: dbus-devel
BuildRequires: file-devel
BuildRequires: fontconfig-devel
BuildRequires: freetype-devel
BuildRequires: fmt-devel
BuildRequires: gcc-c++
@@ -34,7 +35,7 @@ BuildRequires: zlib-devel
BuildRequires: bzip2-devel
BuildRequires: xz-devel
%if 0%{?rhel}
BuildRequires: gcc-toolset-12
BuildRequires: gcc-toolset-14
%endif
Provides: bundled(gnulib)
@@ -70,9 +71,9 @@ rm -rf lib/third_party/{fmt,nlohmann_json,yara}
%build
%if 0%{?rhel}
. /opt/rh/gcc-toolset-12/enable
. /opt/rh/gcc-toolset-14/enable
%set_build_flags
CXXFLAGS+=" -std=gnu++2b"
CXXFLAGS+=" -std=gnu++23"
%endif
%cmake \
-D CMAKE_BUILD_TYPE=Release \
@@ -93,9 +94,9 @@ CXXFLAGS+=" -std=gnu++2b"
%check
%if 0%{?rhel}
. /opt/rh/gcc-toolset-12/enable
. /opt/rh/gcc-toolset-14/enable
%set_build_flags
CXXFLAGS+=" -std=gnu++2b"
CXXFLAGS+=" -std=gnu++23"
%endif
@@ -122,8 +123,11 @@ cp -a lib/third_party/xdgpp/LICENSE %{buildroot
%doc README.md
%{_bindir}/imhex
%{_bindir}/imhex-updater
%{_datadir}/pixmaps/%{name}.png
%{_datadir}/pixmaps/%{name}.svg
%{_datadir}/applications/%{name}.desktop
%{_datadir}/mime/packages/%{name}.xml
%{_libdir}/libimhex.so*
%{_libdir}/%{name}/
%{_libdir}/*.hexpluglib
/usr/lib/debug/%{_libdir}/*.debug
%{_metainfodir}/net.werwolv.%{name}.metainfo.xml

16
dist/web/Dockerfile vendored
View File

@@ -1,11 +1,11 @@
FROM emscripten/emsdk:3.1.51 as build
FROM emscripten/emsdk:3.1.51 AS build
# Used to invalidate layer cache but not mount cache
# See https://github.com/moby/moby/issues/41715#issuecomment-733976493
ARG UNIQUEKEY 1
RUN apt update
RUN apt install -y git ccache autoconf automake libtool cmake pkg-config
RUN apt install -y git ccache autoconf automake libtool cmake pkg-config ninja-build
RUN <<EOF
# Install vcpkg
@@ -27,7 +27,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
' >> /emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake
EOF
ENV VCPKG_DEFAULT_BINARY_CACHE /cache/vcpkg
ENV VCPKG_DEFAULT_BINARY_CACHE=/cache/vcpkg
RUN --mount=type=cache,target=/cache <<EOF
# Install dependencies with vcpkg
set -xe
@@ -45,7 +45,7 @@ EOF
# Build ImHex
ARG JOBS=4
ENV CCACHE_DIR /cache/ccache
ENV CCACHE_DIR=/cache/ccache
RUN mkdir /build
WORKDIR /build
@@ -56,6 +56,7 @@ set -xe
ccache -zs
cmake /imhex \
-G "Ninja" \
-DIMHEX_OFFLINE_BUILD=ON \
-DIMHEX_STATIC_LINK_PLUGINS=ON \
-DIMHEX_EXCLUDE_PLUGINS="script_loader" \
@@ -66,9 +67,10 @@ cmake /imhex
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake \
-DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake \
-DLIBROMFS_COMPRESS_RESOURCES=OFF \
-DCMAKE_BUILD_TYPE=Release
make -j $JOBS
ninja -j $JOBS
cp /imhex/dist/web/source/* /build
ccache -s
@@ -78,7 +80,7 @@ EOF
# See https://stackoverflow.com/questions/41701849/cannot-modify-accept-encoding-with-fetch https://github.com/AnthumChris/fetch-progress-indicators/issues/13
RUN du -b /build/imhex.wasm | cut -f1 > imhex.wasm.size
FROM scratch as raw
FROM scratch AS raw
COPY --from=build [ \
# ImHex \
"/build/imhex.wasm", \
@@ -92,7 +94,7 @@ COPY --from=build [ \
"/build/wasm-config.js", \
"/build/enable-threads.js", \
"/build/favicon.ico", \
"/build/icon.png", \
"/build/icon.svg", \
"/build/manifest.json", \
"/build/robots.txt", \
"/build/sitemap.xml", \

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 KiB

11
dist/web/source/icon.svg vendored Normal file
View File

@@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" version="1">
<rect style="opacity:0.2" width="55" height="10" x="5" y="-60" rx="1.41" transform="rotate(90)"/>
<rect style="fill:#2b50a1" width="55" height="10" x="4" y="-60" rx="1.41" transform="rotate(90)"/>
<rect style="fill:#2b50a1" width="55" height="10" x="4" y="-14" rx="1.41" transform="rotate(90)"/>
<rect style="fill:#2b50a1" width="55" height="10" x="4" y="-33" rx="1.41" transform="rotate(90)"/>
<path style="opacity:0.2" d="M 5.3808594,5 C 4.6158118,5 4,5.6158118 4,6.3808594 V 13.619141 C 4,14.384188 4.6158118,15 5.3808594,15 H 31.619141 C 32.384188,15 33,14.384188 33,13.619141 V 6.3808594 C 33,5.6158118 32.384188,5 31.619141,5 Z M 40.400391,5 C 39.624791,5 39,5.6247906 39,6.4003906 V 13.599609 C 39,14.375209 39.624791,15 40.400391,15 H 58.599609 C 59.375209,15 60,14.375209 60,13.599609 V 6.4003906 C 60,5.6247906 59.375209,5 58.599609,5 Z M 5.3808594,50 C 4.6158118,50 4,50.615812 4,51.380859 v 7.238282 C 4,59.384188 4.6158118,60 5.3808594,60 H 31.619141 C 32.384188,60 33,59.384188 33,58.619141 V 51.380859 C 33,50.615812 32.384188,50 31.619141,50 Z"/>
<rect style="fill:#3a6be0" width="29" height="10" x="4" y="4" rx="1.381"/>
<rect style="fill:#3a6be0" width="21" height="10" x="39" y="4" rx="1.4"/>
<rect style="fill:#3a6be0" width="29" height="10" x="4" y="49" rx="1.381"/>
<path style="fill:#ffffff;opacity:0.1" d="M 5.3808594 4 C 4.6158118 4 4 4.6158118 4 5.3808594 L 4 6.3808594 C 4 5.6158118 4.6158118 5 5.3808594 5 L 31.619141 5 C 32.384188 5 33 5.6158118 33 6.3808594 L 33 5.3808594 C 33 4.6158118 32.384188 4 31.619141 4 L 5.3808594 4 z M 40.400391 4 C 39.624791 4 39 4.6247906 39 5.4003906 L 39 6.4003906 C 39 5.6247906 39.624791 5 40.400391 5 L 58.599609 5 C 59.375209 5 60 5.6247906 60 6.4003906 L 60 5.4003906 C 60 4.6247906 59.375209 4 58.599609 4 L 40.400391 4 z M 5.3808594 49 C 4.6158118 49 4 49.615812 4 50.380859 L 4 51.380859 C 4 50.615812 4.6158118 50 5.3808594 50 L 31.619141 50 C 32.384188 50 33 50.615812 33 51.380859 L 33 50.380859 C 33 49.615812 32.384188 49 31.619141 49 L 5.3808594 49 z"/>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -11,7 +11,7 @@
<meta name="title" content="ImHex">
<meta name="description" content="Free and extremely powerful Online Hex Editor for your Web Browser. ImHex is a free and open source Hex Editor for Reverse Engineers and Developers and Data Analysts.">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="apple-touch-icon" href="icon.png">
<link rel="apple-touch-icon" href="icon.svg">
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website">
@@ -38,7 +38,7 @@
"founder": "WerWolv",
"slogan": "A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.",
"url": "https://imhex.werwolv.net",
"logo": "https://imhex.werwolv.net/assets/logos/logo.png"
"logo": "https://imhex.werwolv.net/assets/logos/logo.svg"
}
</script>

View File

@@ -10,8 +10,8 @@
],
"icons": [
{
"src": "icon.png",
"type": "image/png",
"src": "icon.svg",
"type": "image/svg",
"sizes": "640x640"
}
],

View File

@@ -261,4 +261,11 @@ function js_resizeCanvas() {
canvas.left = document.documentElement.clientLeft;
canvas.width = Math.min(document.documentElement.clientWidth, window.innerWidth || 0);
canvas.height = Math.min(document.documentElement.clientHeight, window.innerHeight || 0);
}
}
// Prevent some default browser shortcuts from preventing ImHex ones to work
document.addEventListener('keydown', e => {
if (e.ctrlKey) {
if (e.which == 83) e.preventDefault();
}
})

1
lib/external/disassembler vendored Submodule

View File

@@ -38,6 +38,7 @@ set(LIBIMHEX_SOURCES
source/helpers/debugging.cpp
source/helpers/default_paths.cpp
source/helpers/imgui_hooks.cpp
source/helpers/semantic_version.cpp
source/test/tests.cpp
@@ -49,6 +50,7 @@ set(LIBIMHEX_SOURCES
source/ui/view.cpp
source/ui/popup.cpp
source/ui/toast.cpp
source/ui/banner.cpp
source/subcommands/subcommands.cpp
)
@@ -133,13 +135,14 @@ if (NOT IMHEX_EXTERNAL_PLUGIN_BUILD)
if (WIN32)
set_target_properties(libimhex PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
target_link_options(libimhex PRIVATE -Wl,--export-all-symbols)
target_link_libraries(libimhex PRIVATE Netapi32.lib)
elseif (APPLE)
find_library(FOUNDATION NAMES Foundation)
target_link_libraries(libimhex PUBLIC ${FOUNDATION})
endif ()
target_link_libraries(libimhex PRIVATE microtar libwolv ${NFD_LIBRARIES} magic dl ${JTHREAD_LIBRARIES})
target_link_libraries(libimhex PUBLIC libpl ${IMGUI_LIBRARIES})
target_link_libraries(libimhex PRIVATE microtar libwolv ${NFD_LIBRARIES} magic dl)
target_link_libraries(libimhex PUBLIC libpl ${IMGUI_LIBRARIES} ${JTHREAD_LIBRARIES})
precompileHeaders(libimhex "${CMAKE_CURRENT_SOURCE_DIR}/include")
endif()

View File

@@ -1,4 +1,3 @@
#pragma once
#include <hex/helpers/types.hpp>
#include <hex/helpers/intrinsics.hpp>

View File

@@ -295,6 +295,7 @@ namespace hex {
};
class AchievementManager {
static bool s_initialized;
public:
AchievementManager() = delete;

View File

@@ -2,10 +2,10 @@
#include <hex.hpp>
#include <hex/api/localization_manager.hpp>
#include <hex/api/shortcut_manager.hpp>
#include <hex/helpers/concepts.hpp>
#include <functional>
#include <map>
#include <mutex>
#include <span>
#include <string>
@@ -20,11 +20,11 @@ using ImGuiDataType = int;
using ImGuiInputTextFlags = int;
struct ImColor;
enum ImGuiCustomCol : int;
typedef int ImGuiColorEditFlags;
namespace hex {
class View;
class Shortcut;
class Task;
namespace dp {
@@ -44,7 +44,6 @@ namespace hex {
plugins when needed.
*/
namespace ContentRegistry {
/* Settings Registry. Allows adding of new entries into the ImHex preferences window. */
namespace Settings {
@@ -178,7 +177,7 @@ namespace hex {
class SliderDataSize : public Widget {
public:
SliderDataSize(u64 defaultValue, u64 min, u64 max) : m_value(defaultValue), m_min(min), m_max(max) { }
SliderDataSize(u64 defaultValue, u64 min, u64 max, u64 stepSize) : m_value(defaultValue), m_min(min), m_max(max), m_stepSize(stepSize) { }
bool draw(const std::string &name) override;
void load(const nlohmann::json &data) override;
@@ -189,11 +188,12 @@ namespace hex {
protected:
u64 m_value;
u64 m_min, m_max;
u64 m_stepSize;
};
class ColorPicker : public Widget {
public:
explicit ColorPicker(ImColor defaultColor);
explicit ColorPicker(ImColor defaultColor, ImGuiColorEditFlags flags = 0);
bool draw(const std::string &name) override;
@@ -203,12 +203,14 @@ namespace hex {
[[nodiscard]] ImColor getColor() const;
protected:
std::array<float, 4> m_value{};
std::array<float, 4> m_value = {}, m_defaultValue = {};
ImGuiColorEditFlags m_flags;
};
class DropDown : public Widget {
public:
explicit DropDown(const std::vector<std::string> &items, const std::vector<nlohmann::json> &settingsValues, const nlohmann::json &defaultItem) : m_items(items), m_settingsValues(settingsValues), m_defaultItem(defaultItem) { }
explicit DropDown(const std::vector<std::string> &items, const std::vector<nlohmann::json> &settingsValues, const nlohmann::json &defaultItem) : m_items(items.begin(), items.end()), m_settingsValues(settingsValues), m_defaultItem(defaultItem) { }
explicit DropDown(const std::vector<UnlocalizedString> &items, const std::vector<nlohmann::json> &settingsValues, const nlohmann::json &defaultItem) : m_items(items), m_settingsValues(settingsValues), m_defaultItem(defaultItem) { }
bool draw(const std::string &name) override;
@@ -219,7 +221,7 @@ namespace hex {
const nlohmann::json& getValue() const;
protected:
std::vector<std::string> m_items;
std::vector<UnlocalizedString> m_items;
std::vector<nlohmann::json> m_settingsValues;
nlohmann::json m_defaultItem;
@@ -381,7 +383,7 @@ namespace hex {
};
using DisplayCallback = std::function<std::string(std::string)>;
using ExecuteCallback = std::function<void(std::string)>;
using ExecuteCallback = std::function<std::optional<std::string>(std::string)>;
using QueryCallback = std::function<std::vector<QueryResult>(std::string)>;
struct Entry {
@@ -417,7 +419,7 @@ namespace hex {
const std::string &command,
const UnlocalizedString &unlocalizedDescription,
const impl::DisplayCallback &displayCallback,
const impl::ExecuteCallback &executeCallback = [](auto) {});
const impl::ExecuteCallback &executeCallback = [](auto) { return std::nullopt; });
/**
* @brief Adds a new command handler to the command palette
@@ -438,7 +440,7 @@ namespace hex {
namespace impl {
using VisualizerFunctionCallback = std::function<void(pl::ptrn::Pattern&, pl::ptrn::IIterable&, bool, std::span<const pl::core::Token::Literal>)>;
using VisualizerFunctionCallback = std::function<void(pl::ptrn::Pattern&, bool, std::span<const pl::core::Token::Literal>)>;
struct FunctionDefinition {
pl::api::Namespace ns;
@@ -450,6 +452,14 @@ namespace hex {
bool dangerous;
};
struct TypeDefinition {
pl::api::Namespace ns;
std::string name;
pl::api::FunctionParameterCount parameterCount;
pl::api::TypeCallback callback;
};
struct Visualizer {
pl::api::FunctionParameterCount parameterCount;
VisualizerFunctionCallback callback;
@@ -459,6 +469,7 @@ namespace hex {
const std::map<std::string, Visualizer>& getInlineVisualizers();
const std::map<std::string, pl::api::PragmaHandler>& getPragmas();
const std::vector<FunctionDefinition>& getFunctions();
const std::vector<TypeDefinition>& getTypes();
}
@@ -517,6 +528,20 @@ namespace hex {
const pl::api::FunctionCallback &func
);
/**
* @brief Adds a new type to the pattern language
* @param ns The namespace of the type
* @param name The name of the type
* @param parameterCount The amount of non-type template parameters the type takes
* @param func The type callback
*/
void addType(
const pl::api::Namespace &ns,
const std::string &name,
pl::api::FunctionParameterCount parameterCount,
const pl::api::TypeCallback &func
);
/**
* @brief Adds a new visualizer to the pattern language
* @note Visualizers are extensions to the [[hex::visualize]] attribute, used to visualize data
@@ -601,8 +626,7 @@ namespace hex {
/* Data Inspector Registry. Allows adding of new types to the data inspector */
namespace DataInspector {
enum class NumberDisplayStyle
{
enum class NumberDisplayStyle : u8 {
Decimal,
Hexadecimal,
Octal
@@ -656,6 +680,13 @@ namespace hex {
std::optional<impl::EditingFunction> editingFunction = std::nullopt
);
/**
* @brief Allows adding new menu items to data inspector row context menus. Call this function inside the
* draw function of the data inspector row definition.
* @param function Callback that will draw menu items
*/
void drawMenuItems(const std::function<void()> &function);
}
/* Data Processor Node Registry. Allows adding new processor nodes to be used in the data processor */
@@ -748,7 +779,7 @@ namespace hex {
struct MenuItem {
std::vector<UnlocalizedString> unlocalizedNames;
Icon icon;
std::unique_ptr<Shortcut> shortcut;
Shortcut shortcut;
View *view;
MenuCallback callback;
EnabledCallback enabledCallback;
@@ -986,7 +1017,7 @@ namespace hex {
namespace impl {
using Callback = std::function<std::string(prv::Provider *provider, u64 address, size_t size)>;
using Callback = std::function<std::string(prv::Provider *provider, u64 address, size_t size, bool preview)>;
struct ExportMenuEntry {
UnlocalizedString unlocalizedName;
Callback callback;
@@ -994,7 +1025,7 @@ namespace hex {
struct FindOccurrence {
Region region;
enum class DecodeType { ASCII, Binary, UTF16, Unsigned, Signed, Float, Double } decodeType;
enum class DecodeType { ASCII, UTF8, Binary, UTF16, Unsigned, Signed, Float, Double } decodeType;
std::endian endian = std::endian::native;
bool selected;
};
@@ -1273,7 +1304,7 @@ namespace hex {
void stopServices();
}
void registerService(const UnlocalizedString &unlocalizedName, const impl::Callback &callback);
void registerService(const UnlocalizedString &unlocalizedString, const impl::Callback &callback);
}
/* Network Communication Interface Registry. Allows adding new communication interface endpoints */
@@ -1332,6 +1363,7 @@ namespace hex {
}
/* Data Information Registry. Allows adding new analyzers to the data information view */
namespace DataInformation {
class InformationSection {
@@ -1398,6 +1430,54 @@ namespace hex {
}
/* Disassembler Registry. Allows adding new disassembler architectures */
namespace Disassembler {
struct Instruction {
u64 address;
u64 offset;
size_t size;
std::string bytes;
std::string mnemonic;
std::string operators;
};
class Architecture {
public:
explicit Architecture(std::string name) : m_name(std::move(name)) {}
virtual ~Architecture() = default;
virtual bool start() = 0;
virtual void end() = 0;
virtual std::optional<Instruction> disassemble(u64 imageBaseAddress, u64 instructionLoadAddress, u64 instructionDataAddress, std::span<const u8> code) = 0;
virtual void drawSettings() = 0;
[[nodiscard]] const std::string& getName() const { return m_name; }
private:
std::string m_name;
};
namespace impl {
using CreatorFunction = std::function<std::unique_ptr<Architecture>()>;
void addArchitectureCreator(CreatorFunction function);
const std::map<std::string, CreatorFunction>& getArchitectures();
}
template<std::derived_from<Architecture> T>
void add(auto && ...args) {
impl::addArchitectureCreator([...args = std::move(args)] {
return std::make_unique<T>(args...);
});
}
}
}
}

View File

@@ -31,15 +31,6 @@
#define EVENT_DEF_NO_LOG(event_name, ...) EVENT_DEF_IMPL(event_name, #event_name, false, __VA_ARGS__)
/* Forward declarations */
struct GLFWwindow;
namespace hex {
class Achievement;
class View;
}
namespace pl::ptrn { class Pattern; }
namespace hex {
namespace impl {
@@ -99,7 +90,8 @@ namespace hex {
/**
* @brief The EventManager allows subscribing to and posting events to different parts of the program.
* To create a new event, use the EVENT_DEF macro. This will create a new event type with the given name and parameters
* To create a new event, use the EVENT_DEF macro. This will create a new event type with the given name and parameters.
* Events should be created in an `events_*.hpp` category file under the `events` folder, and never directly here.
*/
class EventManager {
public:
@@ -129,15 +121,9 @@ namespace hex {
static void subscribe(void *token, typename E::Callback function) {
std::scoped_lock lock(getEventMutex());
if (getTokenStore().contains(token)) {
auto&& [begin, end] = getTokenStore().equal_range(token);
const auto eventRegistered = std::any_of(begin, end, [&](auto &item) {
return item.second->first == E::Id;
});
if (eventRegistered) {
log::fatal("The token '{}' has already registered the same event ('{}')", token, wolv::type::getTypeName<E>());
return;
}
if (isAlreadyRegistered(token, E::Id)) {
log::fatal("The token '{}' has already registered the same event ('{}')", token, wolv::type::getTypeName<E>());
return;
}
getTokenStore().insert({ token, subscribe<E>(function) });
@@ -162,16 +148,7 @@ namespace hex {
static void unsubscribe(void *token) noexcept {
std::scoped_lock lock(getEventMutex());
auto &tokenStore = getTokenStore();
auto iter = std::find_if(tokenStore.begin(), tokenStore.end(), [&](auto &item) {
return item.first == token && item.second->first == E::Id;
});
if (iter != tokenStore.end()) {
getEvents().erase(iter->second);
tokenStore.erase(iter);
}
unsubscribe(token, E::Id);
}
/**
@@ -209,118 +186,9 @@ namespace hex {
static std::multimap<void *, EventList::iterator>& getTokenStore();
static EventList& getEvents();
static std::recursive_mutex& getEventMutex();
static bool isAlreadyRegistered(void *token, impl::EventId id);
static void unsubscribe(void *token, impl::EventId id);
};
/* Default Events */
/**
* @brief Called when Imhex finished startup, and will enter the main window rendering loop
*/
EVENT_DEF(EventImHexStartupFinished);
EVENT_DEF(EventFileLoaded, std::fs::path);
EVENT_DEF(EventDataChanged, prv::Provider *);
EVENT_DEF(EventHighlightingChanged);
EVENT_DEF(EventWindowClosing, GLFWwindow *);
EVENT_DEF(EventRegionSelected, ImHexApi::HexEditor::ProviderRegion);
EVENT_DEF(EventAbnormalTermination, int);
EVENT_DEF(EventThemeChanged);
EVENT_DEF(EventOSThemeChanged);
EVENT_DEF(EventWindowFocused, bool);
/**
* @brief Called when the provider is created.
* This event is responsible for (optionally) initializing the provider and calling EventProviderOpened
* (although the event can also be called manually without problem)
*/
EVENT_DEF(EventProviderCreated, prv::Provider *);
EVENT_DEF(EventProviderChanged, prv::Provider *, prv::Provider *);
/**
* @brief Called as a continuation of EventProviderCreated
* this event is normally called immediately after EventProviderCreated successfully initialized the provider.
* If no initialization (Provider::skipLoadInterface() has been set), this event should be called manually
* If skipLoadInterface failed, this event is not called
*
* @note this is not related to Provider::open()
*/
EVENT_DEF(EventProviderOpened, prv::Provider *);
EVENT_DEF(EventProviderClosing, prv::Provider *, bool *);
EVENT_DEF(EventProviderClosed, prv::Provider *);
EVENT_DEF(EventProviderDeleted, prv::Provider *);
EVENT_DEF(EventProviderSaved, prv::Provider *);
EVENT_DEF(EventWindowInitialized);
EVENT_DEF(EventWindowDeinitializing, GLFWwindow *);
EVENT_DEF(EventBookmarkCreated, ImHexApi::Bookmarks::Entry&);
EVENT_DEF(EventPatchCreated, u64, u8, u8);
EVENT_DEF(EventPatternEvaluating);
EVENT_DEF(EventPatternExecuted, const std::string&);
EVENT_DEF(EventPatternEditorChanged, const std::string&);
EVENT_DEF(EventStoreContentDownloaded, const std::fs::path&);
EVENT_DEF(EventStoreContentRemoved, const std::fs::path&);
EVENT_DEF(EventImHexClosing);
EVENT_DEF(EventAchievementUnlocked, const Achievement&);
EVENT_DEF(EventSearchBoxClicked, u32);
EVENT_DEF(EventViewOpened, View*);
EVENT_DEF(EventFirstLaunch);
EVENT_DEF(EventFileDragged, bool);
EVENT_DEF(EventFileDropped, std::fs::path);
EVENT_DEF(EventProviderDataModified, prv::Provider *, u64, u64, const u8*);
EVENT_DEF(EventProviderDataInserted, prv::Provider *, u64, u64);
EVENT_DEF(EventProviderDataRemoved, prv::Provider *, u64, u64);
EVENT_DEF(EventProviderDirtied, prv::Provider *);
/**
* @brief Called when a project has been loaded
*/
EVENT_DEF(EventProjectOpened);
EVENT_DEF_NO_LOG(EventFrameBegin);
EVENT_DEF_NO_LOG(EventFrameEnd);
EVENT_DEF_NO_LOG(EventSetTaskBarIconState, u32, u32, u32);
EVENT_DEF_NO_LOG(EventImGuiElementRendered, ImGuiID, const std::array<float, 4>&);
EVENT_DEF(RequestAddInitTask, std::string, bool, std::function<bool()>);
EVENT_DEF(RequestAddExitTask, std::string, std::function<bool()>);
EVENT_DEF(RequestOpenWindow, std::string);
EVENT_DEF(RequestHexEditorSelectionChange, Region);
EVENT_DEF(RequestPatternEditorSelectionChange, u32, u32);
EVENT_DEF(RequestJumpToPattern, const pl::ptrn::Pattern*);
EVENT_DEF(RequestAddBookmark, Region, std::string, std::string, color_t, u64*);
EVENT_DEF(RequestRemoveBookmark, u64);
EVENT_DEF(RequestSetPatternLanguageCode, std::string);
EVENT_DEF(RequestRunPatternCode);
EVENT_DEF(RequestLoadPatternLanguageFile, std::fs::path);
EVENT_DEF(RequestSavePatternLanguageFile, std::fs::path);
EVENT_DEF(RequestUpdateWindowTitle);
EVENT_DEF(RequestCloseImHex, bool);
EVENT_DEF(RequestRestartImHex);
EVENT_DEF(RequestOpenFile, std::fs::path);
EVENT_DEF(RequestChangeTheme, std::string);
EVENT_DEF(RequestOpenPopup, std::string);
EVENT_DEF(RequestAddVirtualFile, std::fs::path, std::vector<u8>, Region);
/**
* @brief Creates a provider from it's unlocalized name, and add it to the provider list
*/
EVENT_DEF(RequestCreateProvider, std::string, bool, bool, hex::prv::Provider **);
EVENT_DEF(RequestInitThemeHandlers);
/**
* @brief Send an event to the main Imhex instance
*/
EVENT_DEF(SendMessageToMainInstance, const std::string, const std::vector<u8>&);
/**
* Move the data from all PerProvider instances from one provider to another.
* The 'from' provider should not have any per provider data after this, and should be immediately deleted
*/
EVENT_DEF(MovePerProviderData, prv::Provider *, prv::Provider *);
/**
* Called when ImHex managed to catch an error in a general try/catch to prevent/recover from a crash
*/
EVENT_DEF(EventCrashRecovered, const std::exception &);
}

View File

@@ -0,0 +1,120 @@
#pragma once
#include <hex/api/event_manager.hpp>
/* Forward declarations */
struct GLFWwindow;
namespace hex { class View; }
/* GUI events definitions */
namespace hex {
/**
* @brief Signals a newly opened window
*
* This event is sent when the window has just been opened and docked by the Window manager.
*
* FIXME: In the event that a newly created window is already docked, this will not be sent.
*
* FIXME: This is currently only used for the introduction tutorial.
* If the event's only purpose is this, maybe rename it?
*
* @param view the new view reference
*/
EVENT_DEF(EventViewOpened, View*);
/**
* @brief Signals a change in the DPI scale.
*
* This event is called once at startup to signal native scale definition (by passing the same value twice).
* On Windows OS, this event can also be posted if the window DPI has been changed.
*
* @param oldScale the old scale
* @param newScale the current scale that's now in use
*/
EVENT_DEF(EventDPIChanged, float, float);
/**
* @brief Signals the focus of the ImHex main window.
*
* This is directly tied as a GLFW window focus callback, and will be called accordingly when GLFW detects
* a change in focus.
*
* @param isFocused true if the window is focused
*/
EVENT_DEF(EventWindowFocused, bool);
/**
* @brief Signals a window being closed.
*
* Allows reactive clean up of running tasks, and prevents ImHex from closing
* by displaying an exit confirmation popup.
*
* @param window The window reference
*/
EVENT_DEF(EventWindowClosing, GLFWwindow*);
/**
* @brief Informs that the main window is initialized
*
* On Windows OS, it is used to initialize system theme, if ImHex's theme is following it.
*
* FIXME: Change event name to reflect Theme detection, if it's only used for that purpose?
*/
EVENT_DEF(EventWindowInitialized);
/**
* @brief Informs that the main window is deinitializing
*
* Allows for lifecycle cleanup before ImHex shutdown.
*
* @param window The window reference
*/
EVENT_DEF(EventWindowDeinitializing, GLFWwindow*);
/**
* @brief Signals a theme change in the host OS
*
* Allows ImHex to react to OS theme changes dynamically during execution.
*/
EVENT_DEF(EventOSThemeChanged);
}
/* silent (no-logging) GUI events definitions */
namespace hex {
/**
* @brief Signals the start of a new ImGui frame
*/
EVENT_DEF_NO_LOG(EventFrameBegin);
/**
* @brief Signals the end of an ImGui frame
*/
EVENT_DEF_NO_LOG(EventFrameEnd);
/**
* @brief Windows OS: Sets the taskbar icon state
*
* This event is used on Windows OS to display progress through the taskbar icon (the famous "green loading bar"
* in the taskbar).
*
* @param progressState the progress state (converted from the TaskProgressState enum)
* @param progressType the type of progress (converted from the TaskProgressType enum)
* @param percentage actual progress percentage (expected from 0 to 100)
*
* @see hex::ImHexApi::System::TaskProgressState
* @see hex::ImHexApi::System::TaskProgressType
*/
EVENT_DEF_NO_LOG(EventSetTaskBarIconState, u32, u32, u32);
/**
* @brief Informs of an ImGui element being rendered
*
* @param elementId the element's ID
* @param boundingBox the bounding box (composed of 4 floats)
*/
EVENT_DEF_NO_LOG(EventImGuiElementRendered, ImGuiID, const std::array<float, 4>&);
}

View File

@@ -0,0 +1,158 @@
#pragma once
#include <hex/api/event_manager.hpp>
#include <hex/helpers/patches.hpp>
/* Forward declarations */
namespace hex { class Achievement; }
/* Interaction events definitions */
namespace hex {
/**
* @brief Signals a file was loaded
*
* FIXME: this event is unused and should be scrapped.
*
* @param path the loaded file's path
*/
EVENT_DEF(EventFileLoaded, std::fs::path);
/**
* @brief Signals a change in the current data
*
* Enables provider reaction to data change, especially the data inspector.
*
* This is caused by the following:
* - an explicit provider reload, requested by the user (Ctrl+R)
* - any user action that results in the creation of an "undo" stack action (generally a data modification)
*
* @param provider the Provider subject to the data change
*/
EVENT_DEF(EventDataChanged, prv::Provider *);
/**
* @brief Signals a change in highlighting
*
* The event's only purpose is for the Hex editor to clear highlights when receiving this event.
*/
EVENT_DEF(EventHighlightingChanged);
/**
* @brief Informs of a provider region being selected
*
* This is very generally used to signal user actions that select a specific region within the provider.
* It is also used to pass on regions when the provider changes.
*
* @param providerRegion the provider-aware region being selected
*/
EVENT_DEF(EventRegionSelected, ImHexApi::HexEditor::ProviderRegion);
/**
* @brief Signals a theme change
*
* On Windows OS, this is used to reflect the theme color onto the window frame.
*/
EVENT_DEF(EventThemeChanged);
/**
* @brief Signals that a bookmark was created
*
* For now, this event's only purpose is to unlock an achievement.
*
* @param entry the new bookmark
*/
EVENT_DEF(EventBookmarkCreated, ImHexApi::Bookmarks::Entry&);
/**
* @brief Called upon creation of an IPS patch.
* As for now, the event only serves a purpose for the achievement unlock.
*
* @param data the pointer to the patch content's start
* @param size the patch data size
* @param kind the patch's kind
*/
EVENT_DEF(EventPatchCreated, const u8*, u64, const PatchKind);
/**
* @brief Signals the beginning of evaluation of the current pattern
*
* This allows resetting the drawer view for the pattern data while we wait for the execution completion.
*/
EVENT_DEF(EventPatternEvaluating);
/**
* @brief Signals the completion of the pattern evaluation
*
* This causes another reset in the drawer view, to refresh the table displayed to the user.
*
* @param code the execution's status code
*/
EVENT_DEF(EventPatternExecuted, const std::string&);
/**
* @brief Denotes when pattern editor has changed
*
* FIXME: this event is unused and should be scrapped.
*/
EVENT_DEF(EventPatternEditorChanged, const std::string&);
/**
* @brief Signals that a Content Store item was downloaded
*
* FIXME: this event is unused and should be scrapped.
*
* @param path the item's path on the filesystem
*/
EVENT_DEF(EventStoreContentDownloaded, const std::fs::path&);
/**
* @brief Signals the removal of a Content Store item
*
* Note: at the time of the event firing, the item has already been removed from the filesystem.
*
* FIXME: this event is unused and should be scrapped.
*
* @param path the item's old file path where it used to be in the filesystem
*/
EVENT_DEF(EventStoreContentRemoved, const std::fs::path&);
/**
* @brief Signals the unlocking of an achievement
*
* This is used by the achievement manager to refresh the achievement display, as well as store progress to
* the appropriate storage file.
*
* @param achievement the achievement that was unlocked
*/
EVENT_DEF(EventAchievementUnlocked, const Achievement&);
/**
* @brief Signals a click on the search box
*
* As there are different behaviours depending on the click (left or right) done by the user,
* this allows the consequences of said click to be registered in their own components.
*
* @param button the ImGuiMouseButton's value
*/
EVENT_DEF(EventSearchBoxClicked, u32);
/**
* @brief Updates on whether a file is being dragged into ImHex
*
* Allows ImGUi to display a file dragging information on screen when a file is being dragged.
*
* @param isFileDragged true if a file is being dragged
*/
EVENT_DEF(EventFileDragged, bool);
/**
* @brief Triggers loading when a file is dropped
*
* The event fires when a file is dropped into ImHex, which passes it to file handlers to load it.
*
* @param path the dropped file's path
*/
EVENT_DEF(EventFileDropped, std::fs::path);
}

View File

@@ -0,0 +1,72 @@
#pragma once
#include <hex/api/event_manager.hpp>
/* Lifecycle events definitions */
namespace hex {
/**
* @brief Called when Imhex finished startup, and will enter the main window rendering loop
*/
EVENT_DEF(EventImHexStartupFinished);
/**
* @brief Called when ImHex is closing, to trigger the last shutdown hooks
*
* This is the last event to fire before complete graceful shutdown.
*/
EVENT_DEF(EventImHexClosing);
/**
* @brief Signals that it's ImHex first launch ever
*
* This event allows for the launch of the ImHex tutorial (also called Out of Box experience).
*/
EVENT_DEF(EventFirstLaunch);
/**
* FIXME: this event is unused and should be scrapped.
*/
EVENT_DEF(EventAnySettingChanged);
/**
* @brief Ensures correct plugin cleanup on crash
*
* This event is fired when catching an unexpected error that cannot be recovered and
* which forces Imhex to close immediately.
*
* Subscribing to this event ensures that the plugin can correctly clean up any mission-critical tasks
* before forceful shutdown.
*
* @param signal the POSIX signal code
*/
EVENT_DEF(EventAbnormalTermination, int);
/**
* @brief Informs of the ImHex versions (and difference, if any)
*
* Called on every startup to inform subscribers of the two versions picked up:
* - the version of the previous launch, gathered from the settings file
* - the current version, gathered directly from C++ code
*
* In most cases, and unless ImHex was updated, the two parameters will be the same.
*
* FIXME: Maybe rename the event to signal a startup information, instead of the misleading
* title that the event could be fired when ImHex detects that it was updated since last launch?
*
* @param previousLaunchVersion ImHex's version during the previous launch
* @param currentVersion ImHex's current version for this startup
*/
EVENT_DEF(EventImHexUpdated, SemanticVersion, SemanticVersion);
/**
* @brief Called when ImHex managed to catch an error in a general try/catch to prevent/recover from a crash
*/
EVENT_DEF(EventCrashRecovered, const std::exception &);
/**
* @brief Called when a project has been loaded
*/
EVENT_DEF(EventProjectOpened);
}

View File

@@ -0,0 +1,113 @@
#pragma once
#include <hex.hpp>
#include <hex/api/event_manager.hpp>
/* Provider events definitions */
namespace hex {
/**
* @brief Called when the provider is created.
* This event is responsible for (optionally) initializing the provider and calling EventProviderOpened
* (although the event can also be called manually without problem)
*/
EVENT_DEF(EventProviderCreated, prv::Provider *);
/**
* @brief Called as a continuation of EventProviderCreated
* this event is normally called immediately after EventProviderCreated successfully initialized the provider.
* If no initialization (Provider::skipLoadInterface() has been set), this event should be called manually
* If skipLoadInterface failed, this event is not called
*
* @note this is not related to Provider::open()
*/
EVENT_DEF(EventProviderOpened, prv::Provider *);
/**
* @brief Signals a change in provider (in-place)
*
* Note: if the provider was deleted, the new ("current") provider will be `nullptr`
*
* @param oldProvider the old provider
* @param currentProvider the current provider
*/
EVENT_DEF(EventProviderChanged, prv::Provider *, prv::Provider *);
/**
* @brief Signals that a provider was saved
*
* @param provider the saved provider
*/
EVENT_DEF(EventProviderSaved, prv::Provider *);
/**
* @brief Signals a provider is closing
*
* FIXME: as for now, this behaves as a request more than an event. Also, the boolean is always set to true,
* and serves no purpose. This should be moved into the Provider requests section and declared accordingly.
*
* @param provider the closing provider
* @param shouldClose whether the provider should close
*/
EVENT_DEF(EventProviderClosing, prv::Provider *, bool *);
/**
* @brief Signals that a provider was closed
*
* As this is a closure information broadcast, the provider should generally not be accessed, as it could
* result in problems.
*
* @param provider the now-closed provider
*/
EVENT_DEF(EventProviderClosed, prv::Provider *);
/**
* @brief Signals that a provider is being deleted
*
* Provider's data should not be accessed.
*
* @param provider the provider
*/
EVENT_DEF(EventProviderDeleted, prv::Provider *);
}
/* Provider data events definitions */
namespace hex {
/**
* @brief Signals the dirtying of a provider
*
* Any data modification that occurs in a provider dirties it, until its state is either saved or restored.
* This event signals that fact to subscribers so additional code can be executed for certain cases.
*/
EVENT_DEF(EventProviderDirtied, prv::Provider *);
/**
* @brief Signals an insertion of new data into a provider
*
* @param provider the provider
* @param offset the start of the insertion
* @param size the new data's size
*/
EVENT_DEF(EventProviderDataInserted, prv::Provider *, u64, u64);
/**
* @brief Signals a modification in the provider's data
*
* @param provider the provider
* @param offset the data modification's offset (start address)
* @param size the buffer's size
* @param buffer the modified data written at this address
*/
EVENT_DEF(EventProviderDataModified, prv::Provider *, u64, u64, const u8*);
/**
* @brief Signals a removal of some of the provider's data
*
* @param provider the provider
* @param offset the deletion offset (start address)
* @param size the deleted data's size
*/
EVENT_DEF(EventProviderDataRemoved, prv::Provider *, u64, u64);
}

View File

@@ -0,0 +1,37 @@
#pragma once
#include <hex/api/event_manager.hpp>
/* GUI requests definitions */
namespace hex {
/**
* @brief Requests the opening of a new window.
*
* @param name the window's name
*/
EVENT_DEF(RequestOpenWindow, std::string);
/**
* @brief Centralized request to update ImHex's main window title
*
* This request can be called to make ImHex refresh its main window title, taking into account a new project
* or file opened/closed.
*/
EVENT_DEF(RequestUpdateWindowTitle);
/**
* @brief Requests a theme type (light or dark) change
*
* @param themeType either `Light` or `Dark`
*/
EVENT_DEF(RequestChangeTheme, std::string);
/**
* @brief Requests the opening of a popup
*
* @param name the popup's name
*/
EVENT_DEF(RequestOpenPopup, std::string);
}

View File

@@ -0,0 +1,116 @@
#pragma once
#include <hex.hpp>
#include <hex/api/event_manager.hpp>
/* Forward declarations */
namespace pl::ptrn { class Pattern; }
/* Interaction requests definitions */
namespace hex {
/**
* @brief Requests a selection change in the Hex editor
*
* This request is handled by the Hex editor, which proceeds to check if the selection is valid.
* If it is invalid, the Hex editor fires the `EventRegionSelected` event with nullptr region info.
*
* @param region the region that should be selected
*/
EVENT_DEF(RequestHexEditorSelectionChange, Region);
/**
* @brief Requests the Pattern editor to move selection
*
* Requests the Pattern editor to move the cursor's position to reflect the user's click or movement.
*
* @param line the target line
* @param column the target column
*/
EVENT_DEF(RequestPatternEditorSelectionChange, u32, u32);
/**
* @brief Requests a jump to a given pattern
*
* This request is fired by the Hex editor when the user asks to jump to the pattern.
* It is then caught and reflected by the Pattern data component.
*
* @param pattern the pattern to jump to
*/
EVENT_DEF(RequestJumpToPattern, const pl::ptrn::Pattern*);
/**
* @brief Requests to add a bookmark
*
* @param region the region to be bookmarked
* @param name the bookmark's name
* @param comment a comment
* @param color the color
* @param id the bookmark's unique ID
*/
EVENT_DEF(RequestAddBookmark, Region, std::string, std::string, color_t, u64*);
/**
* @brief Requests a bookmark removal
*
* @param id the bookmark's unique ID
*/
EVENT_DEF(RequestRemoveBookmark, u64);
/**
* @brief Request the Pattern editor to set its code
*
* This request allows the rest of ImHex to interface with the Pattern editor component, by setting its code.
* This allows for `.hexpat` file loading, and more.
*
* @param code the code's string
*/
EVENT_DEF(RequestSetPatternLanguageCode, std::string);
/**
* @brief Requests the Pattern editor to run the current code
*
* This is only ever used in the introduction tutorial.
*
* FIXME: the name is misleading, as for now this activates the pattern's auto-evaluation rather than a
* one-off execution
*/
EVENT_DEF(RequestRunPatternCode);
/**
* @brief Request to load a pattern language file
*
* FIXME: this request is unused, as now another component is responsible for pattern file loading.
* This request should be scrapped.
*
* @param path the pattern file's path
*/
EVENT_DEF(RequestLoadPatternLanguageFile, std::fs::path);
/**
* @brief Request to save a pattern language file
*
* FIXME: this request is unused, as now another component is responsible for pattern file saving.
* This request should be scrapped.
*
* @param path the pattern file's path
*/
EVENT_DEF(RequestSavePatternLanguageFile, std::fs::path);
/**
* @brief Requests ImHex to open and process a file
*
* @param path the file's path
*/
EVENT_DEF(RequestOpenFile, std::fs::path);
/**
* @brief Adds a virtual file in the Pattern editor
*
* @param path the file's path
* @param data the file's data
* @param region the impacted region
*/
EVENT_DEF(RequestAddVirtualFile, std::fs::path, std::vector<u8>, Region);
}

View File

@@ -0,0 +1,84 @@
#pragma once
#include <hex.hpp>
#include <hex/api/event_manager.hpp>
/* Lifecycle requests definitions */
namespace hex {
/**
* @brief Emit a request to add an initialization task to the list
*
* These tasks will be executed at startup.
*
* @param name Name of the init task
* @param isAsync Whether the task is asynchronous (true if yes)
* @param callbackFunction The function to call to execute the task
*/
EVENT_DEF(RequestAddInitTask, std::string, bool, std::function<bool()>);
/**
* @brief Emit a request to add an exit task to the list
*
* These tasks will be executed during the exit phase.
*
* FIXME: request is unused and should be scrapped.
*
* @param name Name of the exit task
* @param callbackFunction The function to call to execute the task
*/
EVENT_DEF(RequestAddExitTask, std::string, std::function<bool()>);
/**
* @brief Requests ImHex's graceful shutdown
*
* If there are no questions (bool set to true), ImHex closes immediately.
* If set to false, there is a procedure run to prompt a confirmation to the user.
*
* @param noQuestions true if no questions
*/
EVENT_DEF(RequestCloseImHex, bool);
/**
* @brief Requests ImHex's restart
*
* This event is necessary for ImHex to restart in the main loop for native and web platforms,
* as ImHex cannot simply close and re-open.
*
* This event serves no purpose on Linux, Windows and macOS platforms.
*/
EVENT_DEF(RequestRestartImHex);
/**
* @brief Requests the initialization of theme handlers
*
* This is called during ImGui bootstrapping, and should not be called at any other time.
*/
EVENT_DEF(RequestInitThemeHandlers);
/**
* @brief Requests version and first-startup checks
*
* This request is called during ImHex's startup, and allows ImHex to check if it was updated since last launch.
* It also ensures newcomers (that open ImHex for the first time) are greeted with the tutorial.
*
* FIXME: the name is misleading, as this request does not effectively start any migration. It only executes
* checks about ImHex's version. The name should be changed to reflect this behaviour.
*/
EVENT_DEF(RequestStartMigration);
/**
* @brief Send a subcommand to the main Imhex instance
*
* This request is called to send a subcommand to the main ImHex instance.
* This subcommand will then be executed by a handler when ImHex finishing initializing
* (`EventImHexStartupFinished`).
*
* FIXME: change the name so that it is prefixed with "Request" like every other request.
*
* @param name the subcommand's name
* @param data the subcommand's data
*/
EVENT_DEF(SendMessageToMainInstance, const std::string, const std::vector<u8>&);
}

View File

@@ -0,0 +1,22 @@
#pragma once
#include <hex/api/event_manager.hpp>
/* Provider requests definitions */
namespace hex {
/**
* @brief Creates a provider from its unlocalized name, and add it to the provider list
*/
EVENT_DEF(RequestCreateProvider, std::string, bool, bool, hex::prv::Provider **);
/**
* @brief Move the data from all PerProvider instances from one provider to another
*
* The 'from' provider should not have any per provider data after this, and should be immediately deleted
*
* FIXME: rename with the "Request" prefix to apply standard naming convention.
*/
EVENT_DEF(MovePerProviderData, prv::Provider *, prv::Provider *);
}

View File

@@ -2,6 +2,7 @@
#include <hex.hpp>
#include <hex/api/localization_manager.hpp>
#include <hex/helpers/semantic_version.hpp>
#include <functional>
#include <optional>
@@ -492,6 +493,7 @@ namespace hex {
*/
float getNativeScale();
float getBackingScaleFactor();
/**
* @brief Gets the current main window position
@@ -580,6 +582,14 @@ namespace hex {
*/
const std::string& getGLRenderer();
/**
* @brief Checks if ImHex is being run in a "Corporate Environment"
* This function simply checks for common telltale signs such as if the machine is joined a
* domain. It's not super accurate, but it's still useful for statistics
* @return True if it is
*/
bool isCorporateEnvironment();
/**
* @brief Checks if ImHex is running in portable mode
* @return Whether ImHex is running in portable mode
@@ -618,7 +628,7 @@ namespace hex {
* @brief Gets the current ImHex version
* @return ImHex version
*/
std::string getImHexVersion(bool withBuildType = true);
SemanticVersion getImHexVersion();
/**
* @brief Gets the current git commit hash
@@ -695,6 +705,13 @@ namespace hex {
*/
void* getLibImHexModuleHandle();
/**
* Adds a new migration routine that will be executed when upgrading from a lower version than specified in migrationVersion
* @param migrationVersion Upgrade point version
* @param function Function to run
*/
void addMigrationRoutine(SemanticVersion migrationVersion, std::function<void()> function);
}
/**
@@ -736,11 +753,8 @@ namespace hex {
const std::vector<Font>& getFonts();
void setCustomFontPath(const std::fs::path &path);
void setFontSize(float size);
void setFontAtlas(ImFontAtlas *fontAtlas);
std::map<UnlocalizedString, ImFont*>& getFontDefinitions();
void setFonts(ImFont *bold, ImFont *italic);
}
GlyphRange glyph(const char *glyph);
@@ -753,26 +767,8 @@ namespace hex {
constexpr static float DefaultFontSize = 13.0;
ImFont* Bold();
ImFont* Italic();
/**
* @brief Gets the current custom font path
* @return The current custom font path
*/
const std::filesystem::path& getCustomFontPath();
/**
* @brief Gets the current font size
* @return The current font size
*/
float getFontSize();
/**
* @brief Gets the current font atlas
* @return Current font atlas
*/
ImFontAtlas* getFontAtlas();
void registerFont(const UnlocalizedString &fontName);
ImFont* getFont(const UnlocalizedString &fontName);
}

View File

@@ -1,11 +1,14 @@
#pragma once
#include <hex.hpp>
#include <map>
#include <string>
#include <string_view>
#include <vector>
#include <fmt/format.h>
#include <fmt/core.h>
#include <wolv/types/static_string.hpp>
namespace hex {
@@ -22,24 +25,30 @@ namespace hex {
};
namespace impl {
void setFallbackLanguage(const std::string &language);
void resetLanguageStrings();
}
void loadLanguage(const std::string &language);
void loadLanguage(std::string language);
std::string getLocalizedString(const std::string &unlocalizedString, const std::string &language = "");
[[nodiscard]] const std::map<std::string, std::string> &getSupportedLanguages();
[[nodiscard]] const std::string &getFallbackLanguage();
[[nodiscard]] const std::string &getSelectedLanguage();
}
struct UnlocalizedString;
class LangConst;
class Lang {
public:
explicit Lang(const char *unlocalizedString);
explicit Lang(const std::string &unlocalizedString);
explicit(false) Lang(const LangConst &localizedString);
explicit Lang(const UnlocalizedString &unlocalizedString);
explicit Lang(std::string_view unlocalizedString);
@@ -47,30 +56,54 @@ namespace hex {
[[nodiscard]] operator std::string_view() const;
[[nodiscard]] operator const char *() const;
[[nodiscard]] const std::string &get() const;
const char* get() const;
private:
std::size_t m_entryHash;
std::string m_unlocalizedString;
};
[[nodiscard]] std::string operator+(const std::string &&left, const Lang &&right);
[[nodiscard]] std::string operator+(const Lang &&left, const std::string &&right);
[[nodiscard]] std::string operator+(const std::string_view &&left, const Lang &&right);
[[nodiscard]] std::string operator+(const Lang &&left, const std::string_view &&right);
[[nodiscard]] std::string operator+(const char *left, const Lang &&right);
[[nodiscard]] std::string operator+(const Lang &&left, const char *right);
[[nodiscard]] std::string operator+(const Lang &&left, const Lang &&right);
class LangConst {
public:
[[nodiscard]] operator std::string() const;
[[nodiscard]] operator std::string_view() const;
[[nodiscard]] operator const char *() const;
[[nodiscard]] inline Lang operator""_lang(const char *string, size_t) {
return Lang(string);
}
const char* get() const;
constexpr static size_t hash(std::string_view string) {
constexpr u64 p = 131;
constexpr u64 m = std::numeric_limits<std::uint32_t>::max() - 4;
u64 total = 0;
u64 currentMultiplier = 1;
for (char c : string) {
total = (total + currentMultiplier * c) % m;
currentMultiplier = (currentMultiplier * p) % m;
}
return total;
}
private:
constexpr explicit LangConst(std::size_t hash, const char *unlocalizedString) : m_entryHash(hash), m_unlocalizedString(unlocalizedString) {}
template<wolv::type::StaticString>
friend consteval LangConst operator""_lang();
friend class Lang;
private:
std::size_t m_entryHash;
const char *m_unlocalizedString = nullptr;
};
struct UnlocalizedString {
public:
UnlocalizedString() = default;
UnlocalizedString(auto && arg) : m_unlocalizedString(std::forward<decltype(arg)>(arg)) {
static_assert(!std::same_as<std::remove_cvref_t<decltype(arg)>, Lang>, "Expected a unlocalized name, got a localized one!");
template<typename T>
UnlocalizedString(T &&arg) : m_unlocalizedString(std::forward<T>(arg)) {
static_assert(!std::same_as<std::remove_cvref_t<T>, Lang>, "Expected a unlocalized name, got a localized one!");
}
[[nodiscard]] operator std::string() const {
@@ -102,9 +135,17 @@ namespace hex {
std::string m_unlocalizedString;
};
// {fmt} formatter for hex::Lang
template<wolv::type::StaticString String>
[[nodiscard]] consteval LangConst operator""_lang() {
return LangConst(LangConst::hash(String.value.data()), String.value.data());
}
// {fmt} formatter for hex::Lang and hex::LangConst
inline auto format_as(const hex::Lang &entry) {
return entry.get();
}
inline auto format_as(const hex::LangConst &entry) {
return entry.get();
}
}
}

View File

@@ -2,142 +2,31 @@
#include <hex.hpp>
#include <hex/api/localization_manager.hpp>
#include <hex/helpers/keys.hpp>
#include <functional>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <GLFW/glfw3.h>
struct ImGuiWindow;
struct KeyEquivalent {
bool valid;
bool ctrl, opt, cmd, shift;
int key;
};
namespace hex {
class View;
enum class Keys {
Space = GLFW_KEY_SPACE,
Apostrophe = GLFW_KEY_APOSTROPHE,
Comma = GLFW_KEY_COMMA,
Minus = GLFW_KEY_MINUS,
Period = GLFW_KEY_PERIOD,
Slash = GLFW_KEY_SLASH,
Num0 = GLFW_KEY_0,
Num1 = GLFW_KEY_1,
Num2 = GLFW_KEY_2,
Num3 = GLFW_KEY_3,
Num4 = GLFW_KEY_4,
Num5 = GLFW_KEY_5,
Num6 = GLFW_KEY_6,
Num7 = GLFW_KEY_7,
Num8 = GLFW_KEY_8,
Num9 = GLFW_KEY_9,
Semicolon = GLFW_KEY_SEMICOLON,
Equals = GLFW_KEY_EQUAL,
A = GLFW_KEY_A,
B = GLFW_KEY_B,
C = GLFW_KEY_C,
D = GLFW_KEY_D,
E = GLFW_KEY_E,
F = GLFW_KEY_F,
G = GLFW_KEY_G,
H = GLFW_KEY_H,
I = GLFW_KEY_I,
J = GLFW_KEY_J,
K = GLFW_KEY_K,
L = GLFW_KEY_L,
M = GLFW_KEY_M,
N = GLFW_KEY_N,
O = GLFW_KEY_O,
P = GLFW_KEY_P,
Q = GLFW_KEY_Q,
R = GLFW_KEY_R,
S = GLFW_KEY_S,
T = GLFW_KEY_T,
U = GLFW_KEY_U,
V = GLFW_KEY_V,
W = GLFW_KEY_W,
X = GLFW_KEY_X,
Y = GLFW_KEY_Y,
Z = GLFW_KEY_Z,
LeftBracket = GLFW_KEY_LEFT_BRACKET,
Backslash = GLFW_KEY_BACKSLASH,
RightBracket = GLFW_KEY_RIGHT_BRACKET,
GraveAccent = GLFW_KEY_GRAVE_ACCENT,
World1 = GLFW_KEY_WORLD_1,
World2 = GLFW_KEY_WORLD_2,
Escape = GLFW_KEY_ESCAPE,
Enter = GLFW_KEY_ENTER,
Tab = GLFW_KEY_TAB,
Backspace = GLFW_KEY_BACKSPACE,
Insert = GLFW_KEY_INSERT,
Delete = GLFW_KEY_DELETE,
Right = GLFW_KEY_RIGHT,
Left = GLFW_KEY_LEFT,
Down = GLFW_KEY_DOWN,
Up = GLFW_KEY_UP,
PageUp = GLFW_KEY_PAGE_UP,
PageDown = GLFW_KEY_PAGE_DOWN,
Home = GLFW_KEY_HOME,
End = GLFW_KEY_END,
CapsLock = GLFW_KEY_CAPS_LOCK,
ScrollLock = GLFW_KEY_SCROLL_LOCK,
NumLock = GLFW_KEY_NUM_LOCK,
PrintScreen = GLFW_KEY_PRINT_SCREEN,
Pause = GLFW_KEY_PAUSE,
F1 = GLFW_KEY_F1,
F2 = GLFW_KEY_F2,
F3 = GLFW_KEY_F3,
F4 = GLFW_KEY_F4,
F5 = GLFW_KEY_F5,
F6 = GLFW_KEY_F6,
F7 = GLFW_KEY_F7,
F8 = GLFW_KEY_F8,
F9 = GLFW_KEY_F9,
F10 = GLFW_KEY_F10,
F11 = GLFW_KEY_F11,
F12 = GLFW_KEY_F12,
F13 = GLFW_KEY_F13,
F14 = GLFW_KEY_F14,
F15 = GLFW_KEY_F15,
F16 = GLFW_KEY_F16,
F17 = GLFW_KEY_F17,
F18 = GLFW_KEY_F18,
F19 = GLFW_KEY_F19,
F20 = GLFW_KEY_F20,
F21 = GLFW_KEY_F21,
F22 = GLFW_KEY_F22,
F23 = GLFW_KEY_F23,
F24 = GLFW_KEY_F24,
F25 = GLFW_KEY_F25,
KeyPad0 = GLFW_KEY_KP_0,
KeyPad1 = GLFW_KEY_KP_1,
KeyPad2 = GLFW_KEY_KP_2,
KeyPad3 = GLFW_KEY_KP_3,
KeyPad4 = GLFW_KEY_KP_4,
KeyPad5 = GLFW_KEY_KP_5,
KeyPad6 = GLFW_KEY_KP_6,
KeyPad7 = GLFW_KEY_KP_7,
KeyPad8 = GLFW_KEY_KP_8,
KeyPad9 = GLFW_KEY_KP_9,
KeyPadDecimal = GLFW_KEY_KP_DECIMAL,
KeyPadDivide = GLFW_KEY_KP_DIVIDE,
KeyPadMultiply = GLFW_KEY_KP_MULTIPLY,
KeyPadSubtract = GLFW_KEY_KP_SUBTRACT,
KeyPadAdd = GLFW_KEY_KP_ADD,
KeyPadEnter = GLFW_KEY_KP_ENTER,
KeyPadEqual = GLFW_KEY_KP_EQUAL,
Menu = GLFW_KEY_MENU,
};
class Key {
public:
constexpr Key() = default;
constexpr Key(Keys key) : m_key(static_cast<u32>(key)) { }
bool operator==(const Key &) const = default;
auto operator<=>(const Key &) const = default;
[[nodiscard]] constexpr u32 getKeyCode() const { return m_key; }
@@ -152,224 +41,32 @@ namespace hex {
constexpr static auto SUPER = Key(static_cast<Keys>(0x0800'0000));
constexpr static auto CurrentView = Key(static_cast<Keys>(0x1000'0000));
constexpr static auto AllowWhileTyping = Key(static_cast<Keys>(0x2000'0000));
#if defined (OS_MACOS)
constexpr static auto CTRLCMD = SUPER;
#else
constexpr static auto CTRLCMD = CTRL;
#endif
constexpr static auto CTRLCMD = Key(static_cast<Keys>(0x4000'0000));
class Shortcut {
public:
Shortcut() = default;
Shortcut(Keys key) : m_keys({ key }) { }
explicit Shortcut(std::set<Key> keys) : m_keys(std::move(keys)) { }
Shortcut(Keys key);
explicit Shortcut(std::set<Key> keys);
Shortcut(const Shortcut &other) = default;
Shortcut(Shortcut &&) noexcept = default;
Shortcut& operator=(const Shortcut &other) = default;
constexpr static auto None = Keys(0);
Shortcut& operator=(const Shortcut &other) = default;
Shortcut& operator=(Shortcut &&) noexcept = default;
constexpr static inline auto None = Keys(0);
Shortcut operator+(const Key &other) const;
Shortcut &operator+=(const Key &other);
bool operator<(const Shortcut &other) const;
bool operator==(const Shortcut &other) const;
Shortcut operator+(const Key &other) const {
Shortcut result = *this;
result.m_keys.insert(other);
return result;
}
Shortcut &operator+=(const Key &other) {
m_keys.insert(other);
return *this;
}
bool operator<(const Shortcut &other) const {
return m_keys < other.m_keys;
}
bool operator==(const Shortcut &other) const {
auto thisKeys = m_keys;
auto otherKeys = other.m_keys;
thisKeys.erase(CurrentView);
thisKeys.erase(AllowWhileTyping);
otherKeys.erase(CurrentView);
otherKeys.erase(AllowWhileTyping);
return thisKeys == otherKeys;
}
bool isLocal() const {
return m_keys.contains(CurrentView);
}
std::string toString() const {
std::string result;
#if defined(OS_MACOS)
constexpr static auto CTRL_NAME = "CTRL";
constexpr static auto ALT_NAME = "OPT";
constexpr static auto SHIFT_NAME = "SHIFT";
constexpr static auto SUPER_NAME = "CMD";
#else
constexpr static auto CTRL_NAME = "CTRL";
constexpr static auto ALT_NAME = "ALT";
constexpr static auto SHIFT_NAME = "SHIFT";
constexpr static auto SUPER_NAME = "SUPER";
#endif
constexpr static auto Concatination = " + ";
auto keys = m_keys;
if (keys.erase(CTRL) > 0) {
result += CTRL_NAME;
result += Concatination;
}
if (keys.erase(ALT) > 0) {
result += ALT_NAME;
result += Concatination;
}
if (keys.erase(SHIFT) > 0) {
result += SHIFT_NAME;
result += Concatination;
}
if (keys.erase(SUPER) > 0) {
result += SUPER_NAME;
result += Concatination;
}
keys.erase(CurrentView);
for (const auto &key : keys) {
switch (Keys(key.getKeyCode())) {
case Keys::Space: result += "SPACE"; break;
case Keys::Apostrophe: result += "'"; break;
case Keys::Comma: result += ","; break;
case Keys::Minus: result += "-"; break;
case Keys::Period: result += "."; break;
case Keys::Slash: result += "/"; break;
case Keys::Num0: result += "0"; break;
case Keys::Num1: result += "1"; break;
case Keys::Num2: result += "2"; break;
case Keys::Num3: result += "3"; break;
case Keys::Num4: result += "4"; break;
case Keys::Num5: result += "5"; break;
case Keys::Num6: result += "6"; break;
case Keys::Num7: result += "7"; break;
case Keys::Num8: result += "8"; break;
case Keys::Num9: result += "9"; break;
case Keys::Semicolon: result += ";"; break;
case Keys::Equals: result += "="; break;
case Keys::A: result += "A"; break;
case Keys::B: result += "B"; break;
case Keys::C: result += "C"; break;
case Keys::D: result += "D"; break;
case Keys::E: result += "E"; break;
case Keys::F: result += "F"; break;
case Keys::G: result += "G"; break;
case Keys::H: result += "H"; break;
case Keys::I: result += "I"; break;
case Keys::J: result += "J"; break;
case Keys::K: result += "K"; break;
case Keys::L: result += "L"; break;
case Keys::M: result += "M"; break;
case Keys::N: result += "N"; break;
case Keys::O: result += "O"; break;
case Keys::P: result += "P"; break;
case Keys::Q: result += "Q"; break;
case Keys::R: result += "R"; break;
case Keys::S: result += "S"; break;
case Keys::T: result += "T"; break;
case Keys::U: result += "U"; break;
case Keys::V: result += "V"; break;
case Keys::W: result += "W"; break;
case Keys::X: result += "X"; break;
case Keys::Y: result += "Y"; break;
case Keys::Z: result += "Z"; break;
case Keys::LeftBracket: result += "["; break;
case Keys::Backslash: result += "\\"; break;
case Keys::RightBracket: result += "]"; break;
case Keys::GraveAccent: result += "`"; break;
case Keys::World1: result += "WORLD1"; break;
case Keys::World2: result += "WORLD2"; break;
case Keys::Escape: result += "ESC"; break;
case Keys::Enter: result += "ENTER"; break;
case Keys::Tab: result += "TAB"; break;
case Keys::Backspace: result += "BACKSPACE"; break;
case Keys::Insert: result += "INSERT"; break;
case Keys::Delete: result += "DELETE"; break;
case Keys::Right: result += "RIGHT"; break;
case Keys::Left: result += "LEFT"; break;
case Keys::Down: result += "DOWN"; break;
case Keys::Up: result += "UP"; break;
case Keys::PageUp: result += "PAGEUP"; break;
case Keys::PageDown: result += "PAGEDOWN"; break;
case Keys::Home: result += "HOME"; break;
case Keys::End: result += "END"; break;
case Keys::CapsLock: result += "CAPSLOCK"; break;
case Keys::ScrollLock: result += "SCROLLLOCK"; break;
case Keys::NumLock: result += "NUMLOCK"; break;
case Keys::PrintScreen: result += "PRINTSCREEN"; break;
case Keys::Pause: result += "PAUSE"; break;
case Keys::F1: result += "F1"; break;
case Keys::F2: result += "F2"; break;
case Keys::F3: result += "F3"; break;
case Keys::F4: result += "F4"; break;
case Keys::F5: result += "F5"; break;
case Keys::F6: result += "F6"; break;
case Keys::F7: result += "F7"; break;
case Keys::F8: result += "F8"; break;
case Keys::F9: result += "F9"; break;
case Keys::F10: result += "F10"; break;
case Keys::F11: result += "F11"; break;
case Keys::F12: result += "F12"; break;
case Keys::F13: result += "F13"; break;
case Keys::F14: result += "F14"; break;
case Keys::F15: result += "F15"; break;
case Keys::F16: result += "F16"; break;
case Keys::F17: result += "F17"; break;
case Keys::F18: result += "F18"; break;
case Keys::F19: result += "F19"; break;
case Keys::F20: result += "F20"; break;
case Keys::F21: result += "F21"; break;
case Keys::F22: result += "F22"; break;
case Keys::F23: result += "F23"; break;
case Keys::F24: result += "F24"; break;
case Keys::F25: result += "F25"; break;
case Keys::KeyPad0: result += "KP0"; break;
case Keys::KeyPad1: result += "KP1"; break;
case Keys::KeyPad2: result += "KP2"; break;
case Keys::KeyPad3: result += "KP3"; break;
case Keys::KeyPad4: result += "KP4"; break;
case Keys::KeyPad5: result += "KP5"; break;
case Keys::KeyPad6: result += "KP6"; break;
case Keys::KeyPad7: result += "KP7"; break;
case Keys::KeyPad8: result += "KP8"; break;
case Keys::KeyPad9: result += "KP9"; break;
case Keys::KeyPadDecimal: result += "KPDECIMAL"; break;
case Keys::KeyPadDivide: result += "KPDIVIDE"; break;
case Keys::KeyPadMultiply: result += "KPMULTIPLY"; break;
case Keys::KeyPadSubtract: result += "KPSUBTRACT"; break;
case Keys::KeyPadAdd: result += "KPADD"; break;
case Keys::KeyPadEnter: result += "KPENTER"; break;
case Keys::KeyPadEqual: result += "KPEQUAL"; break;
case Keys::Menu: result += "MENU"; break;
default:
continue;
}
result += " + ";
}
if (result.ends_with(" + "))
result = result.substr(0, result.size() - 3);
return result;
}
const std::set<Key>& getKeys() const { return m_keys; }
bool isLocal() const;
std::string toString() const;
KeyEquivalent toKeyEquivalent() const;
const std::set<Key>& getKeys() const;
bool has(Key key) const;
bool matches(const Shortcut &other) const;
private:
friend Shortcut operator+(const Key &lhs, const Key &rhs);
@@ -377,12 +74,7 @@ namespace hex {
std::set<Key> m_keys;
};
inline Shortcut operator+(const Key &lhs, const Key &rhs) {
Shortcut result;
result.m_keys = { lhs, rhs };
return result;
}
Shortcut operator+(const Key &lhs, const Key &rhs);
/**
* @brief The ShortcutManager handles global and view-specific shortcuts.
@@ -391,10 +83,12 @@ namespace hex {
class ShortcutManager {
public:
using Callback = std::function<void()>;
using EnabledCallback = std::function<bool()>;
struct ShortcutEntry {
Shortcut shortcut;
UnlocalizedString unlocalizedName;
std::vector<UnlocalizedString> unlocalizedName;
Callback callback;
EnabledCallback enabledCallback;
};
/**
@@ -402,8 +96,10 @@ namespace hex {
* @param shortcut The shortcut to add.
* @param unlocalizedName The unlocalized name of the shortcut
* @param callback The callback to call when the shortcut is triggered.
* @param enabledCallback Callback that's called to check if this shortcut is enabled
*/
static void addGlobalShortcut(const Shortcut &shortcut, const UnlocalizedString &unlocalizedName, const Callback &callback);
static void addGlobalShortcut(const Shortcut &shortcut, const std::vector<UnlocalizedString> &unlocalizedName, const Callback &callback, const EnabledCallback &enabledCallback = []{ return true; });
static void addGlobalShortcut(const Shortcut &shortcut, const UnlocalizedString &unlocalizedName, const Callback &callback, const EnabledCallback &enabledCallback = []{ return true; });
/**
* @brief Add a view-specific shortcut. View-specific shortcuts can only be triggered when the specified view is focused.
@@ -411,8 +107,10 @@ namespace hex {
* @param shortcut The shortcut to add.
* @param unlocalizedName The unlocalized name of the shortcut
* @param callback The callback to call when the shortcut is triggered.
* @param enabledCallback Callback that's called to check if this shortcut is enabled
*/
static void addShortcut(View *view, const Shortcut &shortcut, const UnlocalizedString &unlocalizedName, const Callback &callback);
static void addShortcut(View *view, const Shortcut &shortcut, const std::vector<UnlocalizedString> &unlocalizedName, const Callback &callback, const EnabledCallback &enabledCallback = []{ return true; });
static void addShortcut(View *view, const Shortcut &shortcut, const UnlocalizedString &unlocalizedName, const Callback &callback, const EnabledCallback &enabledCallback = []{ return true; });
/**
@@ -445,12 +143,17 @@ namespace hex {
static void resumeShortcuts();
static void pauseShortcuts();
static void enableMacOSMode();
[[nodiscard]] static std::optional<UnlocalizedString> getLastActivatedMenu();
static void resetLastActivatedMenu();
[[nodiscard]] static std::optional<Shortcut> getPreviousShortcut();
[[nodiscard]] static std::vector<ShortcutEntry> getGlobalShortcuts();
[[nodiscard]] static std::vector<ShortcutEntry> getViewShortcuts(const View *view);
[[nodiscard]] static bool updateShortcut(const Shortcut &oldShortcut, const Shortcut &newShortcut, View *view = nullptr);
[[nodiscard]] static bool updateShortcut(const Shortcut &oldShortcut, Shortcut newShortcut, View *view = nullptr);
};
}

View File

@@ -22,7 +22,7 @@ namespace hex {
class Task {
public:
Task() = default;
Task(UnlocalizedString unlocalizedName, u64 maxValue, bool background, std::function<void(Task &)> function);
Task(const UnlocalizedString &unlocalizedName, u64 maxValue, bool background, std::function<void(Task &)> function);
Task(const Task&) = delete;
Task(Task &&other) noexcept;
@@ -130,20 +130,37 @@ namespace hex {
/**
* @brief Creates a new asynchronous task that gets displayed in the Task Manager in the footer
* @param name Name of the task
* @param unlocalizedName Name of the task
* @param maxValue Maximum value of the task
* @param function Function to be executed
* @return A TaskHolder holding a weak reference to the task
*/
static TaskHolder createTask(std::string name, u64 maxValue, std::function<void(Task &)> function);
static TaskHolder createTask(const UnlocalizedString &unlocalizedName, u64 maxValue, std::function<void(Task &)> function);
/**
* @brief Creates a new asynchronous task that gets displayed in the Task Manager in the footer
* @param unlocalizedName Name of the task
* @param maxValue Maximum value of the task
* @param function Function to be executed
* @return A TaskHolder holding a weak reference to the task
*/
static TaskHolder createTask(const UnlocalizedString &unlocalizedName, u64 maxValue, std::function<void()> function);
/**
* @brief Creates a new asynchronous task that does not get displayed in the Task Manager
* @param name Name of the task
* @param unlocalizedName Name of the task
* @param function Function to be executed
* @return A TaskHolder holding a weak reference to the task
*/
static TaskHolder createBackgroundTask(std::string name, std::function<void(Task &)> function);
static TaskHolder createBackgroundTask(const UnlocalizedString &unlocalizedName, std::function<void(Task &)> function);
/**
* @brief Creates a new asynchronous task that does not get displayed in the Task Manager
* @param unlocalizedName Name of the task
* @param function Function to be executed
* @return A TaskHolder holding a weak reference to the task
*/
static TaskHolder createBackgroundTask(const UnlocalizedString &unlocalizedName, std::function<void()> function);
/**
* @brief Creates a new synchronous task that will execute the given function at the start of the next frame
@@ -190,7 +207,7 @@ namespace hex {
static void runDeferredCalls();
private:
static TaskHolder createTask(std::string name, u64 maxValue, bool background, std::function<void(Task &)> function);
static TaskHolder createTask(const UnlocalizedString &unlocalizedName, u64 maxValue, bool background, std::function<void(Task &)> function);
};
}

View File

@@ -56,6 +56,7 @@ namespace hex {
*/
static void addStyleHandler(const std::string &name, const StyleMap &styleMap);
static void reapplyCurrentTheme();
static std::vector<std::string> getThemeNames();
static const std::string &getImageTheme();
@@ -66,6 +67,7 @@ namespace hex {
static void reset();
static void setAccentColor(const ImColor &color);
public:
struct ThemeHandler {
@@ -81,6 +83,7 @@ namespace hex {
static const std::map<std::string, ThemeHandler>& getThemeHandlers();
static const std::map<std::string, StyleHandler>& getStyleHandlers();
private:
ThemeManager() = default;
};

View File

@@ -151,6 +151,9 @@ namespace hex {
static void addInteractiveHelpText(std::initializer_list<std::variant<Lang, std::string, int>> &&ids, UnlocalizedString unlocalizedString);
static void addInteractiveHelpLink(std::initializer_list<std::variant<Lang, std::string, int>> &&ids, std::string link);
static void setLastItemInteractiveHelpPopup(std::function<void()> callback);
static void setLastItemInteractiveHelpLink(std::string link);
/**
* @brief Draws the tutorial

View File

@@ -3,7 +3,6 @@
#include <hex.hpp>
#include <hex/api/localization_manager.hpp>
#include <hex/helpers/intrinsics.hpp>
#include <hex/data_processor/attribute.hpp>
#include <set>
@@ -12,6 +11,7 @@
#include <nlohmann/json_fwd.hpp>
#include <imgui.h>
#include <hex/providers/provider_data.hpp>
namespace hex::prv {
class Provider;
@@ -42,11 +42,12 @@ namespace hex::dp {
m_overlay = overlay;
}
virtual void drawNode() { }
void draw();
virtual void process() = 0;
virtual void reset() { }
virtual void store(nlohmann::json &j) const { hex::unused(j); }
virtual void load(const nlohmann::json &j) { hex::unused(j); }
virtual void store(nlohmann::json &j) const { std::ignore = j; }
virtual void load(const nlohmann::json &j) { std::ignore = j; }
struct NodeError {
Node *node;
@@ -80,6 +81,11 @@ namespace hex::dp {
void setIntegerOnOutput(u32 index, i128 integer);
void setFloatOnOutput(u32 index, double floatingPoint);
static void interrupt();
protected:
virtual void drawNode() { }
private:
int m_id;
UnlocalizedString m_unlocalizedTitle, m_unlocalizedName;
@@ -90,45 +96,16 @@ namespace hex::dp {
static int s_idCounter;
Attribute& getAttribute(u32 index) {
if (index >= this->getAttributes().size())
throw std::runtime_error("Attribute index out of bounds!");
return this->getAttributes()[index];
}
Attribute *getConnectedInputAttribute(u32 index) {
const auto &connectedAttribute = this->getAttribute(index).getConnectedAttributes();
if (connectedAttribute.empty())
return nullptr;
return connectedAttribute.begin()->second;
}
void markInputProcessed(u32 index) {
const auto &[iter, inserted] = m_processedInputs.insert(index);
if (!inserted)
throwNodeError("Recursion detected!");
}
void unmarkInputProcessed(u32 index) {
m_processedInputs.erase(index);
}
Attribute& getAttribute(u32 index);
Attribute *getConnectedInputAttribute(u32 index);
void markInputProcessed(u32 index);
void unmarkInputProcessed(u32 index);
protected:
[[noreturn]] void throwNodeError(const std::string &message) {
throw NodeError { this, message };
}
[[noreturn]] void throwNodeError(const std::string &message);
void setOverlayData(u64 address, const std::vector<u8> &data);
void setAttributes(std::vector<Attribute> attributes) {
m_attributes = std::move(attributes);
for (auto &attr : m_attributes)
attr.setParentNode(this);
}
void setAttributes(std::vector<Attribute> attributes);
};
}

View File

@@ -1,6 +1,5 @@
#pragma once
#include <hex/api/event_manager.hpp>
#include <hex/api/imhex_api.hpp>
namespace hex {

View File

@@ -2,10 +2,15 @@
#include <hex.hpp>
#include <wolv/utils/expected.hpp>
#include <array>
#include <string>
#include <vector>
#define CRYPTO_ERROR_INVALID_KEY_LENGTH (-1)
#define CRYPTO_ERROR_INVALID_MODE (-2)
namespace hex::prv {
class Provider;
}
@@ -60,5 +65,5 @@ namespace hex::crypt {
Key256Bits = 2
};
std::vector<u8> aesDecrypt(AESMode mode, KeyLength keyLength, const std::vector<u8> &key, std::array<u8, 8> nonce, std::array<u8, 8> iv, const std::vector<u8> &input);
wolv::util::Expected<std::vector<u8>, int> aesDecrypt(AESMode mode, KeyLength keyLength, const std::vector<u8> &key, std::array<u8, 8> nonce, std::array<u8, 8> iv, const std::vector<u8> &input);
}

View File

@@ -44,4 +44,7 @@ namespace hex::dbg {
}
}
bool debugModeEnabled();
void setDebugModeEnabled(bool enabled);
}

View File

@@ -82,8 +82,9 @@ namespace hex::paths {
const static inline impl::DataPath Nodes("scripts/nodes");
const static inline impl::DataPath Layouts("layouts");
const static inline impl::DataPath Workspaces("workspaces");
const static inline impl::DataPath Disassemblers("disassemblers");
constexpr static inline std::array<const impl::DefaultPath*, 20> All = {
constexpr static inline std::array<const impl::DefaultPath*, 21> All = {
&Config,
&Recent,
@@ -106,6 +107,7 @@ namespace hex::paths {
&Nodes,
&Layouts,
&Workspaces,
&Disassemblers
};
}

View File

@@ -1,7 +1,7 @@
#pragma once
#include <string_view>
#include <fmt/format.h>
#include <fmt/core.h>
#include <fmt/ranges.h>
namespace hex {

View File

@@ -25,13 +25,16 @@
template<typename T>
std::future<HttpRequest::Result<T>> HttpRequest::uploadFile(const std::fs::path &path, const std::string &mimeName) {
hex::unused(path, mimeName);
std::ignore = path;
std::ignore = mimeName;
throw std::logic_error("Not implemented");
}
template<typename T>
std::future<HttpRequest::Result<T>> HttpRequest::uploadFile(std::vector<u8> data, const std::string &mimeName, const std::fs::path &fileName) {
hex::unused(data, mimeName, fileName);
std::ignore = data;
std::ignore = mimeName;
std::ignore = fileName;
throw std::logic_error("Not implemented");
}

View File

@@ -1,9 +0,0 @@
#pragma once
namespace hex {
void unused(auto && ... x) {
((void)x, ...);
}
}

View File

@@ -0,0 +1,122 @@
#pragma once
#include <GLFW/glfw3.h>
#if defined(__cplusplus)
enum class Keys {
#else
enum Keys {
#endif
Space = GLFW_KEY_SPACE,
Apostrophe = GLFW_KEY_APOSTROPHE,
Comma = GLFW_KEY_COMMA,
Minus = GLFW_KEY_MINUS,
Period = GLFW_KEY_PERIOD,
Slash = GLFW_KEY_SLASH,
Num0 = GLFW_KEY_0,
Num1 = GLFW_KEY_1,
Num2 = GLFW_KEY_2,
Num3 = GLFW_KEY_3,
Num4 = GLFW_KEY_4,
Num5 = GLFW_KEY_5,
Num6 = GLFW_KEY_6,
Num7 = GLFW_KEY_7,
Num8 = GLFW_KEY_8,
Num9 = GLFW_KEY_9,
Semicolon = GLFW_KEY_SEMICOLON,
Equals = GLFW_KEY_EQUAL,
A = GLFW_KEY_A,
B = GLFW_KEY_B,
C = GLFW_KEY_C,
D = GLFW_KEY_D,
E = GLFW_KEY_E,
F = GLFW_KEY_F,
G = GLFW_KEY_G,
H = GLFW_KEY_H,
I = GLFW_KEY_I,
J = GLFW_KEY_J,
K = GLFW_KEY_K,
L = GLFW_KEY_L,
M = GLFW_KEY_M,
N = GLFW_KEY_N,
O = GLFW_KEY_O,
P = GLFW_KEY_P,
Q = GLFW_KEY_Q,
R = GLFW_KEY_R,
S = GLFW_KEY_S,
T = GLFW_KEY_T,
U = GLFW_KEY_U,
V = GLFW_KEY_V,
W = GLFW_KEY_W,
X = GLFW_KEY_X,
Y = GLFW_KEY_Y,
Z = GLFW_KEY_Z,
LeftBracket = GLFW_KEY_LEFT_BRACKET,
Backslash = GLFW_KEY_BACKSLASH,
RightBracket = GLFW_KEY_RIGHT_BRACKET,
GraveAccent = GLFW_KEY_GRAVE_ACCENT,
World1 = GLFW_KEY_WORLD_1,
World2 = GLFW_KEY_WORLD_2,
Escape = GLFW_KEY_ESCAPE,
Enter = GLFW_KEY_ENTER,
Tab = GLFW_KEY_TAB,
Backspace = GLFW_KEY_BACKSPACE,
Insert = GLFW_KEY_INSERT,
Delete = GLFW_KEY_DELETE,
Right = GLFW_KEY_RIGHT,
Left = GLFW_KEY_LEFT,
Down = GLFW_KEY_DOWN,
Up = GLFW_KEY_UP,
PageUp = GLFW_KEY_PAGE_UP,
PageDown = GLFW_KEY_PAGE_DOWN,
Home = GLFW_KEY_HOME,
End = GLFW_KEY_END,
CapsLock = GLFW_KEY_CAPS_LOCK,
ScrollLock = GLFW_KEY_SCROLL_LOCK,
NumLock = GLFW_KEY_NUM_LOCK,
PrintScreen = GLFW_KEY_PRINT_SCREEN,
Pause = GLFW_KEY_PAUSE,
F1 = GLFW_KEY_F1,
F2 = GLFW_KEY_F2,
F3 = GLFW_KEY_F3,
F4 = GLFW_KEY_F4,
F5 = GLFW_KEY_F5,
F6 = GLFW_KEY_F6,
F7 = GLFW_KEY_F7,
F8 = GLFW_KEY_F8,
F9 = GLFW_KEY_F9,
F10 = GLFW_KEY_F10,
F11 = GLFW_KEY_F11,
F12 = GLFW_KEY_F12,
F13 = GLFW_KEY_F13,
F14 = GLFW_KEY_F14,
F15 = GLFW_KEY_F15,
F16 = GLFW_KEY_F16,
F17 = GLFW_KEY_F17,
F18 = GLFW_KEY_F18,
F19 = GLFW_KEY_F19,
F20 = GLFW_KEY_F20,
F21 = GLFW_KEY_F21,
F22 = GLFW_KEY_F22,
F23 = GLFW_KEY_F23,
F24 = GLFW_KEY_F24,
F25 = GLFW_KEY_F25,
KeyPad0 = GLFW_KEY_KP_0,
KeyPad1 = GLFW_KEY_KP_1,
KeyPad2 = GLFW_KEY_KP_2,
KeyPad3 = GLFW_KEY_KP_3,
KeyPad4 = GLFW_KEY_KP_4,
KeyPad5 = GLFW_KEY_KP_5,
KeyPad6 = GLFW_KEY_KP_6,
KeyPad7 = GLFW_KEY_KP_7,
KeyPad8 = GLFW_KEY_KP_8,
KeyPad9 = GLFW_KEY_KP_9,
KeyPadDecimal = GLFW_KEY_KP_DECIMAL,
KeyPadDivide = GLFW_KEY_KP_DIVIDE,
KeyPadMultiply = GLFW_KEY_KP_MULTIPLY,
KeyPadSubtract = GLFW_KEY_KP_SUBTRACT,
KeyPadAdd = GLFW_KEY_KP_ADD,
KeyPadEnter = GLFW_KEY_KP_ENTER,
KeyPadEqual = GLFW_KEY_KP_EQUAL,
Menu = GLFW_KEY_MENU,
};

View File

@@ -807,6 +807,8 @@ namespace hex::gl {
void bind() const;
void unbind() const;
bool isValid() const { return m_program != 0; }
void setUniform(std::string_view name, const int &value);
void setUniform(std::string_view name, const float &value);

View File

@@ -21,6 +21,11 @@ namespace hex {
MissingEOF
};
enum class PatchKind {
IPS,
IPS32
};
class Patches {
public:
Patches() = default;

View File

@@ -0,0 +1,36 @@
#pragma once
#include <hex.hpp>
#include <compare>
#include <string>
#include <vector>
namespace hex {
class SemanticVersion {
public:
SemanticVersion() = default;
SemanticVersion(std::string version);
SemanticVersion(std::string_view version);
SemanticVersion(const char *version);
std::strong_ordering operator<=>(const SemanticVersion &) const;
bool operator==(const SemanticVersion &other) const;
u32 major() const;
u32 minor() const;
u32 patch() const;
bool nightly() const;
const std::string& buildType() const;
bool isValid() const;
std::string get(bool withBuildType = true) const;
private:
std::vector<std::string> m_parts;
std::string m_buildType;
};
}

View File

@@ -29,7 +29,7 @@ namespace hex {
void close();
/**
* @brief get the error string explaining the error that occured when opening the file.
* @brief get the error string explaining the error that occurred when opening the file.
* This error is a combination of the tar error and the native file open error
*/
std::string getOpenErrorString() const;
@@ -59,4 +59,4 @@ namespace hex {
int m_fileOpenErrno = 0;
};
}
}

View File

@@ -4,6 +4,7 @@
#include <cstdint>
#include <concepts>
#include <type_traits>
using u8 = std::uint8_t;
using u16 = std::uint16_t;

View File

@@ -26,7 +26,7 @@
#include <hex/helpers/utils_linux.hpp>
#endif
struct ImVec2;
#include <imgui.h>
namespace hex {
@@ -34,6 +34,29 @@ namespace hex {
class Provider;
}
template<typename T>
[[nodiscard]] std::vector<std::vector<T>> sampleChannels(const std::vector<T> &data, size_t count, size_t channels) {
if (channels == 0) return {};
size_t signalLength = std::max(1.0, double(data.size()) / channels);
size_t stride = std::max(1.0, double(signalLength) / count);
std::vector<std::vector<T>> result;
result.resize(channels);
for (size_t i = 0; i < channels; i++) {
result[i].reserve(count);
}
result.reserve(count);
for (size_t i = 0; i < data.size(); i += stride) {
for (size_t j = 0; j < channels; j++) {
result[j].push_back(data[i + j]);
}
}
return result;
}
template<typename T>
[[nodiscard]] std::vector<T> sampleData(const std::vector<T> &data, size_t count) {
size_t stride = std::max(1.0, double(data.size()) / count);
@@ -262,13 +285,13 @@ namespace hex {
[[nodiscard]] float float16ToFloat32(u16 float16);
[[nodiscard]] inline bool equalsIgnoreCase(const std::string &left, const std::string &right) {
[[nodiscard]] inline bool equalsIgnoreCase(std::string_view left, std::string_view right) {
return std::equal(left.begin(), left.end(), right.begin(), right.end(), [](char a, char b) {
return tolower(a) == tolower(b);
});
}
[[nodiscard]] inline bool containsIgnoreCase(const std::string &a, const std::string &b) {
[[nodiscard]] inline bool containsIgnoreCase(std::string_view a, std::string_view b) {
auto iter = std::search(a.begin(), a.end(), b.begin(), b.end(), [](char ch1, char ch2) {
return std::toupper(ch1) == std::toupper(ch2);
});
@@ -317,4 +340,6 @@ namespace hex {
*/
[[nodiscard]] void* getContainingModule(void* symbol);
[[nodiscard]] std::optional<ImColor> blendColors(const std::optional<ImColor> &a, const std::optional<ImColor> &b);
}

View File

@@ -1,5 +1,7 @@
#pragma once
#include <hex/helpers/keys.hpp>
#if defined(OS_MACOS)
struct GLFWwindow;
@@ -17,8 +19,11 @@
void enumerateFontsMacos();
void macosHandleTitlebarDoubleClickGesture(GLFWwindow *window);
void macosSetWindowMovable(GLFWwindow *window, bool movable);
bool macosIsWindowBeingResizedByUser(GLFWwindow *window);
void macosMarkContentEdited(GLFWwindow *window, bool edited = true);
void macosGetKey(Keys key, int *output);
}
#endif

View File

@@ -70,7 +70,7 @@ void* PluginSubCommandsFunctionHelper<T>::getSubCommands() {
#define IMHEX_LIBRARY_SETUP(name) IMHEX_LIBRARY_SETUP_IMPL(name)
#define IMHEX_LIBRARY_SETUP_IMPL(name) \
namespace { static struct EXIT_HANDLER { ~EXIT_HANDLER() { hex::log::debug("Unloaded library '{}'", name); } } HANDLER; } \
namespace { static struct EXIT_HANDLER { ~EXIT_HANDLER() { hex::log::info("Unloaded library '{}'", name); } } HANDLER; } \
IMHEX_PLUGIN_VISIBILITY_PREFIX void WOLV_TOKEN_CONCAT(initializeLibrary_, IMHEX_PLUGIN_NAME)(); \
IMHEX_PLUGIN_VISIBILITY_PREFIX const char *WOLV_TOKEN_CONCAT(getLibraryName_, IMHEX_PLUGIN_NAME)() { return name; } \
IMHEX_PLUGIN_VISIBILITY_PREFIX void WOLV_TOKEN_CONCAT(setImGuiContext_, IMHEX_PLUGIN_NAME)(ImGuiContext *ctx) { \

View File

@@ -38,7 +38,7 @@ namespace hex::prv {
[[nodiscard]] std::string getName() const override { return m_name; }
[[nodiscard]] std::string getTypeName() const override { return "MemoryProvider"; }
[[nodiscard]] UnlocalizedString getTypeName() const override { return "MemoryProvider"; }
private:
void renameFile();

View File

@@ -30,6 +30,7 @@ namespace hex::prv {
struct MenuEntry {
std::string name;
const char *icon;
std::function<void()> callback;
};
@@ -151,7 +152,7 @@ namespace hex::prv {
* like "hex.builtin.provider.mem_file" or "hex.builtin.provider.file"
* @return The provider's type name
*/
[[nodiscard]] virtual std::string getTypeName() const = 0;
[[nodiscard]] virtual UnlocalizedString getTypeName() const = 0;
/**
* @brief Gets a human readable representation of the current provider
@@ -165,7 +166,7 @@ namespace hex::prv {
void insert(u64 offset, u64 size);
void remove(u64 offset, u64 size);
virtual void resizeRaw(u64 newSize) { hex::unused(newSize); }
virtual void resizeRaw(u64 newSize) { std::ignore = newSize; }
virtual void insertRaw(u64 offset, u64 size);
virtual void removeRaw(u64 offset, u64 size);

View File

@@ -1,7 +1,10 @@
#pragma once
#include <hex/api/imhex_api.hpp>
#include <hex/api/event_manager.hpp>
#include <hex/api/events/events_provider.hpp>
#include <hex/api/events/events_lifecycle.hpp>
#include <hex/api/events/requests_provider.hpp>
#include <map>
#include <ranges>

View File

@@ -2,7 +2,7 @@
#include <hex.hpp>
#include <hex/api/localization_manager.hpp>
#include <hex/api/event_manager.hpp>
#include <hex/api/events/events_interaction.hpp>
#include <hex/providers/undo_redo/operations/operation.hpp>

View File

@@ -47,7 +47,7 @@ namespace hex::test {
return m_data->size();
}
[[nodiscard]] std::string getTypeName() const override { return "hex.test.provider.test"; }
[[nodiscard]] UnlocalizedString getTypeName() const override { return "hex.test.provider.test"; }
bool open() override { return true; }
void close() override { }

View File

@@ -0,0 +1,57 @@
#pragma once
#include <hex.hpp>
#include <imgui.h>
#include <imgui_internal.h>
#include <hex/helpers/utils.hpp>
#include <list>
#include <memory>
#include <mutex>
#include "hex/api/localization_manager.hpp"
namespace hex {
namespace impl {
class BannerBase {
public:
BannerBase(ImColor color) : m_color(color) {}
virtual ~BannerBase() = default;
virtual void draw() { drawContent(); }
virtual void drawContent() = 0;
[[nodiscard]] static std::list<std::unique_ptr<BannerBase>> &getOpenBanners();
[[nodiscard]] const ImColor& getColor() const {
return m_color;
}
void close() { m_shouldClose = true; }
[[nodiscard]] bool shouldClose() const { return m_shouldClose; }
protected:
static std::mutex& getMutex();
bool m_shouldClose = false;
ImColor m_color;
};
}
template<typename T>
class Banner : public impl::BannerBase {
public:
using impl::BannerBase::BannerBase;
template<typename ...Args>
static void open(Args && ... args) {
std::lock_guard lock(getMutex());
auto toast = std::make_unique<T>(std::forward<Args>(args)...);
getOpenBanners().emplace_back(std::move(toast));
}
};
}

View File

@@ -79,16 +79,16 @@ namespace ImGuiExt {
Texture(const Texture&) = delete;
Texture(Texture&& other) noexcept;
static Texture fromImage(const ImU8 *buffer, int size, Filter filter = Filter::Nearest);
static Texture fromImage(std::span<const std::byte> buffer, Filter filter = Filter::Nearest);
static Texture fromImage(const char *path, Filter filter = Filter::Nearest);
static Texture fromImage(const std::fs::path &path, Filter filter = Filter::Nearest);
static Texture fromGLTexture(unsigned int texture, int width, int height);
static Texture fromBitmap(const ImU8 *buffer, int size, int width, int height, Filter filter = Filter::Nearest);
static Texture fromBitmap(std::span<const std::byte> buffer, int width, int height, Filter filter = Filter::Nearest);
static Texture fromSVG(const char *path, int width = 0, int height = 0, Filter filter = Filter::Nearest);
static Texture fromSVG(const std::fs::path &path, int width = 0, int height = 0, Filter filter = Filter::Nearest);
static Texture fromSVG(std::span<const std::byte> buffer, int width = 0, int height = 0, Filter filter = Filter::Nearest);
[[nodiscard]] static Texture fromImage(const ImU8 *buffer, int size, Filter filter = Filter::Nearest);
[[nodiscard]] static Texture fromImage(std::span<const std::byte> buffer, Filter filter = Filter::Nearest);
[[nodiscard]] static Texture fromImage(const char *path, Filter filter = Filter::Nearest);
[[nodiscard]] static Texture fromImage(const std::fs::path &path, Filter filter = Filter::Nearest);
[[nodiscard]] static Texture fromGLTexture(unsigned int texture, int width, int height);
[[nodiscard]] static Texture fromBitmap(const ImU8 *buffer, int size, int width, int height, Filter filter = Filter::Nearest);
[[nodiscard]] static Texture fromBitmap(std::span<const std::byte> buffer, int width, int height, Filter filter = Filter::Nearest);
[[nodiscard]] static Texture fromSVG(const char *path, int width = 0, int height = 0, Filter filter = Filter::Nearest);
[[nodiscard]] static Texture fromSVG(const std::fs::path &path, int width = 0, int height = 0, Filter filter = Filter::Nearest);
[[nodiscard]] static Texture fromSVG(std::span<const std::byte> buffer, int width = 0, int height = 0, Filter filter = Filter::Nearest);
~Texture();
@@ -97,29 +97,25 @@ namespace ImGuiExt {
Texture& operator=(Texture&& other) noexcept;
[[nodiscard]] constexpr bool isValid() const noexcept {
return m_textureId != nullptr;
return m_textureId != 0;
}
[[nodiscard]] operator ImTextureID() const noexcept {
return m_textureId;
}
[[nodiscard]] operator intptr_t() const noexcept {
return reinterpret_cast<intptr_t>(m_textureId);
}
[[nodiscard]] auto getSize() const noexcept {
[[nodiscard]] ImVec2 getSize() const noexcept {
return ImVec2(m_width, m_height);
}
[[nodiscard]] constexpr auto getAspectRatio() const noexcept {
[[nodiscard]] constexpr float getAspectRatio() const noexcept {
if (m_height == 0) return 1.0F;
return float(m_width) / float(m_height);
}
private:
ImTextureID m_textureId = nullptr;
ImTextureID m_textureId = 0;
int m_width = 0, m_height = 0;
};
@@ -137,6 +133,8 @@ namespace ImGuiExt {
void UnderlinedText(const char *label, ImColor color = ImGui::GetStyleColorVec4(ImGuiCol_Text), const ImVec2 &size_arg = ImVec2(0, 0));
void UnderwavedText(const char *label, ImColor textColor = ImGui::GetStyleColorVec4(ImGuiCol_Text), ImColor lineColor = ImGui::GetStyleColorVec4(ImGuiCol_Text), const ImVec2 &size_arg = ImVec2(0, 0));
void TextSpinner(const char *label);
void Header(const char *label, bool firstEntry = false);
@@ -146,13 +144,13 @@ namespace ImGuiExt {
bool TitleBarButton(const char *label, ImVec2 size_arg);
bool ToolBarButton(const char *symbol, ImVec4 color);
bool IconButton(const char *symbol, ImVec4 color, ImVec2 size_arg = ImVec2(0, 0));
bool IconButton(const char *symbol, ImVec4 color, ImVec2 size_arg = ImVec2(0, 0), ImVec2 iconOffset = ImVec2(0, 0));
bool InputIntegerPrefix(const char* label, const char *prefix, void *value, ImGuiDataType type, const char *format, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
bool InputHexadecimal(const char* label, u32 *value, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
bool InputHexadecimal(const char* label, u64 *value, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
bool SliderBytes(const char *label, u64 *value, u64 min, u64 max, ImGuiSliderFlags flags = ImGuiSliderFlags_None);
bool SliderBytes(const char *label, u64 *value, u64 min, u64 max, u64 stepSize = 1, ImGuiSliderFlags flags = ImGuiSliderFlags_None);
inline bool HasSecondPassed() {
return static_cast<ImU32>(ImGui::GetTime() * 100) % 100 <= static_cast<ImU32>(ImGui::GetIO().DeltaTime * 100);
@@ -205,7 +203,7 @@ namespace ImGuiExt {
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4());
ImGui::PushItemWidth(ImGui::CalcTextSize(text.c_str()).x + ImGui::GetStyle().FramePadding.x * 2);
ImGui::InputText("##", const_cast<char *>(text.c_str()), text.size(), ImGuiInputTextFlags_ReadOnly | ImGuiInputTextFlags_NoHorizontalScroll);
ImGui::InputText("##", const_cast<char *>(text.c_str()), text.size() + 1, ImGuiInputTextFlags_ReadOnly | ImGuiInputTextFlags_NoHorizontalScroll);
ImGui::PopItemWidth();
ImGui::PopStyleColor();
@@ -237,11 +235,13 @@ namespace ImGuiExt {
inline void TextFormattedWrappedSelectable(std::string_view fmt, auto &&...args) {
// Manually wrap text, using the letter M (generally the widest character in non-monospaced fonts) to calculate the character width to use.
auto text = wolv::util::wrapMonospacedString(
auto text = wolv::util::trim(wolv::util::wrapMonospacedString(
hex::format(fmt, std::forward<decltype(args)>(args)...),
ImGui::CalcTextSize("M").x,
ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ScrollbarSize - ImGui::GetStyle().FrameBorderSize
);
));
auto textSize = ImGui::CalcTextSize(text.c_str());
ImGui::PushID(text.c_str());
@@ -252,8 +252,8 @@ namespace ImGuiExt {
ImGui::InputTextMultiline(
"##",
const_cast<char *>(text.c_str()),
text.size(),
ImVec2(0, -FLT_MIN),
text.size() + 1,
ImVec2(0, textSize.y),
ImGuiInputTextFlags_ReadOnly | ImGuiInputTextFlags_NoHorizontalScroll
);
ImGui::PopItemWidth();
@@ -284,6 +284,7 @@ namespace ImGuiExt {
}
bool InputTextIcon(const char* label, const char *icon, std::string &buffer, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
bool InputTextIconHint(const char* label, const char *icon, const char *hint, std::string &buffer, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
bool InputScalarCallback(const char* label, ImGuiDataType data_type, void* p_data, const char* format, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data);
@@ -292,12 +293,12 @@ namespace ImGuiExt {
bool BitCheckbox(const char* label, bool* v);
bool DimmedButton(const char* label, ImVec2 size = ImVec2(0, 0));
bool DimmedIconButton(const char *symbol, ImVec4 color, ImVec2 size = ImVec2(0, 0));
bool DimmedButtonToggle(const char *icon, bool *v, ImVec2 size);
bool DimmedIconButton(const char *symbol, ImVec4 color, ImVec2 size = ImVec2(0, 0), ImVec2 iconOffset = ImVec2(0, 0));
bool DimmedButtonToggle(const char *icon, bool *v, ImVec2 size = ImVec2(0, 0), ImVec2 iconOffset = ImVec2(0, 0));
bool DimmedIconToggle(const char *icon, bool *v);
bool DimmedIconToggle(const char *iconOn, const char *iconOff, bool *v);
void TextOverlay(const char *text, ImVec2 pos);
void TextOverlay(const char *text, ImVec2 pos, float maxWidth = -1);
bool BeginBox();
void EndBox();

View File

@@ -8,7 +8,6 @@
#include <hex/api/imhex_api.hpp>
#include <hex/api/shortcut_manager.hpp>
#include <hex/api/event_manager.hpp>
#include <hex/api/localization_manager.hpp>
#include <hex/providers/provider.hpp>

View File

@@ -1,11 +1,15 @@
#include <hex/api/achievement_manager.hpp>
#include <hex/api/event_manager.hpp>
#include <hex/api/events/events_interaction.hpp>
#include <hex/helpers/auto_reset.hpp>
#include <hex/helpers/default_paths.hpp>
#include <nlohmann/json.hpp>
#if defined(OS_WEB)
#include <emscripten.h>
#endif
namespace hex {
static AutoReset<std::unordered_map<std::string, std::unordered_map<std::string, std::unique_ptr<Achievement>>>> s_achievements;
@@ -196,8 +200,11 @@ namespace hex {
constexpr static auto AchievementsFile = "achievements.json";
bool AchievementManager::s_initialized = false;
void AchievementManager::loadProgress() {
if (s_initialized)
return;
for (const auto &directory : paths::Config.read()) {
auto path = directory / AchievementsFile;
@@ -212,7 +219,16 @@ namespace hex {
}
try {
auto json = nlohmann::json::parse(file.readString());
#if defined(OS_WEB)
auto data = (char *) MAIN_THREAD_EM_ASM_INT({
let data = localStorage.getItem("achievements");
return data ? stringToNewUTF8(data) : null;
});
#else
auto data = file.readString();
#endif
auto json = nlohmann::json::parse(data);
for (const auto &[categoryName, achievements] : getAchievements()) {
for (const auto &[achievementName, achievement] : achievements) {
@@ -227,6 +243,8 @@ namespace hex {
}
}
}
s_initialized = true;
} catch (const std::exception &e) {
log::error("Failed to load achievements: {}", e.what());
}
@@ -235,6 +253,8 @@ namespace hex {
}
void AchievementManager::storeProgress() {
if (!s_initialized)
loadProgress();
nlohmann::json json;
for (const auto &[categoryName, achievements] : getAchievements()) {
json[categoryName] = nlohmann::json::object();
@@ -247,16 +267,23 @@ namespace hex {
if (json.empty())
return;
for (const auto &directory : paths::Config.write()) {
auto path = directory / AchievementsFile;
#if defined(OS_WEB)
auto data = json.dump();
MAIN_THREAD_EM_ASM({
localStorage.setItem("achievements", UTF8ToString($0));
}, data.c_str());
#else
for (const auto &directory : paths::Config.write()) {
auto path = directory / AchievementsFile;
wolv::io::File file(path, wolv::io::File::Mode::Create);
if (!file.isValid())
continue;
wolv::io::File file(path, wolv::io::File::Mode::Create);
if (!file.isValid())
continue;
file.writeString(json.dump(4));
break;
}
file.writeString(json.dump(4));
break;
}
#endif
}
}

View File

@@ -1,5 +1,6 @@
#include <hex/api/content_registry.hpp>
#include <hex/api/shortcut_manager.hpp>
#include <hex/api/events/requests_provider.hpp>
#include <hex/helpers/fs.hpp>
#include <hex/helpers/logger.hpp>
@@ -38,6 +39,34 @@ namespace hex {
static AutoReset<std::map<std::string, std::map<std::string, std::vector<OnChange>>>> s_onChangeCallbacks;
static void runAllOnChangeCallbacks() {
for (const auto &[category, rest] : *impl::s_onChangeCallbacks) {
for (const auto &[name, callbacks] : rest) {
for (const auto &[id, callback] : callbacks) {
try {
callback(getSetting(category, name, {}));
} catch (const std::exception &e) {
log::error("Failed to load setting [{}/{}]: {}", category, name, e.what());
}
}
}
}
}
void runOnChangeHandlers(const UnlocalizedString &unlocalizedCategory, const UnlocalizedString &unlocalizedName, const nlohmann::json &value) {
if (auto categoryIt = s_onChangeCallbacks->find(unlocalizedCategory); categoryIt != s_onChangeCallbacks->end()) {
if (auto nameIt = categoryIt->second.find(unlocalizedName); nameIt != categoryIt->second.end()) {
for (const auto &[id, callback] : nameIt->second) {
try {
callback(value);
} catch (const nlohmann::json::exception &e) {
log::error("Failed to run onChange handler for setting {}/{}: {}", unlocalizedCategory.get(), unlocalizedName.get(), e.what());
}
}
}
}
}
static AutoReset<nlohmann::json> s_settings;
const nlohmann::json& getSettingsData() {
return s_settings;
@@ -72,24 +101,28 @@ namespace hex {
s_settings = nlohmann::json::parse(data);
}
for (const auto &[category, rest] : *impl::s_onChangeCallbacks) {
for (const auto &[name, callbacks] : rest) {
for (const auto &[id, callback] : callbacks) {
try {
callback(getSetting(category, name, {}));
} catch (const std::exception &e) {
log::error("Failed to load setting [{}/{}]: {}", category, name, e.what());
}
}
}
}
runAllOnChangeCallbacks();
}
void store() {
auto data = s_settings->dump();
if (!s_settings.isValid())
return;
const auto &settingsData = *s_settings;
// During a crash settings can be empty, causing them to be overwritten.
if (settingsData.empty()) {
return;
}
const auto result = settingsData.dump(4);
if (result.empty()) {
return;
}
MAIN_THREAD_EM_ASM({
localStorage.setItem("config", UTF8ToString($0));
}, data.c_str());
}, result.c_str());
}
void clear() {
@@ -115,17 +148,7 @@ namespace hex {
if (!loaded)
store();
for (const auto &[category, rest] : *impl::s_onChangeCallbacks) {
for (const auto &[name, callbacks] : rest) {
for (const auto &[id, callback] : callbacks) {
try {
callback(getSetting(category, name, {}));
} catch (const std::exception &e) {
log::error("Failed to load setting [{}/{}]: {}", category, name, e.what());
}
}
}
}
runAllOnChangeCallbacks();
}
void store() {
@@ -135,7 +158,7 @@ namespace hex {
const auto &settingsData = *s_settings;
// During a crash settings can be empty, causing them to be overwritten.
if (settingsData.empty()) {
if (s_settings->empty()) {
return;
}
@@ -191,6 +214,19 @@ namespace hex {
const auto entry = insertOrGetEntry(subCategory->entries, unlocalizedName);
entry->widget = std::move(widget);
if (entry->widget != nullptr) {
onChange(unlocalizedCategory, unlocalizedName, [widget = entry->widget.get(), unlocalizedCategory, unlocalizedName](const SettingsValue &) {
try {
auto defaultValue = widget->store();
widget->load(ContentRegistry::Settings::impl::getSetting(unlocalizedCategory, unlocalizedName, defaultValue));
widget->onChanged();
} catch (const std::exception &e) {
log::error("Failed to load setting [{} / {}]: {}", unlocalizedCategory.get(), unlocalizedName.get(), e.what());
}
});
runOnChangeHandlers(unlocalizedCategory, unlocalizedName, getSetting(unlocalizedCategory, unlocalizedName, entry->widget->store()));
}
return entry->widget.get();
}
@@ -199,20 +235,6 @@ namespace hex {
hex::log::error("Failed to read setting {}/{}: {}", unlocalizedCategory.get(), unlocalizedName.get(), e.what());
}
void runOnChangeHandlers(const UnlocalizedString &unlocalizedCategory, const UnlocalizedString &unlocalizedName, const nlohmann::json &value) {
if (auto categoryIt = s_onChangeCallbacks->find(unlocalizedCategory); categoryIt != s_onChangeCallbacks->end()) {
if (auto nameIt = categoryIt->second.find(unlocalizedName); nameIt != categoryIt->second.end()) {
for (const auto &[id, callback] : nameIt->second) {
try {
callback(value);
} catch (const nlohmann::json::exception &e) {
log::error("Failed to run onChange handler for setting {}/{}: {}", unlocalizedCategory.get(), unlocalizedName.get(), e.what());
}
}
}
}
}
}
void setCategoryDescription(const UnlocalizedString &unlocalizedCategory, const UnlocalizedString &unlocalizedDescription) {
@@ -314,7 +336,7 @@ namespace hex {
bool SliderDataSize::draw(const std::string &name) {
return ImGuiExt::SliderBytes(name.c_str(), &m_value, m_min, m_max);
return ImGuiExt::SliderBytes(name.c_str(), &m_value, m_min, m_max, m_stepSize);
}
void SliderDataSize::load(const nlohmann::json &data) {
@@ -330,17 +352,34 @@ namespace hex {
}
ColorPicker::ColorPicker(ImColor defaultColor) {
m_value = {
defaultColor.Value.x,
defaultColor.Value.y,
defaultColor.Value.z,
defaultColor.Value.w
ColorPicker::ColorPicker(ImColor defaultColor, ImGuiColorEditFlags flags) {
m_defaultValue = m_value = {
defaultColor.Value.x,
defaultColor.Value.y,
defaultColor.Value.z,
defaultColor.Value.w
};
m_flags = flags;
}
bool ColorPicker::draw(const std::string &name) {
return ImGui::ColorEdit4(name.c_str(), m_value.data(), ImGuiColorEditFlags_NoInputs);
ImGui::PushID(name.c_str());
auto result = ImGui::ColorEdit4("##color_picker", m_value.data(), ImGuiColorEditFlags_NoInputs | m_flags);
ImGui::SameLine();
if (ImGui::Button("X", ImGui::GetStyle().FramePadding * 2 + ImVec2(ImGui::GetTextLineHeight(), ImGui::GetTextLineHeight()))) {
m_value = m_defaultValue;
result = true;
}
ImGui::SameLine();
ImGui::TextUnformatted(name.c_str());
ImGui::PopID();
return result;
}
void ColorPicker::load(const nlohmann::json &data) {
@@ -366,7 +405,7 @@ namespace hex {
bool DropDown::draw(const std::string &name) {
auto preview = "";
if (static_cast<size_t>(m_value) < m_items.size())
preview = m_items[m_value].c_str();
preview = m_items[m_value].get().c_str();
bool changed = false;
if (ImGui::BeginCombo(name.c_str(), Lang(preview))) {
@@ -552,6 +591,11 @@ namespace hex {
return *s_functions;
}
static AutoReset<std::vector<TypeDefinition>> s_types;
const std::vector<TypeDefinition>& getTypes() {
return *s_types;
}
}
static std::string getFunctionName(const pl::api::Namespace &ns, const std::string &name) {
@@ -605,12 +649,16 @@ namespace hex {
runtime.addFunction(ns, name, paramCount, callback);
}
for (const auto &[ns, name, paramCount, callback] : impl::getTypes()) {
runtime.addType(ns, name, paramCount, callback);
}
for (const auto &[name, callback] : impl::getPragmas()) {
runtime.addPragma(name, callback);
}
runtime.addDefine("__IMHEX__");
runtime.addDefine("__IMHEX_VERSION__", ImHexApi::System::getImHexVersion());
runtime.addDefine("__IMHEX_VERSION__", ImHexApi::System::getImHexVersion().get());
}
void addPragma(const std::string &name, const pl::api::PragmaHandler &handler) {
@@ -639,6 +687,15 @@ namespace hex {
});
}
void addType(const pl::api::Namespace &ns, const std::string &name, pl::api::FunctionParameterCount parameterCount, const pl::api::TypeCallback &func) {
log::debug("Registered new pattern language type: {}", getFunctionName(ns, name));
impl::s_types->push_back({
ns, name,
parameterCount, func
});
}
void addVisualizer(const std::string &name, const impl::VisualizerFunctionCallback &function, pl::api::FunctionParameterCount parameterCount) {
log::debug("Registered new pattern visualizer function: {}", name);
@@ -723,6 +780,14 @@ namespace hex {
impl::s_entries->push_back({ unlocalizedName, requiredSize, maxSize, std::move(displayGeneratorFunction), std::move(editingFunction) });
}
void drawMenuItems(const std::function<void()> &function) {
if (ImGui::BeginPopup("##DataInspectorRowContextMenu")) {
function();
ImGui::Separator();
ImGui::EndPopup();
}
}
}
namespace ContentRegistry::DataProcessorNode {
@@ -884,14 +949,14 @@ namespace hex {
coloredIcon.color = ImGuiCustomCol_ToolbarGray;
impl::s_menuItems->insert({
priority, impl::MenuItem { unlocalizedMainMenuNames, coloredIcon, std::make_unique<Shortcut>(shortcut), view, function, enabledCallback, selectedCallback, -1 }
priority, impl::MenuItem { unlocalizedMainMenuNames, coloredIcon, shortcut, view, function, enabledCallback, selectedCallback, -1 }
});
if (shortcut != Shortcut::None) {
if (shortcut.isLocal() && view != nullptr)
ShortcutManager::addShortcut(view, shortcut, unlocalizedMainMenuNames.back(), function);
ShortcutManager::addShortcut(view, shortcut, unlocalizedMainMenuNames, function, enabledCallback);
else
ShortcutManager::addGlobalShortcut(shortcut, unlocalizedMainMenuNames.back(), function);
ShortcutManager::addGlobalShortcut(shortcut, unlocalizedMainMenuNames, function, enabledCallback);
}
}
@@ -904,14 +969,14 @@ namespace hex {
unlocalizedMainMenuNames.emplace_back(impl::SubMenuValue);
impl::s_menuItems->insert({
priority, impl::MenuItem { unlocalizedMainMenuNames, icon, std::make_unique<Shortcut>(), nullptr, function, enabledCallback, []{ return false; }, -1 }
priority, impl::MenuItem { unlocalizedMainMenuNames, icon, Shortcut::None, nullptr, function, enabledCallback, []{ return false; }, -1 }
});
}
void addMenuItemSeparator(std::vector<UnlocalizedString> unlocalizedMainMenuNames, u32 priority) {
unlocalizedMainMenuNames.emplace_back(impl::SeparatorValue);
impl::s_menuItems->insert({
priority, impl::MenuItem { unlocalizedMainMenuNames, "", std::make_unique<Shortcut>(), nullptr, []{}, []{ return true; }, []{ return false; }, -1 }
priority, impl::MenuItem { unlocalizedMainMenuNames, "", Shortcut::None, nullptr, []{}, []{ return true; }, []{ return false; }, -1 }
});
}
@@ -1199,7 +1264,7 @@ namespace hex {
class Service {
public:
Service(std::string name, std::jthread thread) : m_name(std::move(name)), m_thread(std::move(thread)) { }
Service(const UnlocalizedString &unlocalizedName, std::jthread thread) : m_unlocalizedName(std::move(unlocalizedName)), m_thread(std::move(thread)) { }
Service(const Service&) = delete;
Service(Service &&) = default;
~Service() {
@@ -1211,8 +1276,8 @@ namespace hex {
Service& operator=(const Service&) = delete;
Service& operator=(Service &&) = default;
[[nodiscard]] const std::string& getName() const {
return m_name;
[[nodiscard]] const UnlocalizedString& getUnlocalizedName() const {
return m_unlocalizedName;
}
[[nodiscard]] const std::jthread& getThread() const {
@@ -1220,7 +1285,7 @@ namespace hex {
}
private:
std::string m_name;
UnlocalizedString m_unlocalizedName;
std::jthread m_thread;
};
@@ -1355,4 +1420,23 @@ namespace hex {
}
namespace ContentRegistry::Disassembler {
namespace impl {
static AutoReset<std::map<std::string, impl::CreatorFunction>> s_architectures;
void addArchitectureCreator(impl::CreatorFunction function) {
const auto arch = function();
(*s_architectures)[arch->getName()] = std::move(function);
}
const std::map<std::string, impl::CreatorFunction>& getArchitectures() {
return *s_architectures;
}
}
}
}

View File

@@ -21,4 +21,30 @@ namespace hex {
}
bool EventManager::isAlreadyRegistered(void *token, impl::EventId id) {
if (getTokenStore().contains(token)) {
auto&& [begin, end] = getTokenStore().equal_range(token);
return std::any_of(begin, end, [&](auto &item) {
return item.second->first == id;
});
}
return false;
}
void EventManager::unsubscribe(void *token, impl::EventId id) {
auto &tokenStore = getTokenStore();
auto iter = std::find_if(tokenStore.begin(), tokenStore.end(), [&](auto &item) {
return item.first == token && item.second->first == id;
});
if (iter != tokenStore.end()) {
getEvents().erase(iter->second);
tokenStore.erase(iter);
}
}
}

View File

@@ -1,6 +1,13 @@
#include <hex/api/imhex_api.hpp>
#include <hex/api/event_manager.hpp>
#include <hex/api/events/events_provider.hpp>
#include <hex/api/events/events_lifecycle.hpp>
#include <hex/api/events/events_gui.hpp>
#include <hex/api/events/requests_interaction.hpp>
#include <hex/api/events/requests_lifecycle.hpp>
#include <hex/api/events/requests_provider.hpp>
#include <hex/api/events/requests_gui.hpp>
#include <hex/api/task_manager.hpp>
#include <hex/helpers/fmt.hpp>
#include <hex/helpers/utils.hpp>
@@ -11,6 +18,7 @@
#include <wolv/utils/string.hpp>
#include <utility>
#include <numeric>
#include <imgui.h>
#include <imgui_internal.h>
@@ -18,13 +26,20 @@
#include <algorithm>
#include <GLFW/glfw3.h>
#include <hex/helpers/utils_macos.hpp>
#if defined(OS_WINDOWS)
#include <windows.h>
#include <DSRole.h>
#else
#include <sys/utsname.h>
#include <unistd.h>
#endif
#if defined(OS_WEB)
#include <emscripten.h>
#endif
namespace hex {
@@ -268,7 +283,7 @@ namespace hex {
static i64 s_currentProvider = -1;
static AutoReset<std::vector<std::unique_ptr<prv::Provider>>> s_providers;
static AutoReset<std::list<std::unique_ptr<prv::Provider>>> s_providersToRemove;
static AutoReset<std::map<prv::Provider*, std::unique_ptr<prv::Provider>>> s_providersToRemove;
namespace impl {
@@ -337,8 +352,11 @@ namespace hex {
}
void markDirty() {
get()->markDirty();
EventProviderDirtied::post(get());
const auto provider = get();
if (!provider->isDirty()) {
provider->markDirty();
EventProviderDirtied::post(provider);
}
}
void resetDirty() {
@@ -430,7 +448,8 @@ namespace hex {
// Move provider over to a list of providers to delete
eraseMutex.lock();
auto removeIt = s_providersToRemove->emplace(s_providersToRemove->end(), std::move(*it));
auto providerToRemove = it->get();
(*s_providersToRemove)[providerToRemove] = std::move(*it);
eraseMutex.unlock();
// Remove left over references from the main provider list
@@ -443,16 +462,16 @@ namespace hex {
if (s_providers->empty())
EventProviderChanged::post(provider, nullptr);
EventProviderClosed::post(removeIt->get());
EventProviderClosed::post(it->get());
RequestUpdateWindowTitle::post();
// Do the destruction of the provider in the background once all tasks have finished
TaskManager::runWhenTasksFinished([removeIt] {
EventProviderDeleted::post(removeIt->get());
TaskManager::createBackgroundTask("Closing Provider", [removeIt](Task &) {
TaskManager::runWhenTasksFinished([providerToRemove] {
EventProviderDeleted::post(providerToRemove);
TaskManager::createBackgroundTask("Closing Provider", [providerToRemove](Task &) {
eraseMutex.lock();
auto provider = std::move(*removeIt);
s_providersToRemove->erase(removeIt);
auto provider = std::move((*s_providersToRemove)[providerToRemove]);
s_providersToRemove->erase(providerToRemove);
eraseMutex.unlock();
provider->close();
@@ -604,6 +623,27 @@ namespace hex {
return impl::s_nativeScale;
}
float getBackingScaleFactor() {
#if defined(OS_WINDOWS)
return 1.0F;
#elif defined(OS_MACOS)
return ::getBackingScaleFactor();
#elif defined(OS_LINUX)
if (std::string_view(::getenv("XDG_SESSION_TYPE")) == "x11")
return 1.0F;
else {
float xScale = 0, yScale = 0;
glfwGetMonitorContentScale(glfwGetPrimaryMonitor(), &xScale, &yScale);
return std::midpoint(xScale, yScale);
}
#elif defined(OS_WEB)
return 1.0F;
#else
return 1.0F;
#endif
}
ImVec2 getMainWindowPosition() {
if ((ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable) != ImGuiConfigFlags_None)
@@ -641,6 +681,14 @@ namespace hex {
return hex::getContainingModule(reinterpret_cast<void*>(&getLibImHexModuleHandle));
}
void addMigrationRoutine(SemanticVersion migrationVersion, std::function<void()> function) {
EventImHexUpdated::subscribe([migrationVersion, function](const SemanticVersion &oldVersion, const SemanticVersion &newVersion) {
if (oldVersion < migrationVersion && newVersion >= migrationVersion) {
function();
}
});
}
const std::map<std::string, std::string>& getInitArguments() {
return *impl::s_initArguments;
@@ -685,6 +733,27 @@ namespace hex {
return impl::s_glRenderer;
}
bool isCorporateEnvironment() {
#if defined(OS_WINDOWS)
{
DSROLE_PRIMARY_DOMAIN_INFO_BASIC * info;
if ((DsRoleGetPrimaryDomainInformation(NULL, DsRolePrimaryDomainInfoBasic, (PBYTE *)&info) == ERROR_SUCCESS) && (info != nullptr))
{
bool result = std::wstring(info->DomainNameFlat).empty();
DsRoleFreeMemory(info);
return result;
} else {
DWORD size = 1024;
::GetComputerNameExA(ComputerNameDnsDomain, nullptr, &size);
return size > 0;
}
}
#else
return false;
#endif
}
bool isPortableVersion() {
static std::optional<bool> portable;
if (portable.has_value())
@@ -790,16 +859,11 @@ namespace hex {
return { { name, version } };
}
std::string getImHexVersion(bool withBuildType) {
SemanticVersion getImHexVersion() {
#if defined IMHEX_VERSION
if (withBuildType) {
return IMHEX_VERSION;
} else {
auto version = std::string(IMHEX_VERSION);
return version.substr(0, version.find('-'));
}
return SemanticVersion(IMHEX_VERSION);
#else
return "Unknown";
return {};
#endif
}
@@ -811,7 +875,7 @@ namespace hex {
return std::string(GIT_COMMIT_HASH_LONG).substr(0, 7);
}
#else
hex::unused(longHash);
std::ignore = longHash;
return "Unknown";
#endif
}
@@ -833,7 +897,7 @@ namespace hex {
}
bool isNightlyBuild() {
return getImHexVersion(false).ends_with("WIP");
return getImHexVersion().nightly();
}
bool updateImHex(UpdateType updateType) {
@@ -931,11 +995,6 @@ namespace hex {
return *s_fonts;
}
static AutoReset<std::fs::path> s_customFontPath;
void setCustomFontPath(const std::fs::path &path) {
s_customFontPath = path;
}
static float s_fontSize = DefaultFontSize;
void setFontSize(float size) {
s_fontSize = size;
@@ -953,6 +1012,10 @@ namespace hex {
s_italicFont = italic;
}
static AutoReset<std::map<UnlocalizedString, ImFont*>> s_fontDefinitions;
std::map<UnlocalizedString, ImFont*>& getFontDefinitions() {
return *s_fontDefinitions;
}
}
@@ -1017,10 +1080,6 @@ namespace hex {
});
}
const std::fs::path& getCustomFontPath() {
return impl::s_customFontPath;
}
float getFontSize() {
return impl::s_fontSize;
}
@@ -1029,6 +1088,14 @@ namespace hex {
return impl::s_fontAtlas;
}
void registerFont(const UnlocalizedString &fontName) {
(*impl::s_fontDefinitions)[fontName] = nullptr;
}
ImFont* getFont(const UnlocalizedString &fontName) {
return (*impl::s_fontDefinitions)[fontName];
}
ImFont* Bold() {
return impl::s_boldFont;
}

View File

@@ -10,7 +10,7 @@ namespace hex {
AutoReset<std::string> s_fallbackLanguage;
AutoReset<std::string> s_selectedLanguage;
AutoReset<std::map<std::string, std::string>> s_currStrings;
AutoReset<std::map<size_t, std::string>> s_currStrings;
}
@@ -41,22 +41,34 @@ namespace hex {
return m_entries;
}
void loadLanguage(const std::string &language) {
static void loadLanguageDefinitions(const std::vector<LanguageDefinition> &definitions) {
for (const auto &definition : definitions) {
const auto &entries = definition.getEntries();
if (entries.empty())
continue;
for (const auto &[key, value] : entries) {
if (value.empty())
continue;
s_currStrings->emplace(LangConst::hash(key), value);
}
}
}
void loadLanguage(std::string language) {
auto &definitions = ContentRegistry::Language::impl::getLanguageDefinitions();
const auto& fallbackLanguage = getFallbackLanguage();
if (!definitions.contains(language))
return;
language = fallbackLanguage;
s_currStrings->clear();
for (const auto &definition : definitions.at(language))
s_currStrings->insert(definition.getEntries().begin(), definition.getEntries().end());
loadLanguageDefinitions(definitions.at(language));
const auto& fallbackLanguage = getFallbackLanguage();
if (language != fallbackLanguage && definitions.contains(fallbackLanguage)) {
for (const auto &definition : definitions.at(fallbackLanguage))
s_currStrings->insert(definition.getEntries().begin(), definition.getEntries().end());
}
if (language != fallbackLanguage)
loadLanguageDefinitions(definitions.at(fallbackLanguage));
s_selectedLanguage = language;
}
@@ -98,11 +110,11 @@ namespace hex {
}
Lang::Lang(const char *unlocalizedString) : m_unlocalizedString(unlocalizedString) { }
Lang::Lang(const std::string &unlocalizedString) : m_unlocalizedString(unlocalizedString) { }
Lang::Lang(const UnlocalizedString &unlocalizedString) : m_unlocalizedString(unlocalizedString.get()) { }
Lang::Lang(std::string_view unlocalizedString) : m_unlocalizedString(unlocalizedString) { }
Lang::Lang(const char *unlocalizedString) : m_entryHash(LangConst::hash(unlocalizedString)), m_unlocalizedString(unlocalizedString) { }
Lang::Lang(const std::string &unlocalizedString) : m_entryHash(LangConst::hash(unlocalizedString)), m_unlocalizedString(unlocalizedString) { }
Lang::Lang(const LangConst &localizedString) : m_entryHash(localizedString.m_entryHash), m_unlocalizedString(localizedString.m_unlocalizedString) { }
Lang::Lang(const UnlocalizedString &unlocalizedString) : m_entryHash(LangConst::hash(unlocalizedString.get())), m_unlocalizedString(unlocalizedString.get()) { }
Lang::Lang(std::string_view unlocalizedString) : m_entryHash(LangConst::hash(unlocalizedString)), m_unlocalizedString(unlocalizedString) { }
Lang::operator std::string() const {
return get();
@@ -113,43 +125,41 @@ namespace hex {
}
Lang::operator const char *() const {
return get().c_str();
return get();
}
std::string operator+(const std::string &&left, const Lang &&right) {
return left + static_cast<std::string>(right);
const char *Lang::get() const {
const auto &lang = *LocalizationManager::s_currStrings;
const auto it = lang.find(m_entryHash);
if (it == lang.end()) {
return m_unlocalizedString.c_str();
} else {
return it->second.c_str();
}
}
std::string operator+(const Lang &&left, const std::string &&right) {
return static_cast<std::string>(left) + right;
LangConst::operator std::string() const {
return get();
}
std::string operator+(const Lang &&left, const Lang &&right) {
return static_cast<std::string>(left) + static_cast<std::string>(right);
LangConst::operator std::string_view() const {
return get();
}
std::string operator+(const std::string_view &&left, const Lang &&right) {
return std::string(left) + static_cast<std::string>(right);
LangConst::operator const char *() const {
return get();
}
std::string operator+(const Lang &&left, const std::string_view &&right) {
return static_cast<std::string>(left) + std::string(right);
}
const char *LangConst::get() const {
const auto &lang = *LocalizationManager::s_currStrings;
std::string operator+(const char *left, const Lang &&right) {
return left + static_cast<std::string>(right);
}
std::string operator+(const Lang &&left, const char *right) {
return static_cast<std::string>(left) + right;
}
const std::string &Lang::get() const {
auto &lang = LocalizationManager::s_currStrings;
if (lang->contains(m_unlocalizedString))
return lang->at(m_unlocalizedString);
else
const auto it = lang.find(m_entryHash);
if (it == lang.end()) {
return m_unlocalizedString;
} else {
return it->second.c_str();
}
}
}

View File

@@ -112,10 +112,6 @@ namespace hex {
}
Plugin::~Plugin() {
if (isLoaded()) {
log::info("Trying to unload plugin '{}'", getPluginName());
}
unloadLibrary(m_handle, m_path);
}
@@ -133,7 +129,7 @@ namespace hex {
const auto requestedVersion = getCompatibleVersion();
const auto imhexVersion = ImHexApi::System::getImHexVersion();
const auto imhexVersion = ImHexApi::System::getImHexVersion().get();
if (!imhexVersion.starts_with(requestedVersion)) {
if (requestedVersion.empty()) {
log::warn("Plugin '{}' did not specify a compatible version, assuming it is compatible with the current version of ImHex.", wolv::util::toUTF8String(m_path.filename()));
@@ -335,7 +331,7 @@ namespace hex {
void PluginManager::initializeNewPlugins() {
for (const auto &plugin : getPlugins()) {
if (!plugin.isLoaded())
hex::unused(plugin.initializePlugin());
std::ignore = plugin.initializePlugin();
}
}

View File

@@ -1,6 +1,7 @@
#include <hex/api/shortcut_manager.hpp>
#include <imgui.h>
#include <hex/api/content_registry.hpp>
#include <hex/api/task_manager.hpp>
#include <hex/helpers/auto_reset.hpp>
#include <hex/ui/view.hpp>
@@ -12,29 +13,300 @@ namespace hex {
AutoReset<std::map<Shortcut, ShortcutManager::ShortcutEntry>> s_globalShortcuts;
std::atomic<bool> s_paused;
std::optional<Shortcut> s_prevShortcut;
bool s_macOSMode = false;
AutoReset<std::optional<UnlocalizedString>> s_lastShortcutMainMenu;
}
Shortcut operator+(const Key &lhs, const Key &rhs) {
Shortcut result;
result.m_keys = { lhs, rhs };
void ShortcutManager::addGlobalShortcut(const Shortcut &shortcut, const UnlocalizedString &unlocalizedName, const std::function<void()> &callback) {
s_globalShortcuts->insert({ shortcut, { shortcut, unlocalizedName, callback } });
return result;
}
void ShortcutManager::addShortcut(View *view, const Shortcut &shortcut, const UnlocalizedString &unlocalizedName, const std::function<void()> &callback) {
view->m_shortcuts.insert({ shortcut + CurrentView, { shortcut, unlocalizedName, callback } });
Shortcut::Shortcut(Keys key) : m_keys({ key }) {
}
Shortcut::Shortcut(std::set<Key> keys) : m_keys(std::move(keys)) {
}
Shortcut Shortcut::operator+(const Key &other) const {
Shortcut result = *this;
result.m_keys.insert(other);
return result;
}
Shortcut& Shortcut::operator+=(const Key &other) {
m_keys.insert(other);
return *this;
}
bool Shortcut::operator<(const Shortcut &other) const {
return m_keys < other.m_keys;
}
bool Shortcut::operator==(const Shortcut &other) const {
return m_keys == other.m_keys;
}
bool Shortcut::isLocal() const {
return m_keys.contains(CurrentView);
}
const std::set<Key>& Shortcut::getKeys() const {
return m_keys;
}
bool Shortcut::has(Key key) const {
return m_keys.contains(key);
}
bool Shortcut::matches(const Shortcut& other) const {
auto left = this->m_keys;
auto right = other.m_keys;
left.erase(CurrentView);
left.erase(AllowWhileTyping);
right.erase(CurrentView);
right.erase(AllowWhileTyping);
return left == right;
}
std::string Shortcut::toString() const {
std::string result;
const auto CTRL_NAME = s_macOSMode ? "" : "CTRL";
const auto ALT_NAME = s_macOSMode ? "" : "ALT";
const auto SHIFT_NAME = s_macOSMode ? "" : "SHIFT";
const auto SUPER_NAME = s_macOSMode ? "" : "SUPER";
const auto Concatination = s_macOSMode ? " " : " + ";
auto keys = m_keys;
if (keys.erase(CTRL) > 0 || (!s_macOSMode && keys.erase(CTRLCMD) > 0)) {
result += CTRL_NAME;
result += Concatination;
}
if (keys.erase(ALT) > 0) {
result += ALT_NAME;
result += Concatination;
}
if (keys.erase(SHIFT) > 0) {
result += SHIFT_NAME;
result += Concatination;
}
if (keys.erase(SUPER) > 0 || (s_macOSMode && keys.erase(CTRLCMD) > 0)) {
result += SUPER_NAME;
result += Concatination;
}
keys.erase(CurrentView);
for (const auto &key : keys) {
switch (Keys(key.getKeyCode())) {
case Keys::Space: result += ""; break;
case Keys::Apostrophe: result += "'"; break;
case Keys::Comma: result += ","; break;
case Keys::Minus: result += "-"; break;
case Keys::Period: result += "."; break;
case Keys::Slash: result += "/"; break;
case Keys::Num0: result += "0"; break;
case Keys::Num1: result += "1"; break;
case Keys::Num2: result += "2"; break;
case Keys::Num3: result += "3"; break;
case Keys::Num4: result += "4"; break;
case Keys::Num5: result += "5"; break;
case Keys::Num6: result += "6"; break;
case Keys::Num7: result += "7"; break;
case Keys::Num8: result += "8"; break;
case Keys::Num9: result += "9"; break;
case Keys::Semicolon: result += ";"; break;
case Keys::Equals: result += "="; break;
case Keys::A: result += "A"; break;
case Keys::B: result += "B"; break;
case Keys::C: result += "C"; break;
case Keys::D: result += "D"; break;
case Keys::E: result += "E"; break;
case Keys::F: result += "F"; break;
case Keys::G: result += "G"; break;
case Keys::H: result += "H"; break;
case Keys::I: result += "I"; break;
case Keys::J: result += "J"; break;
case Keys::K: result += "K"; break;
case Keys::L: result += "L"; break;
case Keys::M: result += "M"; break;
case Keys::N: result += "N"; break;
case Keys::O: result += "O"; break;
case Keys::P: result += "P"; break;
case Keys::Q: result += "Q"; break;
case Keys::R: result += "R"; break;
case Keys::S: result += "S"; break;
case Keys::T: result += "T"; break;
case Keys::U: result += "U"; break;
case Keys::V: result += "V"; break;
case Keys::W: result += "W"; break;
case Keys::X: result += "X"; break;
case Keys::Y: result += "Y"; break;
case Keys::Z: result += "Z"; break;
case Keys::LeftBracket: result += "["; break;
case Keys::Backslash: result += "\\"; break;
case Keys::RightBracket: result += "]"; break;
case Keys::GraveAccent: result += "`"; break;
case Keys::World1: result += "WORLD1"; break;
case Keys::World2: result += "WORLD2"; break;
case Keys::Escape: result += "ESC"; break;
case Keys::Enter: result += ""; break;
case Keys::Tab: result += ""; break;
case Keys::Backspace: result += ""; break;
case Keys::Insert: result += "INSERT"; break;
case Keys::Delete: result += "DELETE"; break;
case Keys::Right: result += "RIGHT"; break;
case Keys::Left: result += "LEFT"; break;
case Keys::Down: result += "DOWN"; break;
case Keys::Up: result += "UP"; break;
case Keys::PageUp: result += "PAGEUP"; break;
case Keys::PageDown: result += "PAGEDOWN"; break;
case Keys::Home: result += "HOME"; break;
case Keys::End: result += "END"; break;
case Keys::CapsLock: result += ""; break;
case Keys::ScrollLock: result += "SCROLLLOCK"; break;
case Keys::NumLock: result += "NUMLOCK"; break;
case Keys::PrintScreen: result += "PRINTSCREEN"; break;
case Keys::Pause: result += "PAUSE"; break;
case Keys::F1: result += "F1"; break;
case Keys::F2: result += "F2"; break;
case Keys::F3: result += "F3"; break;
case Keys::F4: result += "F4"; break;
case Keys::F5: result += "F5"; break;
case Keys::F6: result += "F6"; break;
case Keys::F7: result += "F7"; break;
case Keys::F8: result += "F8"; break;
case Keys::F9: result += "F9"; break;
case Keys::F10: result += "F10"; break;
case Keys::F11: result += "F11"; break;
case Keys::F12: result += "F12"; break;
case Keys::F13: result += "F13"; break;
case Keys::F14: result += "F14"; break;
case Keys::F15: result += "F15"; break;
case Keys::F16: result += "F16"; break;
case Keys::F17: result += "F17"; break;
case Keys::F18: result += "F18"; break;
case Keys::F19: result += "F19"; break;
case Keys::F20: result += "F20"; break;
case Keys::F21: result += "F21"; break;
case Keys::F22: result += "F22"; break;
case Keys::F23: result += "F23"; break;
case Keys::F24: result += "F24"; break;
case Keys::F25: result += "F25"; break;
case Keys::KeyPad0: result += "KP0"; break;
case Keys::KeyPad1: result += "KP1"; break;
case Keys::KeyPad2: result += "KP2"; break;
case Keys::KeyPad3: result += "KP3"; break;
case Keys::KeyPad4: result += "KP4"; break;
case Keys::KeyPad5: result += "KP5"; break;
case Keys::KeyPad6: result += "KP6"; break;
case Keys::KeyPad7: result += "KP7"; break;
case Keys::KeyPad8: result += "KP8"; break;
case Keys::KeyPad9: result += "KP9"; break;
case Keys::KeyPadDecimal: result += "KPDECIMAL"; break;
case Keys::KeyPadDivide: result += "KPDIVIDE"; break;
case Keys::KeyPadMultiply: result += "KPMULTIPLY"; break;
case Keys::KeyPadSubtract: result += "KPSUBTRACT"; break;
case Keys::KeyPadAdd: result += "KPADD"; break;
case Keys::KeyPadEnter: result += "KPENTER"; break;
case Keys::KeyPadEqual: result += "KPEQUAL"; break;
case Keys::Menu: result += "MENU"; break;
default:
continue;
}
result += Concatination;
}
if (result.ends_with(Concatination))
result = result.substr(0, result.size() - strlen(Concatination));
return result;
}
KeyEquivalent Shortcut::toKeyEquivalent() const {
#if defined(OS_MACOS)
if (*this == None)
return { };
KeyEquivalent result = {};
result.valid = true;
for (const auto &key : m_keys) {
switch (key.getKeyCode()) {
case CTRL.getKeyCode():
result.ctrl = true;
break;
case SHIFT.getKeyCode():
result.shift = true;
break;
case ALT.getKeyCode():
result.opt = true;
break;
case SUPER.getKeyCode():
case CTRLCMD.getKeyCode():
result.cmd = true;
break;
case CurrentView.getKeyCode(): break;
case AllowWhileTyping.getKeyCode(): break;
default:
macosGetKey(Keys(key.getKeyCode()), &result.key);
break;
}
}
return result;
#else
return { };
#endif
}
void ShortcutManager::addGlobalShortcut(const Shortcut &shortcut, const std::vector<UnlocalizedString> &unlocalizedName, const std::function<void()> &callback, const EnabledCallback &enabledCallback) {
log::debug("Adding global shortcut {} for {}", shortcut.toString(), unlocalizedName.back().get());
auto [it, inserted] = s_globalShortcuts->insert({ shortcut, { shortcut, unlocalizedName, callback, enabledCallback } });
if (!inserted) log::error("Failed to add shortcut!");
}
void ShortcutManager::addGlobalShortcut(const Shortcut &shortcut, const UnlocalizedString &unlocalizedName, const std::function<void()> &callback, const EnabledCallback &enabledCallback) {
log::debug("Adding global shortcut {} for {}", shortcut.toString(), unlocalizedName.get());
auto [it, inserted] = s_globalShortcuts->insert({ shortcut, { shortcut, { unlocalizedName }, callback, enabledCallback } });
if (!inserted) log::error("Failed to add shortcut!");
}
void ShortcutManager::addShortcut(View *view, const Shortcut &shortcut, const std::vector<UnlocalizedString> &unlocalizedName, const std::function<void()> &callback, const EnabledCallback &enabledCallback) {
log::debug("Adding shortcut {} for {}", shortcut.toString(), unlocalizedName.back().get());
auto [it, inserted] = view->m_shortcuts.insert({ shortcut + CurrentView, { shortcut, unlocalizedName, callback, enabledCallback } });
if (!inserted) log::error("Failed to add shortcut!");
}
void ShortcutManager::addShortcut(View *view, const Shortcut &shortcut, const UnlocalizedString &unlocalizedName, const std::function<void()> &callback, const EnabledCallback &enabledCallback) {
log::debug("Adding shortcut {} for {}", shortcut.toString(), unlocalizedName.get());
auto [it, inserted] = view->m_shortcuts.insert({ shortcut + CurrentView, { shortcut, { unlocalizedName }, callback, enabledCallback } });
if (!inserted) log::error("Failed to add shortcut!");
}
static Shortcut getShortcut(bool ctrl, bool alt, bool shift, bool super, bool focused, u32 keyCode) {
Shortcut pressedShortcut;
if (ctrl)
pressedShortcut += CTRL;
pressedShortcut += s_macOSMode ? CTRL : CTRLCMD;
if (alt)
pressedShortcut += ALT;
if (shift)
pressedShortcut += SHIFT;
if (super)
pressedShortcut += SUPER;
pressedShortcut += s_macOSMode ? CTRLCMD : SUPER;
if (focused)
pressedShortcut += CurrentView;
@@ -43,17 +315,30 @@ namespace hex {
return pressedShortcut;
}
static void processShortcut(const Shortcut &shortcut, const std::map<Shortcut, ShortcutManager::ShortcutEntry> &shortcuts) {
static void processShortcut(Shortcut shortcut, const std::map<Shortcut, ShortcutManager::ShortcutEntry> &shortcuts) {
if (s_paused) return;
if (ImGui::IsPopupOpen(ImGuiID(0), ImGuiPopupFlags_AnyPopupId))
return;
if (shortcuts.contains(shortcut + AllowWhileTyping)) {
shortcuts.at(shortcut + AllowWhileTyping).callback();
} else if (shortcuts.contains(shortcut)) {
if (!ImGui::GetIO().WantTextInput)
shortcuts.at(shortcut).callback();
const bool currentlyTyping = ImGui::GetIO().WantTextInput;
auto it = shortcuts.find(shortcut + AllowWhileTyping);
if (!currentlyTyping && it == shortcuts.end()) {
if (it == shortcuts.end())
it = shortcuts.find(shortcut);
}
if (it != shortcuts.end()) {
const auto &[foundShortcut, entry] = *it;
if (entry.enabledCallback()) {
entry.callback();
if (!entry.unlocalizedName.empty()) {
s_lastShortcutMainMenu = entry.unlocalizedName.front();
}
}
}
}
@@ -73,6 +358,15 @@ namespace hex {
processShortcut(pressedShortcut, s_globalShortcuts);
}
std::optional<UnlocalizedString> ShortcutManager::getLastActivatedMenu() {
return *s_lastShortcutMainMenu;
}
void ShortcutManager::resetLastActivatedMenu() {
s_lastShortcutMainMenu->reset();
}
void ShortcutManager::clearShortcuts() {
s_globalShortcuts->clear();
}
@@ -122,10 +416,13 @@ namespace hex {
return true;
}
bool ShortcutManager::updateShortcut(const Shortcut &oldShortcut, const Shortcut &newShortcut, View *view) {
if (oldShortcut == newShortcut)
bool ShortcutManager::updateShortcut(const Shortcut &oldShortcut, Shortcut newShortcut, View *view) {
if (oldShortcut.matches(newShortcut))
return true;
if (oldShortcut.has(AllowWhileTyping))
newShortcut += AllowWhileTyping;
bool result;
if (view != nullptr) {
result = updateShortcutImpl(oldShortcut + CurrentView, newShortcut + CurrentView , view->m_shortcuts);
@@ -134,9 +431,9 @@ namespace hex {
}
if (result) {
for (auto &[priority, menuItem] : ContentRegistry::Interface::impl::getMenuItems()) {
if (menuItem.view == view && *menuItem.shortcut == oldShortcut) {
*menuItem.shortcut = newShortcut;
for (auto &[priority, menuItem] : ContentRegistry::Interface::impl::getMenuItemsMutable()) {
if (menuItem.view == view && menuItem.shortcut == oldShortcut) {
menuItem.shortcut = newShortcut;
break;
}
}
@@ -145,4 +442,9 @@ namespace hex {
return result;
}
void ShortcutManager::enableMacOSMode() {
s_macOSMode = true;
}
}

View File

@@ -63,7 +63,7 @@ namespace hex {
}
Task::Task(UnlocalizedString unlocalizedName, u64 maxValue, bool background, std::function<void(Task &)> function)
Task::Task(const UnlocalizedString &unlocalizedName, u64 maxValue, bool background, std::function<void(Task &)> function)
: m_unlocalizedName(std::move(unlocalizedName)), m_maxValue(maxValue), m_function(std::move(function)), m_background(background) { }
Task::Task(hex::Task &&other) noexcept {
@@ -327,11 +327,11 @@ namespace hex {
s_tasksFinishedCallbacks.clear();
}
TaskHolder TaskManager::createTask(std::string name, u64 maxValue, bool background, std::function<void(Task&)> function) {
TaskHolder TaskManager::createTask(const UnlocalizedString &unlocalizedName, u64 maxValue, bool background, std::function<void(Task&)> function) {
std::scoped_lock lock(s_queueMutex);
// Construct new task
auto task = std::make_shared<Task>(std::move(name), maxValue, background, std::move(function));
auto task = std::make_shared<Task>(std::move(unlocalizedName), maxValue, background, std::move(function));
s_tasks.emplace_back(task);
@@ -344,14 +344,32 @@ namespace hex {
}
TaskHolder TaskManager::createTask(std::string name, u64 maxValue, std::function<void(Task &)> function) {
log::debug("Creating task {}", name);
return createTask(std::move(name), maxValue, false, std::move(function));
TaskHolder TaskManager::createTask(const UnlocalizedString &unlocalizedName, u64 maxValue, std::function<void(Task &)> function) {
log::debug("Creating task {}", unlocalizedName.get());
return createTask(std::move(unlocalizedName), maxValue, false, std::move(function));
}
TaskHolder TaskManager::createBackgroundTask(std::string name, std::function<void(Task &)> function) {
log::debug("Creating background task {}", name);
return createTask(std::move(name), 0, true, std::move(function));
TaskHolder TaskManager::createTask(const UnlocalizedString &unlocalizedName, u64 maxValue, std::function<void()> function) {
log::debug("Creating task {}", unlocalizedName.get());
return createTask(std::move(unlocalizedName), maxValue, false,
[function = std::move(function)](Task&) {
function();
}
);
}
TaskHolder TaskManager::createBackgroundTask(const UnlocalizedString &unlocalizedName, std::function<void(Task &)> function) {
log::debug("Creating background task {}", unlocalizedName.get());
return createTask(std::move(unlocalizedName), 0, true, std::move(function));
}
TaskHolder TaskManager::createBackgroundTask(const UnlocalizedString &unlocalizedName, std::function<void()> function) {
log::debug("Creating background task {}", unlocalizedName.get());
return createTask(std::move(unlocalizedName), 0, true,
[function = std::move(function)](Task&) {
function();
}
);
}
void TaskManager::collectGarbage() {
@@ -472,7 +490,7 @@ namespace hex {
#elif defined(OS_LINUX)
pthread_setname_np(pthread_self(), name.c_str());
#elif defined(OS_WEB)
hex::unused(name);
std::ignore = name;
#elif defined(OS_MACOS)
pthread_setname_np(name.c_str());
#endif

View File

@@ -1,5 +1,5 @@
#include <hex/api/theme_manager.hpp>
#include <hex/api/event_manager.hpp>
#include <hex/api/events/events_interaction.hpp>
#include <hex/helpers/logger.hpp>
#include <hex/helpers/utils.hpp>
@@ -16,11 +16,17 @@ namespace hex {
AutoReset<std::map<std::string, ThemeManager::StyleHandler>> s_styleHandlers;
AutoReset<std::string> s_imageTheme;
AutoReset<std::string> s_currTheme;
AutoReset<std::optional<float>> s_accentColor;
std::recursive_mutex s_themeMutex;
}
void ThemeManager::reapplyCurrentTheme() {
ThemeManager::changeTheme(s_currTheme);
}
void ThemeManager::addThemeHandler(const std::string &name, const ColorMap &colorMap, const std::function<ImColor(u32)> &getFunction, const std::function<void(u32, ImColor)> &setFunction) {
std::unique_lock lock(s_themeMutex);
@@ -150,12 +156,28 @@ namespace hex {
continue;
}
auto color = parseColorString(value.get<std::string>());
auto colorString = value.get<std::string>();
bool accentableColor = false;
if (colorString.starts_with("*")) {
colorString = colorString.substr(1);
accentableColor = true;
}
auto color = parseColorString(colorString);
if (!color.has_value()) {
log::warn("Invalid color '{}' for '{}.{}'", value.get<std::string>(), type, key);
log::warn("Invalid color '{}' for '{}.{}'", colorString, type, key);
continue;
}
if (accentableColor && s_accentColor->has_value()) {
float h, s, v;
ImGui::ColorConvertRGBtoHSV(color->Value.x, color->Value.y, color->Value.z, h, s, v);
h = s_accentColor->value();
ImGui::ColorConvertHSVtoRGB(h, s, v, color->Value.x, color->Value.y, color->Value.z);
}
(*s_themeHandlers)[type].setFunction((*s_themeHandlers)[type].colorMap.at(key), color.value());
}
}
@@ -231,6 +253,14 @@ namespace hex {
s_currTheme->clear();
}
void ThemeManager::setAccentColor(const ImColor &color) {
float h, s, v;
ImGui::ColorConvertRGBtoHSV(color.Value.x, color.Value.y, color.Value.z, h, s, v);
s_accentColor = h;
reapplyCurrentTheme();
}
const std::map<std::string, ThemeManager::ThemeHandler> &ThemeManager::getThemeHandlers() {
return s_themeHandlers;

View File

@@ -2,6 +2,7 @@
#include <hex/api/imhex_api.hpp>
#include <hex/api/localization_manager.hpp>
#include <hex/api/task_manager.hpp>
#include <hex/api/events/events_gui.hpp>
#include <hex/helpers/auto_reset.hpp>
@@ -11,6 +12,8 @@
#include <map>
#include <imgui.h>
namespace hex {
namespace {
@@ -20,10 +23,12 @@ namespace hex {
AutoReset<std::map<ImGuiID, std::string>> s_highlights;
AutoReset<std::vector<std::pair<ImRect, std::string>>> s_highlightDisplays;
AutoReset<std::map<ImGuiID, ImRect>> s_interactiveHelpDisplays;
AutoReset<std::map<ImGuiID, std::function<void()>>> s_interactiveHelpItems;
ImRect s_hoveredRect;
ImGuiID s_hoveredId;
ImGuiID s_activeHelpId;
bool s_helpHoverActive = false;
@@ -33,6 +38,13 @@ namespace hex {
idStack.push_back(0);
}
void add(const char *string) {
const ImGuiID seed = idStack.back();
const ImGuiID id = ImHashStr(string, 0, seed);
idStack.push_back(id);
}
void add(const std::string &string) {
const ImGuiID seed = idStack.back();
const ImGuiID id = ImHashStr(string.c_str(), string.length(), seed);
@@ -84,9 +96,23 @@ namespace hex {
EventImGuiElementRendered::subscribe([](ImGuiID id, const std::array<float, 4> bb){
const auto boundingBox = ImRect(bb[0], bb[1], bb[2], bb[3]);
const auto element = hex::s_highlights->find(id);
if (element != hex::s_highlights->end()) {
hex::s_highlightDisplays->emplace_back(boundingBox, element->second);
{
const auto element = hex::s_highlights->find(id);
if (element != hex::s_highlights->end()) {
hex::s_highlightDisplays->emplace_back(boundingBox, element->second);
const auto window = ImGui::GetCurrentWindow();
if (window != nullptr && window->DockNode != nullptr && window->DockNode->TabBar != nullptr)
window->DockNode->TabBar->NextSelectedTabId = window->TabId;
}
}
{
const auto element = s_interactiveHelpItems->find(id);
if (element != s_interactiveHelpItems->end()) {
(*s_interactiveHelpDisplays)[id] = boundingBox;
}
}
if (id != 0 && boundingBox.Contains(ImGui::GetMousePos())) {
@@ -117,10 +143,10 @@ namespace hex {
});
}
void TutorialManager::addInteractiveHelpText(std::initializer_list<std::variant<Lang, std::string, int>> &&ids, UnlocalizedString text) {
void TutorialManager::addInteractiveHelpText(std::initializer_list<std::variant<Lang, std::string, int>> &&ids, UnlocalizedString unlocalizedString) {
auto id = calculateId(ids);
s_interactiveHelpItems->emplace(id, [text = std::move(text)]{
s_interactiveHelpItems->emplace(id, [text = std::move(unlocalizedString)]{
log::info("{}", Lang(text).get());
});
}
@@ -133,6 +159,39 @@ namespace hex {
});
}
void TutorialManager::setLastItemInteractiveHelpPopup(std::function<void()> callback) {
auto id = ImGui::GetItemID();
if (!s_interactiveHelpItems->contains(id)) {
s_interactiveHelpItems->emplace(id, [id]{
s_activeHelpId = id;
});
}
if (id == s_activeHelpId) {
ImGui::SetNextWindowSize(scaled({ 400, 0 }));
if (ImGui::BeginTooltip()) {
callback();
ImGui::EndTooltip();
}
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) || ImGui::IsKeyPressed(ImGuiKey_Escape))
s_activeHelpId = 0;
}
}
void TutorialManager::setLastItemInteractiveHelpLink(std::string link) {
auto id = ImGui::GetItemID();
if (s_interactiveHelpItems->contains(id))
return;
s_interactiveHelpItems->emplace(id, [link = std::move(link)]{
hex::openWebpage(link);
});
}
void TutorialManager::startTutorial(const UnlocalizedString &unlocalizedName) {
s_currentTutorial = s_tutorials->find(unlocalizedName);
if (s_currentTutorial == s_tutorials->end())
@@ -146,6 +205,19 @@ namespace hex {
const auto &drawList = ImGui::GetForegroundDrawList();
drawList->AddText(ImGui::GetMousePos() + scaled({ 10, -5, }), ImGui::GetColorU32(ImGuiCol_Text), "?");
for (const auto &[id, boundingBox] : *s_interactiveHelpDisplays) {
drawList->AddRect(
boundingBox.Min - ImVec2(5, 5),
boundingBox.Max + ImVec2(5, 5),
ImGui::GetColorU32(ImGuiCol_PlotHistogram),
5.0F,
ImDrawFlags_None,
2.0F
);
}
s_interactiveHelpDisplays->clear();
const bool mouseClicked = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
if (s_hoveredId != 0) {
drawList->AddRectFilled(s_hoveredRect.Min, s_hoveredRect.Max, 0x30FFFFFF);
@@ -164,6 +236,11 @@ namespace hex {
if (mouseClicked || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
s_helpHoverActive = false;
}
// Discard mouse click so it doesn't activate clicked item
ImGui::GetIO().MouseDown[ImGuiMouseButton_Left] = false;
ImGui::GetIO().MouseReleased[ImGuiMouseButton_Left] = false;
ImGui::GetIO().MouseClicked[ImGuiMouseButton_Left] = false;
}
for (const auto &[rect, unlocalizedText] : *s_highlightDisplays) {

View File

@@ -8,12 +8,18 @@
namespace hex::dp {
int Node::s_idCounter = 1;
static std::atomic_bool s_interrupted;
Node::Node(UnlocalizedString unlocalizedTitle, std::vector<Attribute> attributes) : m_id(s_idCounter++), m_unlocalizedTitle(std::move(unlocalizedTitle)), m_attributes(std::move(attributes)) {
for (auto &attr : m_attributes)
attr.setParentNode(this);
}
void Node::draw() {
this->drawNode();
}
const std::vector<u8>& Node::getBufferOnInput(u32 index) {
auto attribute = this->getConnectedInputAttribute(index);
@@ -29,9 +35,6 @@ namespace hex::dp {
auto &outputData = attribute->getOutputData();
if (outputData.empty())
throwNodeError("No data available at connected attribute");
return outputData;
}
@@ -148,9 +151,56 @@ namespace hex::dp {
m_overlay->getData() = data;
}
[[noreturn]] void Node::throwNodeError(const std::string &message) {
throw NodeError { this, message };
}
void Node::setAttributes(std::vector<Attribute> attributes) {
m_attributes = std::move(attributes);
for (auto &attr : m_attributes)
attr.setParentNode(this);
}
void Node::setIdCounter(int id) {
if (id > s_idCounter)
s_idCounter = id;
}
Attribute& Node::getAttribute(u32 index) {
if (index >= this->getAttributes().size())
throw std::runtime_error("Attribute index out of bounds!");
return this->getAttributes()[index];
}
Attribute *Node::getConnectedInputAttribute(u32 index) {
const auto &connectedAttribute = this->getAttribute(index).getConnectedAttributes();
if (connectedAttribute.empty())
return nullptr;
return connectedAttribute.begin()->second;
}
void Node::markInputProcessed(u32 index) {
const auto &[iter, inserted] = m_processedInputs.insert(index);
if (!inserted)
throwNodeError("Recursion detected!");
if (s_interrupted) {
s_interrupted = false;
throwNodeError("Execution interrupted!");
}
}
void Node::unmarkInputProcessed(u32 index) {
m_processedInputs.erase(index);
}
void Node::interrupt() {
s_interrupted = true;
}
}

View File

@@ -1,8 +1,10 @@
#include <algorithm>
#include <hex/helpers/crypto.hpp>
#include <hex/providers/provider.hpp>
#include <wolv/utils/guards.hpp>
#include <wolv/utils/expected.hpp>
#include <mbedtls/version.h>
#include <mbedtls/base64.h>
@@ -496,8 +498,8 @@ namespace hex::crypt {
return encodeLeb128<i128>(value);
}
static std::vector<u8> aes(mbedtls_cipher_type_t type, mbedtls_operation_t operation, const std::vector<u8> &key, std::array<u8, 8> nonce, std::array<u8, 8> iv, const std::vector<u8> &input) {
std::vector<u8> output;
static wolv::util::Expected<std::vector<u8>, int> aes(mbedtls_cipher_type_t type, mbedtls_operation_t operation, const std::vector<u8> &key,
std::array<u8, 8> nonce, std::array<u8, 8> iv, const std::span<const u8> &input) {
if (input.empty())
return {};
@@ -507,38 +509,65 @@ namespace hex::crypt {
mbedtls_cipher_context_t ctx;
auto cipherInfo = mbedtls_cipher_info_from_type(type);
if (cipherInfo == nullptr)
return {};
mbedtls_cipher_setup(&ctx, cipherInfo);
mbedtls_cipher_setkey(&ctx, key.data(), key.size() * 8, operation);
int setupResult = mbedtls_cipher_setup(&ctx, cipherInfo);
if (setupResult != 0)
return wolv::util::Unexpected(setupResult);
int setKeyResult = mbedtls_cipher_setkey(&ctx, key.data(), key.size() * 8, operation);
if (setKeyResult != 0)
return wolv::util::Unexpected(setKeyResult);
std::array<u8, 16> nonceCounter = { 0 };
std::copy(nonce.begin(), nonce.end(), nonceCounter.begin());
std::copy(iv.begin(), iv.end(), nonceCounter.begin() + 8);
auto mode = mbedtls_cipher_get_cipher_mode(&ctx);
// if we are in ECB mode, we don't need to set the nonce
if (mode != MBEDTLS_MODE_ECB) {
std::ranges::copy(nonce, nonceCounter.begin());
std::ranges::copy(iv, nonceCounter.begin() + 8);
}
size_t outputSize = input.size() + mbedtls_cipher_get_block_size(&ctx);
output.resize(outputSize, 0x00);
mbedtls_cipher_crypt(&ctx, nonceCounter.data(), nonceCounter.size(), input.data(), input.size(), output.data(), &outputSize);
std::vector<u8> output(outputSize, 0x00);
int cryptResult = 0;
if (mode == MBEDTLS_MODE_ECB) {
cryptResult = mbedtls_cipher_crypt(&ctx, nullptr, 0, input.data(), input.size(), output.data(), &outputSize);
} else {
cryptResult = mbedtls_cipher_crypt(&ctx, nonceCounter.data(), nonceCounter.size(), input.data(), input.size(), output.data(), &outputSize);
}
// free regardless of the result
mbedtls_cipher_free(&ctx);
if (cryptResult != 0) {
return wolv::util::Unexpected(cryptResult);
}
output.resize(input.size());
return output;
}
std::vector<u8> aesDecrypt(AESMode mode, KeyLength keyLength, const std::vector<u8> &key, std::array<u8, 8> nonce, std::array<u8, 8> iv, const std::vector<u8> &input) {
wolv::util::Expected<std::vector<u8>, int> aesDecrypt(AESMode mode, KeyLength keyLength, const std::vector<u8> &key, std::array<u8, 8> nonce, std::array<u8, 8> iv, const std::vector<u8> &input) {
switch (keyLength) {
case KeyLength::Key128Bits:
if (key.size() != 128 / 8) return {};
if (key.size() != 128 / 8)
return wolv::util::Unexpected(CRYPTO_ERROR_INVALID_KEY_LENGTH);
break;
case KeyLength::Key192Bits:
if (key.size() != 192 / 8) return {};
if (key.size() != 192 / 8)
return wolv::util::Unexpected(CRYPTO_ERROR_INVALID_KEY_LENGTH);
break;
case KeyLength::Key256Bits:
if (key.size() != 256 / 8) return {};
if (key.size() != 256 / 8)
return wolv::util::Unexpected(CRYPTO_ERROR_INVALID_KEY_LENGTH);
break;
default:
return {};
return wolv::util::Unexpected(CRYPTO_ERROR_INVALID_KEY_LENGTH);
}
mbedtls_cipher_type_t type;
@@ -568,7 +597,7 @@ namespace hex::crypt {
type = MBEDTLS_CIPHER_AES_128_XTS;
break;
default:
return {};
return wolv::util::Unexpected(CRYPTO_ERROR_INVALID_MODE);
}
type = mbedtls_cipher_type_t(type + u8(keyLength));

Some files were not shown because too many files have changed in this diff Show More