Compare commits

...

348 Commits

Author SHA1 Message Date
WerWolv
f517dc9829 Merge branch 'master' into feature/clipboard_improvements 2025-05-29 20:27:10 +02:00
WerWolv
fe1309fb3d build: Don't link against llvm demangle in external builds 2025-05-29 20:27:03 +02:00
WerWolv
0ea3adcb75 Merge branch 'master' into feature/clipboard_improvements 2025-05-29 20:01:25 +02:00
WerWolv
12d59ce3e4 fix: Bad copy paste 2025-05-29 20:01:17 +02:00
WerWolv
96ef758bbd impr: Added clip library to improve clipboard situation 2025-05-29 19:56:46 +02:00
WerWolv
224fa83c65 fix: Missing <span> include 2025-05-29 19:55:59 +02:00
WerWolv
f591ac8780 fix: UDP Port not being updated correctly when loading provider from recents file 2025-05-29 18:26:07 +02:00
WerWolv
11e70511e6 build: Fix plugin SDK issues 2025-05-29 18:19:20 +02:00
WerWolv
c1e4121d1e build: Updated Windows resource copyright year 2025-05-29 18:00:41 +02:00
WerWolv
03884ddd05 feat: Added simple UDP Data Provider 2025-05-29 18:00:29 +02:00
WerWolv
ac67e985af build: Make tracing library a static library 2025-05-29 14:02:06 +02:00
WerWolv
9d12cd64d3 impr: Add full resolution Windows icon 2025-05-29 13:53:57 +02:00
paxcut
702b5f2888 fix: Problems with textures in 3d visualizer with bitmap visualizer. (#2167)
The bitmap visualizer has been simplified considerably. The previous version was designed to work with the TIM format which has some peculiarities that are not general enough. The current implementation has the following specifications.

. Whether colors are in a lookup table or part of the image itself they are always 32 bit R8G8B8A8.

. If using a color LUT the image then has indices as its element. Indices can have 16(32000 colors), 8 (256 colors) or 4(16 colors) bits each.

.For the cases 0f 16 and 8 bits, the data should be an array of N*M elements of the given size where N is the number of rows and M is the number of columns of the image.

. For the 4 bit case use an array of N*M/2 bytes so that each column contains two indices.

ToDo: Documentation, sample patterns and unit tests.

The 3-d visualizer can now handle textures from both the command line or the user interface and things should work as expected. A command line entry will be automatically displayed in the user interface, but changes will be applied immediately as you type or use the file picker. If the user interface text is deleted, then the command line texture will be used again.  If a texture is invalid for any reason, then the previous one, if any, will be still in use and an error message will be displayed until the problem is cleared. Valid textures are image files that the stb library can open.
2025-05-27 09:25:20 -07:00
WerWolv
a5eef3f34d build: Fix more linker errors 2025-05-26 21:57:27 +02:00
WerWolv
1bc9277e3c build: Fix undefined references 2025-05-26 20:25:35 +02:00
WerWolv
b33cb07dc0 build: Include tracing library in plugin SDK 2025-05-26 20:19:27 +02:00
WerWolv
ce74915c14 feat: Add full exception tracing support 2025-05-26 20:15:20 +02:00
WerWolv
f341413248 fix: Crash when opening diff view
#2269
2025-05-26 18:34:00 +02:00
WerWolv
ed3e2f65f8 impr: Set default font size to 12pt 2025-05-25 23:32:43 +02:00
WerWolv
6e5878b5d6 fix: OOBE logo background color 2025-05-25 23:29:01 +02:00
WerWolv
39242097dd fix: --reset-settings not working due to superfluous null bytes in string 2025-05-25 23:23:51 +02:00
WerWolv
0aec3fffe1 fix: Unused lambda captures 2025-05-25 22:21:40 +02:00
WerWolv
38ef00548a impr: Speed up Import Pattern popup
Closes #2264
2025-05-25 21:08:52 +02:00
WerWolv
c78c8072e9 fix: Text Editor Scrollbars being added multiple times 2025-05-25 20:35:03 +02:00
WerWolv
7c98411abe fix: Tutorial highlighting of menu item 2025-05-25 18:21:26 +02:00
WerWolv
e22516662f patterns: Updated pattern language 2025-05-25 18:21:03 +02:00
WerWolv
24c1f48522 build: Updated lunasvg and libyara 2025-05-25 15:32:43 +02:00
WerWolv
69b07d40e4 build: Updated ImGui to v1.91.9b 2025-05-25 15:30:33 +02:00
WerWolv
b96692b1ba fix: Global scale race condition during font loading 2025-05-25 15:11:09 +02:00
WerWolv
53afb7cba0 git: Add Ubuntu 25.04 release 2025-05-25 14:09:56 +02:00
WerWolv
8e0953af1e git: Only put the current web assembly build into the release artifact 2025-05-25 13:46:57 +02:00
WerWolv
724f9aa524 git: Deploy both latest release and nightly to web.imhex.werwolv.net 2025-05-25 13:43:06 +02:00
WerWolv
7067ffafe7 patterns: Display pattern errors in red in the pattern data view 2025-05-25 11:46:41 +02:00
WerWolv
145c88db31 patterns: Updated pattern language
Fixes #2266
2025-05-25 11:00:59 +02:00
paxcut
56615d6c06 patterns: Updated pattern language (#2270) 2025-05-24 16:44:59 -07:00
WerWolv
d26bcc1abe fix: Menu bar being gone on the Web build 2025-05-24 23:10:53 +02:00
WerWolv
04f817c042 fix: Web Assembly build 2025-05-24 22:45:17 +02:00
WerWolv
b58f97c1f1 impr: Added function to Texture class to retrieve raw image from GPU 2025-05-24 22:32:56 +02:00
WerWolv
96dc386694 fix: Linux build errors 2025-05-24 22:32:33 +02:00
WerWolv
c6c70daa5e fix: macOS build errors 2025-05-24 22:32:24 +02:00
WerWolv
de16375903 impr: Slightly simplify subpixel rendering logic and required ImGui patches 2025-05-24 22:32:08 +02:00
WerWolv
c6548d5ad1 fix: Non-subpixel rendered glyphs appearing as white rectangles if subpixel rendering is enabled 2025-05-24 21:59:21 +02:00
WerWolv
bd8c4e807c fix: Remove extra pixel from Hex Editor selection frame 2025-05-24 16:19:13 +02:00
WerWolv
553549302c impr: Use linear scaling for the windows title bar icon 2025-05-24 16:18:59 +02:00
WerWolv
c69a7012c5 fix: Unifont glyphs being rendered too far down 2025-05-24 16:09:15 +02:00
WerWolv
7acc5fc02e impr: Make title bar backdrop actually a backdrop and not an overlay 2025-05-24 11:57:02 +02:00
WerWolv
39bc165f36 build: Prevent frame pointer omission to improve stack traces 2025-05-24 11:56:44 +02:00
WerWolv
707a92281b fix: Multithreaded disk access issues 2025-05-24 11:48:07 +02:00
WerWolv
823013a3d9 fix: Fonts being smaller than their set size value 2025-05-24 11:47:46 +02:00
WerWolv
7089561b21 git: Remove accidentally committed file 2025-05-19 00:01:23 +02:00
WerWolv
0f0bff1685 fix: Remaining Subpixel rendering issues 2025-05-19 00:00:32 +02:00
WerWolv
b6387c3f64 fix: Crash when loading subpixel font didn't work 2025-05-18 11:10:43 +02:00
paxcut
ff0bcfb7da fix: More per-provider data access errors (#2256) 2025-05-17 21:48:36 -07:00
Stephen Hewitt
f729d36214 fix: Crash when sorting for value fields in pattern data view, fix HTML export encoding (#2242)
<!--
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
This is a fix for the ImHex bug "ImHex crashes when analysing any PE
file #2221"

### Implementation description
This is a fix for the ImHex bug "ImHex crashes when analysing any PE
file #2221". The fix requires changes to the Pattern Language and the
ImHex UI. Revision would be wise. We want to avoid collateral damage.
It's a big code base and I'm new to it and the compilers/build-systems
used. And the bug is complex and low-level. I suspect this will fix
other random crashes. The problem is caused by two issues:
- The std::sort algorithm conjuring up garbage due to the sorting
criteria not being a strict weak ordering. See
[this](https://github.com/Voultapher/sort-research-rs/blob/main/writeup/sort_safety/text.md)
link.
- We sort shared_ptr&lt;ptrn::Pattern&gt; by pointer value, and the
object is a clone. In essence we're changing the values as we're
sorting.
 
Fixes #2221

### IMPORTANT
I'm not sure how "plugins/builtin/source/content/data_formatters.cpp"
got into the PR. Been trying for an hour to rectify. I'm not a Git
expert (the last time I used source control seriously SourceSafe was a
thing) please ignore that file. It's a fix for another PR I submitted. I
suspect I stuffed up the branching and merging.

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2025-05-17 20:50:21 +00:00
WerWolv
d5a07b6a5b patterns: Updated pattern language 2025-05-17 22:20:05 +02:00
WerWolv
bda0b3ce18 fix: More per-provider data access errors 2025-05-17 22:14:27 +02:00
WerWolv
14d95a7e46 patterns: Updated pattern language 2025-05-17 20:31:38 +02:00
WerWolv
2ef2cdd874 fix: Make sure PerProvider don't get accessed using a nullptr provider 2025-05-17 20:29:54 +02:00
paxcut
57c2d84122 improv: made the text editors to be per provider. (#2255)
The recent update that made importing patterns undoable had the side
effect of undoing tab changes as well. When working on a fix for that it
became clear that the undo/redo stacks were being shared by all
providers so that you could undo changes done in a separate file. The
problem was fixed by making the text editors (and the console editors as
well) to be per provider which gives better control on things like
breakpoints and selections and a more robust focusing system that
preserves the cursor positions and removes the need to click on a
pattern to start editing. There are a lot of changes, but they are
mostly all the uses of text editors being now coded differently to
manage the providers. File imports are still undoable, but switching
providers is not.
Further changes suggested by reviewer were implemented namely a mull provider was being used and there was a get function missing which prevented the use of the preferred syntax.
2025-05-17 11:26:54 -07:00
paxcut
d263962a06 fix: horizontal scrollbar missing in console (#2253)
The recent changes to the text editor to fix the longest line length
problems broke the console horizontal scrollbar. The code that displays
the console editor was more complicated that it needed be, and it had
the bad side effect of resetting the cursor which prevented horizontal
scrolling. Adding a function that appends lines to the text editor fixes
all problems and makes the code clearer. To accommodate for strings
containing zeros, the code that inserts text was changed to print a '.'
when zeros are encountered thus keeping the line length the same.
2025-05-17 00:23:43 -07:00
WerWolv
e32c5784af impr: Further refine pattern tree indenting 2025-05-16 20:24:38 +02:00
WerWolv
1496a6e755 impr: Improve indentation of pattern data tree
#2252
2025-05-16 18:50:35 +02:00
WerWolv
6dab1063a1 fix: Provider getting marked as dirty immediately on load
#2251
2025-05-16 18:50:03 +02:00
paxcut
ff286f3e05 fix: subpixel effects on hex editor. (#2247)
The implementation of subpixel rendering using draw call lists with
callbacks prevents call list merging and their associated clip rects in
tables. As a result clip rects become as narrow as the columns of the
table which can clip previously renderable primitives. The hex editor
has several draw calls that render outside their column so if subpixel
rendering is selected those primitives cease to be displayed.

To fix this issue, and to verify that this was indeed the cause behind
the issue, we simply push an adequately sized clip rect before the draw
call command and pop it right after.

A problem with segment vertical separators not being rendered in the
first tow was also fixed.
2025-05-16 01:31:29 -07:00
WerWolv
6f112c2d16 feat: Added custom encoding row to data inspector 2025-05-15 22:00:43 +02:00
paxcut
8f222dab99 fix: unable to display models if indices are not contiguous in the input file (#2248)
If you tried to collect the indices using addressof like stl pattern
collects vertices you get a small square for visualizer and no error
message. The changes here are able to extract the indices if they can be
extracted and give an error message if they can't.
2025-05-14 22:08:16 -07:00
paxcut
828951ffe9 build: msvc uninitialized variables. (#2239)
MSVC build failing because of a warning treated as an error for
variables being used without initializing even though they are being
passed as references.
2025-05-12 01:58:10 -07:00
WerWolv
616f34e210 fix: Window being created partially off-screen if monitor is too small
Fixes #2238
2025-05-11 23:54:58 +02:00
WerWolv
fa3ed7e618 impr: Load all unicode planes if requested 2025-05-11 23:26:27 +02:00
WerWolv
a207969dec fix: Unicode enable option not working correctly 2025-05-11 23:07:52 +02:00
WerWolv
7fde40b04e impr: Allow for higher planes of unicode characters to be recognized
#2237
2025-05-11 23:07:27 +02:00
WerWolv
1bce588cdd impr: Make sure settings descriptions are always visible 2025-05-11 18:11:28 +02:00
WerWolv
5a095cc993 fix: Icon scaling when using pixel perfect font 2025-05-11 17:42:36 +02:00
WerWolv
431eab47a2 git: Remove Fedora 40 support, add Fedora 42 support 2025-05-11 17:25:20 +02:00
WerWolv
e9e3d25315 fix: Rendering on macOS being broken 2025-05-11 17:18:43 +02:00
WerWolv
e2735e283e fix: Text not rendering at all on the Web version 2025-05-11 17:07:19 +02:00
WerWolv
3e9cb57dd6 fix: Grayscale antialiasing not blending correctly 2025-05-11 17:07:03 +02:00
paxcut
5c4cf7379f feat: Added Subpixel Font rendering (#2092)
Proof of concept for implementing subpixel processing in ImGui. This is
work in progress, and it is bound to have problems.

What it does:
1) Uses freetype own subpixel processing implementation to build a
32-bit color atlas for the default font only (no icons, no unifont) . 2)
Avoids pixel perfect font conversion when possible. 3) Self contained,
no ImGui source code changes.
4) Results in much improved legibility of fonts rendered on low dpi LCD
screens that use horizontal RGB pixel layouts (no BRG or OLED or CRT if
they even exist anymore)

What it doesn't:
1) Fancy class based interface. The code is barely the minimum needed to
show it can work. 2) Dual source color blending. That needs to be
implemented in shader code, so it needs to change ImGui source code
although minimally. This will result in some characters appearing dimmer
than others. Easily fixed with small fragment and vertex shaders. 3)
subpixel positioning. If characters are very thin they will look
colored, or they can be moved to improve legibility. 4) deal with
detection of fringe cases including rare pixel layouts, non LCD screens,
Mac-OS not handling subpixel rendering and any other deviation from the
standard LCD. 5) tries to be efficient in speed or memory use. Font
Atlases will be 4 times the size they were before, but there are no
noticeable delays in font loading in the examples I have tried.

Any comments and code improvements are welcome.

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2025-05-11 15:36:32 +02:00
WerWolv
8cd961596e fix: Undo accent color changes as they produced some weird results 2025-05-11 15:24:24 +02:00
WerWolv
d2344418d6 patterns: Updated pattern language 2025-05-11 15:22:27 +02:00
WerWolv
33aa2248d2 fix: Theme color alpha not being applied correctly to accented colors 2025-05-11 11:05:53 +02:00
WerWolv
feb5b209ed web: Adapt new async WASM loading API 2025-05-10 21:30:42 +02:00
WerWolv
34722404f4 build: Emscripten no longer generates imhex.worker.js 2025-05-10 19:25:36 +02:00
WerWolv
b78a234fe1 impr: Make accent colors work more naturally 2025-05-10 18:23:29 +02:00
WerWolv
f19478374f build: Update emscripten to the latest version 2025-05-10 14:24:07 +02:00
WerWolv
51a01c860b patterns: Updated pattern language 2025-05-10 12:17:41 +02:00
WerWolv
eedd044716 build: Updated dependencies 2025-05-10 11:11:18 +02:00
WerWolv
0a327f4ad3 impr: Allow debug banner to be skipped with a env var 2025-05-10 11:00:18 +02:00
WerWolv
eec6a5da0a impr: Unlock frame rate in more cases 2025-05-10 11:00:18 +02:00
WerWolv
fc87bc0cf1 impr: Allow events to be used with a function without args 2025-05-10 11:00:18 +02:00
peelz
1f213408a1 build: Move nlohmann-json to build dependencies (#2218)
nlohmann-json is a headers-only library, so there's no runtime
requirement for it.
2025-05-10 10:59:18 +02:00
WerWolv
bac6fd803f patterns: Updated pattern language 2025-05-09 21:18:31 +02:00
WerWolv
5a74d7e3e2 patterns: Updated pattern language 2025-05-09 19:35:00 +02:00
WerWolv
e289380c39 fix: Crash when selecting invalid time_t 2025-05-09 19:33:01 +02:00
WerWolv
8081dff6b6 build: Updated libfmt (#2234) 2025-05-09 19:00:04 +02:00
WerWolv
7dcf09118b patterns: Updated pattern language 2025-05-09 18:24:50 +02:00
WerWolv
4b9a3d121d fix: Visualizer popups being draggable from their body 2025-05-09 17:23:55 +02:00
WerWolv
cd24cba240 build: Updated libwolv 2025-05-09 17:23:35 +02:00
paxcut
d33fad9d23 fix: The bar between pattern editor and console could be locked even if it seemed like it should be movable. (#2227)
This was caused by the variable that holds the bar location not being
updated when window was resized.
The bar can be moved until only one line is shown in the smaller window.
When ImJex window is resized, the proportion of editor/console height is
maintained.
2025-05-05 02:43:14 -07:00
paxcut
b02aa51e09 fix: macos builds
Found post on s.o. about c++ headers not being found when using llvm
clang installed using homebrew
[here](https://stackoverflow.com/questions/77250743/mac-xcode-g-cannot-compile-even-a-basic-c-program-issues-with-standard-libr)
and when I tested the proposed solution in my imhex fork the macos x86
builds were able to complete.
2025-05-04 21:19:29 -07:00
ThePirate42
36eeee5f9c fix: prevent potential UB using std::clamp.
### Problem description
It is possible for the maximum and minimum value arguments to std::clamp to be swapped which is defined  in the standard as undefined behavior

### Implementation description
Swap the values if necessary.


---------

Co-authored-by: paxcut <53811119+paxcut@users.noreply.github.com>
2025-05-04 17:24:59 -07:00
paxcut
4883ed0e5a fix: Incorrect horizontal scrollbar displayed. (#2209)
The horizontal scroll bar length is set using the maximum line length across the input file. The original setup had the lengths of imported and included files added so changes are made to insure that only changes from the input file are taken. This required changes to the Pattern Language library so the library is updated to the latest version as well.
2025-05-04 07:56:39 -07:00
paxcut
78ad0d2592 fix: fixed console selections while improving code clarity.
The function SetSelection() in the text editor is used as its name implies to set the part of text that will be shown highlighted as a selection. It has two parameter for the selection start and end.

Strangely it also uses a third argument to choose one of 3 selection modes (line, word and normal). This is strange because it seems that if one wanted to select a line one would simply choose the line start and end as the selection values. 

Furthermore using selection mode creates a bug when the word boundaries are advanced twice during a single word left or right selection and a second bug when SetSelection is used to set the cursor when the window acquires focus breaking selections in the console editor.

This PR simply eliminates the extraneous argument to SetSelection() ensuring that any problems related to it are fixed once and for all improving code readability by removing the use of inconsistent argument values to cover for the functionality  duplication design flaw.
2025-04-30 22:08:23 -07:00
SparkyTD
f6def74b29 impr: Fix word bound selection and 'MoveHome' behavior in the pattern editor (#2193)
### Problem description
This PR addresses two small issues regarding the cursor in the pattern
editor (TextEditor.cpp):

1. It was not possible to move the cursor to the start of a line, if it
contained leading white space characters. With my fix, the editor will
behave more like other code editors. Pressing Home once will jump to the
first non-whitespace character (as it did before), but pressing it again
will jump to column 0. Subsequent presses will alternate between the two
positions.
2. When expanding a selection with Ctrl+Shift+{Left/Right}, the new
selection position would skip an additional word, resulting in the
cursor landing "inside" the selection. This PR fixes this bug.

### Implementation description
1. To fix the first issue, I simply added a condition in
`TextEditor::MoveHome` to check if the cursor is already on the first
meaningful character, or on one of the whitespaces preceding it, in
which case the jump offset is set to 0. If we're already on column 0,
then jump forwards to the first non-whitespace character.
2. This bug was happening because the word boundary jump calculations
were essentially happening twice. Once in
`TextEditor::MoveLeft`/`TextEditor::MoveRight`, and then a second time
in `TextEditor::SetSelection`, leading to the selection skipping an
additional word. I fixed this by replacing the ternary operator with
just `SelectionMode::Normal`.

---------

Co-authored-by: paxcut <53811119+paxcut@users.noreply.github.com>
2025-04-30 11:57:34 -07:00
Geky
be44676b01 i18n: Added french translation (#2171) 2025-04-24 11:14:41 +02:00
paxcut
60c1c22a73 fix: fixes Issue #1621 (#2189)
fixes Issue #1621.
Using shift-tab on an empty line caused a crash.  Additionally, changed
the hard coded value of 4 to the tab size variable it really needs to be.
2025-04-23 06:54:39 -07:00
WerWolv
02cadc264e build: Try to use macOS 13 SDK if possible 2025-04-14 20:42:37 +02:00
WerWolv
a0ca5b8072 fix: Missing include on clang 20 2025-04-14 20:21:53 +02:00
WerWolv
31fdb73b0e git: Remove --no-lock from brew commands since it was removed 2025-04-14 19:02:07 +02:00
WerWolv
d2caa1859d fix: LayoutManager build issues 2025-04-09 07:26:45 +02:00
PietHelzel
f6c25b30ae fix: Saving layout now picks the first path in the list (#2208)
<!--
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
Saving a layout using the "Workspace -> Layout -> Save Layout ..."
button saved to the last writable path in the list that can be found in
the "Help -> About" menu. Instead, it should write to the first working
path encountered.

### Implementation description
Getting all of the writable paths, then picking the first one.

### 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 -->
2025-04-08 21:47:20 +02:00
WerWolv
379d826f18 build: Fix configure issues with cmake 4.0.0 2025-04-04 00:02:39 +02:00
WerWolv
96afccc46c fix: Workspaces not being updated correctly 2025-04-03 23:55:35 +02:00
paxcut
c0a222644b feat: Allow adding breakpoints in pattern editor by clicking on line numbers (#2161)
Now that line numbers are not part of the line of code clicking them
makes the text editor lose focus. This PR changes that by allowing the
user to toggle breakpoints by clicking the field where the line number
is located.

Not only will the text editor retain focus when breakpoints are set, but
if other parts of ImHex had focus, then it will be transferred to the
text editor's current cursor position when the line number field is
clicked.

It is also possible to keep the focus where it was and only retain the
focus if the text editor was focused when the break point is set. The
change is very trivial so if that is preferred I can easily switch it.
2025-03-11 14:57:49 +01:00
paxcut
653173945f feat: Make undo work when importing pattern (#2160)
A user complained that they imported a file by accident when they meant
to export it and as a result had trouble recovering the changes they
were trying to save. Auto-save saved the day but there is no reason for
not being able to undo changes after importing a pattern.

In fact, the previous implementation treated importing a pattern as a
reset on the editor instance which actually erased all previous undo
entries. Importing now is treated as a normal editing operation where
the entire file is replaced with the imported pattern.
Since all imports use AddText it was easy to add an undo entry to that
function while removing the part where the previous undo records were
being deleted.

Care is taken to add the preprocessed version of the imported file to
the undo buffer so that unwanted chars don't sneak in. A bug was found
in the handling of a tab char as well but hopefully it wont need to be
used anymore.
2025-03-11 14:56:44 +01:00
paxcut
7d09cc6d25 fix: Console editor not showing all output (#2133)
This change is to fix a bug reported in discord by berkus and Naheulf
about the console missing output lines. The bug was caused by using
SetText which replaces the existing text with the text in the argument.

To fix it use InsertText which puts the text at the current cursor
position that was already set to the end of the current contents.

Code was tested with pattern used to reproduce the bug and seemed to
work when evaluated repeatedly.
2025-03-11 14:56:05 +01:00
Stefan
a4360dfe76 lang: Use ß in German translation where needed (#2135) 2025-03-11 14:55:12 +01:00
WerWolv
9887117e7a build: Updated disassembler library 2025-03-03 15:41:04 +01:00
xtex
9be7eafa39 build: Find regex component of Boost explicitly (#2151)
'Boost::regex' could not be found unless regex is specified explicitly
on some systems.

cf. https://github.com/AOSC-Dev/aosc-os-abbs/pull/9798
cc. @chenx97

### Problem description
> Target "libimhex" links to: Boost::regex but the target was not found.
when building ImHex with system Boost.

### Implementation description
Add `COMPONENETS regex` to require regex library explicitly.

Signed-off-by: xtex <xtex@aosc.io>
Co-authored-by: Henry Chen <chenx97@aosc.io>
2025-02-28 12:29:39 +01:00
WerWolv
774eb18a42 impr: Make custom disassemblers reload on run 2025-02-28 12:04:47 +01:00
WerWolv
4e582d02f5 fix: More issues with OpenGL texture deallocation 2025-02-27 21:44:42 +01:00
WerWolv
38d11dacb7 fix: Crash when choosing Edit -> Disassemble Selection without ever opening disassembler view
Fixes #2149
2025-02-27 08:45:24 +01:00
WerWolv
e17490ee04 build: Install updater binary into bundle on macOS 2025-02-27 08:44:32 +01:00
WerWolv
f3a9ca6d6f fix: Only try to delete textures if OpenGL is still available 2025-02-26 16:03:37 +01:00
WerWolv
2653740a36 fix: Wrong scripts menu rendering on macOS with OS menu bar enabled 2025-02-26 16:03:29 +01:00
WerWolv
335042ec08 impr: Reduce CPU usage further 2025-02-26 16:03:24 +01:00
WerWolv
f6944b15f3 fix: Large CPU usage 2025-02-26 16:03:16 +01:00
WerWolv
d7960dccb4 fix: ID collision when having duplicate fonts installed
Fixes #2141
2025-02-25 11:52:46 +01:00
WerWolv
c974c4257d fix: Crash on exit due to frame rate limiter thread not being shut down
Fixes #2140
2025-02-25 11:50:38 +01:00
WerWolv
40d74dd633 fix: Crashes when switching disassembler architecture while disassembling 2025-02-24 19:58:40 +01:00
WerWolv
602c85b57d fix: Way too low sleep target fps 2025-02-24 19:53:07 +01:00
WerWolv
f96fa596b3 fix: Debug assertion 2025-02-24 19:52:41 +01:00
WerWolv
8c13d0096e build: Remove wrong hexpluglib bundling from rpms 2025-02-23 21:08:22 +01:00
WerWolv
7879f8b6a4 impr: Don't wake up frame rate limiter thread more often than necessary 2025-02-23 20:25:29 +01:00
WerWolv
4c0e8bc1d6 build: Disable fortify source in debug builds 2025-02-23 20:24:10 +01:00
WerWolv
6644df3958 build: Make sure plugin libraries don't end up in lib folder 2025-02-20 11:29:39 +01:00
WerWolv
2b5551d719 fix: Crash when closing provider that's open in the diff view 2025-02-20 10:34:59 +01:00
Jonathan Wright
137063dd21 build: Fix using system lunasvg (#2131)
Fix capitalization for cmake find_package and lunasvg.h path
2025-02-19 20:42:22 +01:00
WerWolv
ca403869ab fix: Broken Plugin API link 2025-02-19 14:46:01 +01:00
WerWolv
daf676b277 fix: Potential division by zero on Windows 7
#2130
2025-02-19 10:58:16 +01:00
WerWolv
66bbdbe6ec patterns: Updated pattern language
Fixes #2126
2025-02-18 22:48:49 +01:00
WerWolv
d3c2516f5f fix: Occasional crash when switching fonts 2025-02-18 21:50:51 +01:00
WerWolv
c39ae84922 impr: Make CLI not hang for a second after each command on Linux 2025-02-18 20:54:25 +01:00
WerWolv
a83843fdab patterns: Updated pattern language 2025-02-18 20:39:59 +01:00
WerWolv
2d48da1c4a fix: Prevent stack overread when calling dbus-send 2025-02-18 15:22:29 +01:00
WerWolv
af0c15f69d impr: Make title bar icon always draw at the correct size 2025-02-18 15:21:56 +01:00
WerWolv
7898df9c2c fix: Pattern Editor losing focus during auto evaluation
Fixes #2122
2025-02-18 10:25:59 +01:00
WerWolv
48abdeaf6b build: Fixed Linux build issues 2025-02-18 10:21:26 +01:00
WerWolv
99a4979b65 build: Fixed Windows build issues 2025-02-18 09:24:20 +01:00
WerWolv
d8beff4f6b build: Only enable module scanning when modules are enabled 2025-02-18 00:47:36 +01:00
WerWolv
ccaf1e33c0 build: Make this modules stuff actually mostly work on Clang 2025-02-18 00:39:53 +01:00
WerWolv
3f119b957e build: Use -fvisibility=hidden for plugins 2025-02-17 22:57:33 +01:00
WerWolv
abf97212fe build: Added some initial test code for C++ Modules 2025-02-17 22:57:21 +01:00
WerWolv
b81c3d2f75 build: Updated dependencies 2025-02-17 16:19:02 +01:00
WerWolv
5651c4d95c git: Updated gcc version in compile instructions 2025-02-17 16:14:49 +01:00
WerWolv
c83a5cc1b7 build: Get rid of unused Toolchain file warning 2025-02-17 13:19:53 +01:00
WerWolv
0499807597 fix: Remove unused event unsubscribes in disassembler 2025-02-17 13:07:01 +01:00
WerWolv
f846afd8a9 fix: Crash when setting invalid font 2025-02-17 13:06:35 +01:00
WerWolv
b822c82d18 impr: Added missing ellipsis on Edit options 2025-02-17 11:21:55 +01:00
WerWolv
e4de551008 fix: Closing one view breaking all other views 2025-02-17 10:16:51 +01:00
WerWolv
5333d0180f fix: Crash when loading process memory provider from project 2025-02-17 10:16:37 +01:00
WerWolv
658d4c4d72 fix: Make sure fps counter values are initialized to zero 2025-02-16 23:46:08 +01:00
WerWolv
efa50a8c39 fix: Revert accent color changes 2025-02-16 22:52:54 +01:00
WerWolv
677dc6192d fix: Don't execute EventDPIChanged multiple times 2025-02-16 22:21:00 +01:00
WerWolv
1ed56c1b1d fix: Wrong native scaling on Wayland 2025-02-16 21:59:30 +01:00
WerWolv
983be04722 impr: Allow accent colors to have darker colors 2025-02-16 21:24:23 +01:00
WerWolv
1bd9c918f6 fix: Crash when custom disassembler returns no bytes 2025-02-16 21:11:02 +01:00
WerWolv
0ba16485bb patterns: Updated pattern language 2025-02-16 21:06:39 +01:00
WerWolv
1d9934830b fix: Pattern editor being shifted to the left on evaluate 2025-02-16 20:50:49 +01:00
WerWolv
806d6148eb fix: Pattern console log logic 2025-02-16 20:08:36 +01:00
WerWolv
e484587778 fix: Don't parse version string on every call 2025-02-16 20:08:10 +01:00
WerWolv
1e4b5104b7 build: Updated libwolv 2025-02-16 20:07:44 +01:00
WerWolv
676d2e2ef5 build: Fixed release note generator script 2025-02-16 19:24:40 +01:00
WerWolv
6122d44bd9 git: Fixed dnf cache key 2025-02-16 19:24:27 +01:00
WerWolv
eb9f0cdf0c build: Bumped version to 1.38.0.WIP 2025-02-16 19:24:10 +01:00
WerWolv
01f4595aab build: Bumped version to 1.37.0 2025-02-16 17:13:50 +01:00
WerWolv
bf10d333cd fix: Default scale of Web version on macOS 2025-02-16 16:35:37 +01:00
WerWolv
267ef37cb6 fix: Use after free when logging during plugin unload 2025-02-16 16:19:00 +01:00
WerWolv
879e4c9d58 build: Move menu items handler into libimhex 2025-02-16 15:48:44 +01:00
WerWolv
67340e1526 impr: Make sure to only ever load plugins once 2025-02-16 15:14:23 +01:00
WerWolv
6ec8f9efe5 fix: Allow --select subcommand to work with hex numbers 2025-02-16 15:02:29 +01:00
WerWolv
c2b0560d91 git: Make sure entitlements are applied correctly to ARM macos builds 2025-02-16 14:58:29 +01:00
WerWolv
388071557e impr: Reduce opacity of modal backdrop 2025-02-16 14:33:17 +01:00
WerWolv
f6e3ede178 impr: Make hyperlink icons gray 2025-02-16 14:30:06 +01:00
WerWolv
a907550567 fix: Title bar backdrop not working correctly on macOS 2025-02-16 14:24:00 +01:00
WerWolv
c75a15dc3b patterns: Updated pattern language 2025-02-16 14:21:19 +01:00
WerWolv
83904aa1f1 fix: Disable alpha display in various color buttons 2025-02-16 14:12:58 +01:00
WerWolv
7d527fd2a6 feat: Added disassemblers tab to content store 2025-02-16 13:58:56 +01:00
paxcut
007e04bf37 fix: Auto evaluate not working when undoing changes (#2106)
The pattern editor was resetting the flag that marked text changes on
every frame, but resolving a text change may take more than one frame,
so instead I created a function that allows the resetting of the text
changed boolean from view pattern editor.

Currently, when a pattern is evaluated the pattern editor will lose
focus regardless of how evaluation was triggered. This is specially
annoying when using f5 or auto-evaluate. Now whenever a pattern is
evaluated, focus is given to the pattern editor when evaluation ends.

JumptoLine didn't work for empty lines.

Co-authored-by: Nik <werwolv98@gmail.com>
2025-02-16 12:20:22 +00:00
paxcut
caff49504e impr: Better home shortcut for pattern editor (#2105)
The old home shortcut moved the cursor to column zero of the current
line.
Most editors move cursor to the first non-space character instead.
2025-02-16 12:53:07 +01:00
WerWolv
aad38beaf5 fix: Dangerous for loop comparison 2025-02-16 11:56:07 +01:00
WerWolv
bdad733331 build: Document disabled MSVC warnings 2025-02-16 11:53:01 +01:00
WerWolv
bc26ade57e fix: Double -> Float truncation 2025-02-16 11:49:32 +01:00
WerWolv
ee52ff3b11 impr: Make toolbar buttons slightly easier to see 2025-02-16 11:48:28 +01:00
WerWolv
40b95f02e4 patterns: Updated pattern language 2025-02-16 11:42:27 +01:00
WerWolv
8777a85630 fix: Make title bar backdrop stay where it is on resize 2025-02-16 11:40:09 +01:00
WerWolv
870aeb34fc feat: Added a title bar backdrop color gradient 2025-02-16 11:33:41 +01:00
WerWolv
b03be212b3 git: Fixed AppImage runner caching 2025-02-16 11:11:24 +01:00
WerWolv
c8f7dbf85e fix: Remove settings scaling warning as it doesn't make any sense anymore now 2025-02-16 10:56:01 +01:00
WerWolv
9e826b4c8b fix: Make sure shortcuts migration routine runs again with this release 2025-02-16 10:48:29 +01:00
WerWolv
05d528b39a git: Disable attestation for pull requests again 2025-02-16 10:03:17 +01:00
Justus Garbe
6828c7c077 fix: crash when disassembler encounters invalid instructions (#2116) 2025-02-16 00:52:30 +01:00
WerWolv
54f3bc0262 impr: Use heuristic to determine backing scale factor on the web 2025-02-15 22:30:06 +01:00
WerWolv
e232a2b33d fix: Web build rendering 2025-02-15 22:23:49 +01:00
WerWolv
73a3b217a4 fix: Scaling on the web version 2025-02-15 21:26:03 +01:00
WerWolv
19f925c60b build: Disable stack protectors for the web build since emscripten doesn't support it 2025-02-15 21:08:05 +01:00
WerWolv
5fb488236b git: Fixed macOS DMGs not having their volume icon set 2025-02-15 21:05:50 +01:00
WerWolv
c84786f9ee git: Fixed name of macOS ARM64 release build 2025-02-15 21:05:35 +01:00
WerWolv
c1925ddf8d fix: Inverted logic of donation nag 2025-02-15 19:34:18 +01:00
WerWolv
cf194e332c impr: Move update button from welcome screen to the title bar and show a toast 2025-02-15 19:25:29 +01:00
WerWolv
d8877e7d8b build: Enabled various hardening flags on GCC and Clang 2025-02-15 19:15:34 +01:00
WerWolv
8b2184f8e3 updater: Fixed updater not working properly on macOS 2025-02-15 17:50:29 +01:00
WerWolv
a42e4c5299 updater: Added updater support for more platforms 2025-02-15 17:14:58 +01:00
WerWolv
419787e17c impr: Make auto updater work better on Windows 2025-02-15 16:46:36 +01:00
WerWolv
2d6da52a86 patterns: Updated pattern language
Fixes #2114
2025-02-15 16:10:09 +01:00
Nik
b46deb3fa0 git: Added MSVC build CI (#2115) 2025-02-15 15:44:16 +01:00
WerWolv
b70120a248 build: Updated libwolv 2025-02-15 11:16:50 +01:00
WerWolv
3a6a4011d0 feat: Added nag banners for donations 2025-02-15 11:15:56 +01:00
WerWolv
999c4d07b7 fix: More double -> float narrowing fixes 2025-02-15 11:15:39 +01:00
WerWolv
44b182c6ae impr: Handle upgrade paths better 2025-02-15 11:15:24 +01:00
WerWolv
de7bec547a build: Make VS preset use Ninja because _my god_ MSBuild sucks 2025-02-15 11:14:46 +01:00
WerWolv
5542c0bc00 fix: Multiple issues with provider load interfaces not working 2025-02-15 11:13:22 +01:00
WerWolv
83e0ce0042 fix: Corporate environment detection not working correctly 2025-02-15 11:09:20 +01:00
WerWolv
4685dea075 git: Fix attestation generation 2025-02-11 23:52:46 +01:00
WerWolv
599f63bc67 build: Updated libwolv 2025-02-11 23:45:55 +01:00
WerWolv
199f2aea77 build: Updated disassembler library 2025-02-11 23:09:15 +01:00
WerWolv
bff9b8b4b1 feat: Fixed string/char names in data inspector, added utf16 and utf32 string and char types 2025-02-11 23:05:56 +01:00
WerWolv
a83610bc06 build: Updated libwolv 2025-02-11 23:05:25 +01:00
WerWolv
b3d208e6e6 impr: Allow sidebar to be only resized from the right 2025-02-10 21:42:12 +01:00
WerWolv
e8b391c0f6 feat: Added option to randomize window title 2025-02-10 14:02:32 +01:00
WerWolv
02b5df03ab impr: Drastically reduce font-related memory usage 2025-02-10 12:02:05 +01:00
WerWolv
e1580e51cf build: Make ImHex fully compile with warnings enabled in MSVC 2025-02-10 09:42:35 +01:00
WerWolv
3a7578879f fix: RGBA8 data processor node not working correctly 2025-02-09 23:38:35 +01:00
WerWolv
ea3d4b41a9 patterns: Updated pattern language 2025-02-09 10:28:46 +01:00
WerWolv
e0c2a39ce7 build: Fix ARM64 macOS build issues 2025-02-08 11:27:40 +01:00
WerWolv
1fa27b7f09 build: Fix remaining wasm build issues 2025-02-08 10:50:04 +01:00
WerWolv
f980f1dae2 build: Compress wasm build romfs 2025-02-07 23:56:50 +01:00
WerWolv
b81ad53449 build: Move vcpkg.json away 2025-02-07 23:56:50 +01:00
WerWolv
a9727171e2 build: vcpkg is already installed in the macOS docker 2025-02-07 23:37:10 +01:00
WerWolv
a1634fb337 build: Properly update vcpkg pages in web and macOS ARM docker 2025-02-07 23:34:05 +01:00
WerWolv
94a2f9460e impr: Use proper main() return values in forwarder 2025-02-07 22:19:35 +01:00
WerWolv
18cd39270a fix: Very slow processing of large pattern console outputs 2025-02-07 22:19:15 +01:00
WerWolv
72c2bca363 fix: Severe lack of easter eggs 2025-02-07 16:24:57 +01:00
WerWolv
4c153dc76d fix: Windows forwarder application not working when piping output 2025-02-07 16:23:27 +01:00
WerWolv
e63606f6bb feat: Added separate --version-short command 2025-02-07 15:46:11 +01:00
WerWolv
ed6da7fe14 fix: Writing not working correctly through a provider view 2025-02-07 15:45:38 +01:00
WerWolv
a588c96440 fix: Properly trigger global shortcuts 2025-02-06 22:34:34 +01:00
WerWolv
4c284b224e fix: Properly trigger all shortcuts 2025-02-06 22:33:14 +01:00
WerWolv
96afa650d1 fix: Properly trigger shortcuts on selected view on macOS 2025-02-06 22:13:06 +01:00
WerWolv
f17d0d3ae1 impr: Added simplified output option for --version 2025-02-06 21:46:27 +01:00
WerWolv
930d2b4280 fix: Some shortcuts not working correctly on macOS 2025-02-06 15:58:18 +01:00
WerWolv
f67b78bd91 build: Update vcpkg baseline on build 2025-02-06 15:24:57 +01:00
WerWolv
540e8ed602 build: Install vcpkg again in the ARM64 macOS docker 2025-02-06 15:21:07 +01:00
WerWolv
99cb51e813 build: Updated vcpkg baseline 2025-02-06 15:08:48 +01:00
WerWolv
db000c4b12 fix: Missing GLFW include on macOS 2025-02-06 14:12:52 +01:00
WerWolv
0cd557a686 impr: Remove frame from selectable text regions 2025-02-06 14:00:32 +01:00
WerWolv
6142bf859b fix: Missing new line 2025-02-06 13:27:48 +01:00
WerWolv
b6498b5c2d fix: Build error when including file in ObjC code 2025-02-06 13:04:36 +01:00
WerWolv
c15030e96e git: Remove libpl from PDB extraction process 2025-02-06 13:04:01 +01:00
WerWolv
cd2acd73b4 build: Fix libpl linking 2025-02-06 12:08:57 +01:00
WerWolv
cfe06ea1b6 build: Statically link libpl again everywhere 2025-02-06 12:03:20 +01:00
WerWolv
ca5c3e0e94 build: Fix linking against libpl in external plugins 2025-02-05 20:09:42 +01:00
WerWolv
6252fd399a fix: Loading/Storing of shortcut keys 2025-02-05 20:09:24 +01:00
WerWolv
de571e2c2a build: Updated libwolv 2025-02-05 20:09:12 +01:00
WerWolv
0cbd052b91 build: Updated dependencies 2025-02-05 15:09:09 +01:00
WerWolv
aa3ec3ece8 build: Updated dependencies 2025-02-05 13:49:16 +01:00
WerWolv
6b11028b72 impr: Use proper function to get environment variables 2025-02-05 13:47:38 +01:00
WerWolv
269c3e7398 fix: Wrong keys being loaded from settings for shortcuts 2025-02-05 13:47:17 +01:00
WerWolv
08335041f5 fix: Crash on Linux uf XDG_SESSION_TYPE is not set 2025-02-05 09:40:13 +01:00
WerWolv
d75b9cf942 build: Properly link plugins against libpl if it's a shared library 2025-02-04 12:16:46 +01:00
WerWolv
b55c40523f fix: Crash when closing ImHex with one or more view providers open 2025-02-04 09:35:26 +01:00
WerWolv
99a2dee7a2 build: Updated libromfs 2025-02-03 22:06:43 +01:00
WerWolv
c94265c77b build: Only add magic library dir in regular build 2025-02-03 21:48:13 +01:00
WerWolv
7ddfba1b4c build: Exclude more libraries from external plugin builds 2025-02-03 21:46:21 +01:00
WerWolv
9ecdd28eea build: Don't link against libcurl in external plugin builds 2025-02-03 21:43:57 +01:00
WerWolv
d8b36242f6 build: Don't set EXPORT_SYMBOLS when doing an external plugin build 2025-02-03 21:33:41 +01:00
WerWolv
3f470aabe9 fix: Compile errors 2025-02-03 21:11:48 +01:00
WerWolv
1e8dd54b3e build: Don't set -Wno-unused-result on MSVC 2025-02-03 20:51:47 +01:00
WerWolv
0a6681ccb7 impr: Remove dependencies on curl, mbedTLS and GLFW in the SDK 2025-02-03 20:50:11 +01:00
WerWolv
0140e24822 build: Fixed warning in miniaudio library 2025-02-03 16:05:40 +01:00
WerWolv
9fb38922ea impr: Disable main menu items for views that aren't selected right now 2025-02-02 22:32:24 +01:00
WerWolv
7752354598 impr: Make dark theme text slightly off-white 2025-02-02 21:48:12 +01:00
WerWolv
497670c4c3 fix: Don't apply backing scale factor twice to splash screen 2025-02-02 21:36:49 +01:00
WerWolv
84954cd2f1 build: Fixed more SDK errors 2025-02-02 21:22:42 +01:00
WerWolv
8b6eab401e fix: "Other Data Sources" welcome screen sub-window being too tall 2025-02-02 21:15:56 +01:00
WerWolv
71c11a5923 fix: Banner position being wrong while provider is loaded 2025-02-02 21:15:31 +01:00
WerWolv
f345edb252 fix: Banners not being part of the main viewport 2025-02-02 21:06:18 +01:00
WerWolv
be40fd9563 build: Apply flags correctly for imported libraries 2025-02-02 20:50:49 +01:00
WerWolv
5ee2ebfb4f build: Fix addXXXFlag functions for interface targets 2025-02-02 20:32:24 +01:00
WerWolv
cfa6b706a8 patterns: Updated pattern language 2025-02-02 20:32:06 +01:00
WerWolv
42f2a62d62 build: Make plugin library sdk path relative 2025-02-02 19:05:10 +01:00
WerWolv
41b6ef930a build: Fix MinGW build 2025-02-02 17:19:34 +01:00
WerWolv
948cbe0a9c build: Updated dependencies 2025-02-02 13:08:08 +01:00
WerWolv
18669f3230 build: Move back to upstream lunasvg 2025-02-02 12:14:32 +01:00
Tim Blume
4e9f944204 build: Install include folders of plugin libraries to SDK (#2074)
Partially fixes #2068 .

This assumes the headers are in "include" for all plugins - this is
necessary since the INCLUDES argument of add_imhex_plugin may contain
paths to third party libs, whose headers should not be copied.
To fix this I think it is necessary to add a second argument like
"PRIVATE_INCLUDES", which is included, but not installed.

With this it possible to append the ui plugin for example:
```
INCLUDES
        $ENV{IMHEX_SDK_PATH}/lib/plugins/ui/
```
and to link against it:
```    
LIBRARIES
        /usr/local/lib/imhex/plugins/ui.hexpluglib
```

In a follow-up in the CMake Template for plugins imho there should be
fixed, that:

 - you can include plugin includes relative to the SDK Path
- you can link plugins relative to the lib path + without the hexpluglib
or hexplug extension

---------

Co-authored-by: Tim Blume <git@3nd.io>
Co-authored-by: Nik <werwolv98@gmail.com>
2025-02-02 12:12:40 +01:00
WerWolv
fe18cbaa41 fix: Always properly jump to cursor position when scrolling with arrow keys
Fixes #1582
2025-02-02 12:06:34 +01:00
WerWolv
ed3712e1b9 fix: Shortcuts not working until a modal is opened 2025-02-02 12:00:59 +01:00
WerWolv
20dc4f31f0 impr: Show a loading spinner while providers are loading 2025-02-02 11:24:50 +01:00
WerWolv
19f9296a40 feat: Added blocking tasks that show a full-screen modal when active 2025-02-02 11:24:28 +01:00
WerWolv
06c019387c build: Fix most remaining warnings 2025-02-01 22:11:19 +01:00
WerWolv
645b43e9cc fix: Various MSVC warnings 2025-02-01 20:54:00 +01:00
WerWolv
ed37a3711f build: Fix extra comma 2025-02-01 20:23:02 +01:00
WerWolv
a3460de9dc build: Make VS CMake Preset do a 64 bit build 2025-02-01 20:20:42 +01:00
WerWolv
5084009d62 fix: Invalid iterator dereference when removing providers 2025-02-01 20:10:13 +01:00
WerWolv
e5c003d726 fix: Only use __declspec on with MSVC 2025-02-01 19:57:39 +01:00
WerWolv
327a02b87d fix: Plugins not having a proper entry point on MSVC 2025-02-01 19:14:15 +01:00
WerWolv
e9bf1a9f7a fix: Crash when no plugins were loaded 2025-02-01 18:08:47 +01:00
WerWolv
0c6fa768ea build: Fix building for 64bit with MSVC 2025-02-01 18:08:35 +01:00
WerWolv
483468a6c7 impr: Make WorkspaceManager internals static 2025-02-01 16:02:45 +01:00
WerWolv
8039ae1b90 build: Make ImHex fully compile with MSVC and Clang CL
This does NOT make ImHex work yet. However it can now be compiled
2025-02-01 15:13:13 +01:00
WerWolv
466b372d41 build: Added vcpkg manifest 2025-01-31 23:48:52 +01:00
WerWolv
3f6b5203ca fix: Further MSVC compile fixes 2025-01-31 23:48:38 +01:00
WerWolv
8d1352ddff fix: Remaining compile errors 2025-01-31 20:23:47 +01:00
WerWolv
e6ab2c3b7e impr: Various small fixes and improvements 2025-01-31 19:43:39 +01:00
WerWolv
e603c75bd3 build: Updated dependencies 2025-01-31 19:40:58 +01:00
WerWolv
4f28f97141 git: Fix workflow indentation 2025-01-30 22:34:50 +01:00
WerWolv
d0b32e5224 git: Try creating dmg a few times again in case XProtect is being a bitch 2025-01-30 22:25:00 +01:00
WerWolv
2062a23347 patterns: Updated pattern language 2025-01-30 22:12:04 +01:00
WerWolv
8c9236a066 patterns: Updated pattern language 2025-01-30 21:31:14 +01:00
paxcut
2f981ef91e fix: Banners not scaling properly with font size (#2096)
The banner windows did not scale with the fonts resulting in cropped
text when font size was made bigger than normal.
fixed by ensuring the window is big enough and then making sure text is
centered in the y-axis.
2025-01-30 20:18:44 +01:00
WerWolv
6725c170ea build: Updated dependencies 2025-01-30 20:12:19 +01:00
WerWolv
c8cf6e7c08 build: Fix compile errors on platforms where sizeof(long double) > sizeof(unsigned long long) 2025-01-29 22:16:42 +01:00
Connor Gibson
e0b4acee12 build: Updated macOS compile instructions as Brewfile has moved (#2093)
<!--
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
Brewfile has moved from `dist/Brewfile` to `dist/macOS/Brewfile`.

### Implementation description
Updated build instructions to reflect this previous change

### Screenshots
N/A

### Additional things
N/A
2025-01-29 21:38:47 +01:00
WerWolv
803ebe34ed build: Update for software defined 128 bit types 2025-01-29 21:37:41 +01:00
WerWolv
e981eff1e6 fix: Uninitialized buffers in resize operation 2025-01-29 18:39:19 +01:00
WerWolv
aee7a09b6c feat: Added new --select, --pattern and --debug-mode subcommands 2025-01-29 18:32:54 +01:00
WerWolv
e74e4e92a0 build: Updated libwolv 2025-01-29 18:32:35 +01:00
WerWolv
6dba15defd impr: Removed black border from splash screen bytes 2025-01-28 23:41:44 +01:00
WerWolv
fee7a16692 fix: Exception being thrown while loading projects
Fixes #2091
2025-01-28 23:23:31 +01:00
WerWolv
141030344b fix: Crash when certain pattern language exceptions were thrown
Fixes #2091
2025-01-28 23:23:08 +01:00
WerWolv
4fa9586206 impr: Added Russian language to WiX installer and ImHex Web 2025-01-28 20:55:10 +01:00
WerWolv
fbbc430b7c fix: Body text being displayed in response text field 2025-01-28 20:53:01 +01:00
WerWolv
bfc68c4d28 fix: Replace HTTP Requests text editors with input text boxes 2025-01-28 20:52:00 +01:00
WerWolv
53fc018ada fix: --pl subcommand not working correctly anymore 2025-01-28 19:47:20 +01:00
WerWolv
d45dd45720 fix: Windows system error messages not being encoded correctly 2025-01-28 19:33:31 +01:00
WerWolv
19a9786bbf impr: Make ImHex cli work more like other tools 2025-01-28 18:41:29 +01:00
WerWolv
b8caf41423 fix: Make sure splash screen is rendered consistently on all platforms 2025-01-28 18:38:20 +01:00
WerWolv
0b3866a56a fix: Wrong usage of windows icon texture 2025-01-27 22:35:27 +01:00
WerWolv
53a7577416 impr: Allow resizing of settings window 2025-01-27 22:20:15 +01:00
WerWolv
f5515417d6 fix: Message dispatching related build issues 2025-01-27 22:15:39 +01:00
WerWolv
24e7c2f3db fix: Make sure all textures are destroyed before glfw gets uninitialized 2025-01-27 22:10:30 +01:00
WerWolv
6e6c5bbc67 fix: Splash screen texture scaling 2025-01-27 21:20:59 +01:00
WerWolv
f4403ff480 impr: Make splash screen use SVG directly 2025-01-27 20:45:30 +01:00
WerWolv
098da20761 fix: Delete splash textures before destroying splash screen 2025-01-27 19:08:01 +01:00
WerWolv
ef2373e8c0 feat: Implement messaging support for Linux 2025-01-27 19:07:22 +01:00
WerWolv
b2c8ed17d5 feat: Added shortcut for opening settings 2025-01-26 22:41:20 +01:00
Nik
bb594a459f feat: Implemented macOS messaging support (#2088) 2025-01-26 18:50:19 +01:00
WerWolv
7340a30650 impr: Make scalable font the default 2025-01-26 14:26:57 +01:00
361 changed files with 14317 additions and 6119 deletions

View File

@@ -15,8 +15,8 @@ env:
jobs:
# Windows build
win:
# Windows MINGW build
win_mingw:
runs-on: windows-2022
name: 🪟 Windows MINGW64
@@ -41,8 +41,8 @@ jobs:
uses: hendrikmuhs/ccache-action@v1
id: cache-ccache
with:
key: ${{ runner.os }}-ccache-${{ github.run_id }}
restore-keys: ${{ runner.os }}-ccache
key: ${{ runner.os }}-mingw-ccache-${{ github.run_id }}
restore-keys: ${{ runner.os }}-mingw-ccache
max-size: 1G
- name: 🟦 Install msys2
@@ -103,7 +103,6 @@ jobs:
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
@@ -132,7 +131,6 @@ jobs:
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
@@ -142,7 +140,7 @@ jobs:
- name: 🗝️ Generate build provenance attestations
uses: actions/attest-build-provenance@v2
if: github.event.pull_request.head.repo.full_name == github.repository
if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }}
with:
subject-path: |
imhex-*.msi
@@ -180,6 +178,80 @@ jobs:
path: |
build/install/*
win_msvc:
runs-on: windows-2022
name: 🪟 Windows MSVC
env:
CCACHE_DIR: "${{ github.workspace }}/.ccache"
permissions:
id-token: write
attestations: write
steps:
- name: 🧰 Checkout
uses: actions/checkout@v4
with:
submodules: recursive
- name: 🫧 Setup Visual Studio Dev Environment
uses: ilammy/msvc-dev-cmd@v1
with:
arch: amd64
- name: 📜 Setup ccache
uses: hendrikmuhs/ccache-action@v1
id: cache-ccache
with:
key: ${{ runner.os }}-msvc-ccache-${{ github.run_id }}
restore-keys: ${{ runner.os }}-msvc-ccache
max-size: 1G
- name: 📦 Install vcpkg
uses: friendlyanon/setup-vcpkg@v1
with: { committish: 7e21420f775f72ae938bdeb5e6068f722088f06a }
- name: ⬇️ Install dependencies
run: |
cp dist/vcpkg.json vcpkg.json
- name: ⬇️ Install CMake and Ninja
uses: lukka/get-cmake@latest
- name: ⬇️ Install .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.100'
- name: 📜 Set version variable
run: |
"IMHEX_VERSION=$(Get-Content VERSION -Raw)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
# Windows cmake build
- name: 🛠️ Configure CMake
run: |
mkdir -p build
cmake -G "Ninja" -B build `
--preset vs2022 `
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" `
-DCMAKE_C_COMPILER="$($(Get-Command cl.exe).Path)" `
-DCMAKE_CXX_COMPILER="$($(Get-Command cl.exe).Path)" `
-DCMAKE_C_COMPILER_LAUNCHER=ccache `
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache `
-DCMAKE_BUILD_TYPE="$env:BUILD_TYPE" `
-DIMHEX_PATTERNS_PULL_MASTER=ON `
-DIMHEX_COMMIT_HASH_LONG="$env:GITHUB_SHA" `
-DIMHEX_COMMIT_BRANCH="$($env:GITHUB_REF -replace '.*/', '')" `
-DDOTNET_EXECUTABLE="C:/Program Files/dotnet/dotnet.exe" `
.
- name: 🛠️ Build
run: |
cd build
ninja
win-plugin-template-test:
runs-on: windows-2022
name: 🧪 Plugin Template Test
@@ -188,7 +260,7 @@ jobs:
run:
shell: msys2 {0}
needs: win
needs: win_mingw
env:
IMHEX_SDK_PATH: "${{ github.workspace }}/out/sdk"
@@ -273,6 +345,9 @@ jobs:
restore-keys: ${{ runner.os }}${{ matrix.suffix }}-ccache
max-size: 1G
- name: Set Xcode version
run: sudo xcode-select -s /Library/Developer/CommandLineTools
- name: ⬇️ Install dependencies
env:
# Make brew not display useless errors
@@ -280,7 +355,7 @@ jobs:
run: |
brew reinstall python --quiet || true
brew link --overwrite --quiet python 2>/dev/null || true
brew bundle --no-lock --quiet --file dist/macOS/Brewfile || true
brew bundle --quiet --file dist/macOS/Brewfile || true
rm -rf /usr/local/Cellar/capstone
- name: ⬇️ Install classic glfw
@@ -371,17 +446,22 @@ jobs:
- name: 📦 Create DMG
run: |
brew install imagemagick
brew install graphicsmagick 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
for i in $(seq 1 10); do
create-dmg ImHex.app || true
if ls -d *.dmg 1>/dev/null 2>/dev/null; then
break;
fi
done
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
if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }}
with:
subject-path: |
./*.dmg
@@ -423,6 +503,7 @@ jobs:
run: |
echo "IMHEX_VERSION=`cat VERSION`" >> $GITHUB_OUTPUT
docker buildx build . -f dist/macOS/arm64.Dockerfile --progress=plain --build-arg 'JOBS=4' --build-arg "BUILD_TYPE=$(BUILD_TYPE)" --build-context imhex=$(pwd) --output out
cp resources/dist/macos/Entitlements.plist out/Entitlements.plist
- name: ⬆️ Upload artifacts
uses: actions/upload-artifact@v4
@@ -445,7 +526,7 @@ jobs:
needs: macos-arm64
env:
IMHEX_VERSION: ${{ needs.macos-arm64-build.outputs.IMHEX_VERSION }}
IMHEX_VERSION: ${{ needs.macos-arm64.outputs.IMHEX_VERSION }}
permissions:
id-token: write
@@ -469,7 +550,7 @@ jobs:
cd out
mv imhex.app ImHex.app
codesign --remove-signature ImHex.app
codesign --force --deep --sign - ImHex.app
codesign --force --deep --entitlements Entitlements.plist --sign - ImHex.app
- name: 📁 Fix permissions
run: |
@@ -485,17 +566,22 @@ jobs:
- name: 📦 Create DMG
run: |
brew install imagemagick
brew install graphicsmagick imagemagick
git clone https://github.com/sindresorhus/create-dmg
cd create-dmg
npm i && npm -g i
cd ../out
create-dmg ImHex.app || true
for i in $(seq 1 10); do
create-dmg ImHex.app || true
if ls -d *.dmg 1>/dev/null 2>/dev/null; then
break;
fi
done
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
if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }}
with:
subject-path: |
./*.dmg
@@ -515,6 +601,7 @@ jobs:
include:
- release_num: "24.04"
- release_num: "24.10"
- release_num: "25.04"
name: 🐧 Ubuntu ${{ matrix.release_num }}
runs-on: ubuntu-24.04
@@ -589,7 +676,7 @@ jobs:
- name: 🗝️ Generate build provenance attestations
uses: actions/attest-build-provenance@v2
if: github.event.pull_request.head.repo.full_name == github.repository
if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }}
with:
subject-path: |
./*.deb
@@ -633,8 +720,8 @@ jobs:
uses: actions/cache@v4
with:
path: cache
key: appimage-ccache-${{ github.run_id }}
restore-keys: appimage-cache
key: appimage-ccache-${{ matrix.architecture }}-${{ github.run_id }}
restore-keys: appimage-ccache-${{ matrix.architecture }}
- name: 🐳 Inject /cache into docker
uses: reproducible-containers/buildkit-cache-dance@v2
@@ -651,7 +738,7 @@ jobs:
- name: 🗝️ Generate build provenance attestations
uses: actions/attest-build-provenance@v2
if: github.event.pull_request.head.repo.full_name == github.repository
if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }}
with:
subject-path: |
out/*.AppImage
@@ -768,7 +855,7 @@ jobs:
- name: 🗝️ Generate build provenance attestations
uses: actions/attest-build-provenance@v2
if: github.event.pull_request.head.repo.full_name == github.repository
if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }}
with:
subject-path: |
build/imhex-${{ env.IMHEX_VERSION }}-ArchLinux-x86_64.pkg.tar.zst
@@ -791,14 +878,14 @@ jobs:
mock_release: rawhide
release_num: rawhide
mock_config: fedora-rawhide
- name: Fedora
mock_release: f42
release_num: 42
mock_config: fedora-42
- 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: RHEL-AlmaLinux
mock_release: epel9
release_num: 9
@@ -844,7 +931,7 @@ jobs:
path: /var/cache/dnf
key: ${{ matrix.mock_release }}-dnf-${{ github.run_id }}
restore-keys: |
${{ matrix.mock_release }}-dnf-
${{ matrix.mock_release }}-dnf
- name: ⬇️ Update all packages and install dependencies
run: |
@@ -912,7 +999,7 @@ jobs:
- name: 🗝️ Generate build provenance attestations
uses: actions/attest-build-provenance@v2
if: github.event.pull_request.head.repo.full_name == github.repository
if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }}
with:
subject-path: |
imhex-${{ env.IMHEX_VERSION }}-${{ matrix.name }}-${{ matrix.release_num }}-x86_64.rpm
@@ -952,10 +1039,18 @@ jobs:
- name: 🛠️ Build using docker
run: |
docker buildx build . -f dist/web/Dockerfile --progress=plain --build-arg 'JOBS=4' --output out --target raw
mkdir -p out/nightly
docker buildx build . -f dist/web/Dockerfile --progress=plain --build-arg 'JOBS=4' --output out/nightly --target raw
- name: ⬇️ Download Release
uses: robinraju/release-downloader@v1
with:
latest: true
fileName: 'imhex-*-Web.zip'
- name: 🔨 Fix permissions
run: |
unzip imhex-*-Web.zip -d out
chmod -c -R +rX "out/"
- name: ⬆️ Upload artifacts
@@ -965,14 +1060,14 @@ jobs:
- name: 🔨 Copy necessary files
run: |
cp dist/web/serve.py out/start_imhex_web.py
cp dist/web/serve.py out/nightly/start_imhex_web.py
- name: ⬆️ Upload package
uses: actions/upload-artifact@v4
with:
if-no-files-found: error
name: ImHex Web
path: out/*
path: out/nightly/*
# See https://github.com/actions/cache/issues/342#issuecomment-1711054115
- name: 🗑️ Delete old cache

View File

@@ -117,7 +117,8 @@ 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
mv "ImHex Web.zip" imhex-${{ env.IMHEX_VERSION }}-Web.zip
rm artifact.tar
- name: ⬆️ Upload everything to release
uses: softprops/action-gh-release@4634c16e79c963813287e889244c50009e7f0981

5
.gitignore vendored
View File

@@ -7,6 +7,8 @@ build*/
local/
venv/
.cache/
install/
out/
*.mgc
*.kdev4
@@ -14,3 +16,6 @@ imgui.ini
.DS_Store
CMakeUserPresets.json
Brewfile.lock.json
.vs/
vcpkg.json

7
.gitmodules vendored
View File

@@ -24,11 +24,11 @@
ignore = dirty
[submodule "lib/third_party/edlib"]
path = lib/third_party/edlib
url = https://github.com/Martinsos/edlib
url = https://github.com/blawrence-ont/edlib
ignore = dirty
[submodule "lib/third_party/lunasvg"]
path = lib/third_party/lunasvg
url = https://github.com/WerWolv/lunasvg
url = https://github.com/sammycage/lunasvg
ignore = dirty
[submodule "lib/external/libromfs"]
@@ -47,3 +47,6 @@
[submodule "lib/external/disassembler"]
path = lib/external/disassembler
url = https://github.com/WerWolv/Disassembler
[submodule "lib/third_party/clip"]
path = lib/third_party/clip
url = https://github.com/dacap/clip

View File

@@ -22,6 +22,7 @@ option(IMHEX_ENABLE_STD_ASSERTS "Enable debug asserts in the C++ std lib
option(IMHEX_ENABLE_UNIT_TESTS "Enable building unit tests" OFF)
option(IMHEX_ENABLE_PRECOMPILED_HEADERS "Enable precompiled headers" OFF)
option(IMHEX_COMPRESS_DEBUG_INFO "Compress debug information" ON )
option(IMHEX_ENABLE_CXX_MODULES "Enable C++20 Module compilation. Testing only!" OFF)
set(IMHEX_BASE_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}")
set(CMAKE_MODULE_PATH "${IMHEX_BASE_FOLDER}/cmake/modules")
@@ -31,6 +32,7 @@ include("${IMHEX_BASE_FOLDER}/cmake/ide_helpers.cmake")
# Basic compiler and cmake configurations
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_SCAN_FOR_MODULES ${IMHEX_ENABLE_CXX_MODULES})
set(CMAKE_INCLUDE_DIRECTORIES_BEFORE ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include("${IMHEX_BASE_FOLDER}/cmake/build_helpers.cmake")
@@ -70,6 +72,7 @@ addBundledLibraries()
add_subdirectory(lib/libimhex)
add_subdirectory(main)
addPluginDirectories()
add_subdirectory(lib/trace)
# Add unit tests
if (IMHEX_ENABLE_UNIT_TESTS)

View File

@@ -45,6 +45,15 @@
"IMHEX_IDE_HELPERS_OVERRIDE_XCODE_COMPILER": "ON"
}
},
{
"name": "vs2022",
"displayName": "Visual Studio 2022",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
}
}
],
"buildPresets": [

View File

@@ -1 +1 @@
1.37.0.WIP
1.38.0.WIP

View File

@@ -10,6 +10,62 @@ if (POLICY CMP0177)
cmake_policy(SET CMP0177 OLD)
endif()
function(getTarget target type)
get_target_property(IMPORTED_TARGET ${target} IMPORTED)
if (IMPORTED_TARGET)
set(${type} INTERFACE PARENT_SCOPE)
else()
set(${type} PRIVATE PARENT_SCOPE)
endif()
endfunction()
function(addCFlag)
if (ARGC EQUAL 1)
add_compile_options($<$<COMPILE_LANGUAGE:C>:${ARGV0}>)
elseif (ARGC EQUAL 2)
getTarget(${ARGV1} TYPE)
target_compile_options(${ARGV1} ${TYPE} $<$<COMPILE_LANGUAGE:C>:${ARGV0}>)
endif()
endfunction()
function(addCXXFlag)
if (ARGC EQUAL 1)
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:${ARGV0}>)
elseif (ARGC EQUAL 2)
getTarget(${ARGV1} TYPE)
target_compile_options(${ARGV1} ${TYPE} $<$<COMPILE_LANGUAGE:CXX>:${ARGV0}>)
endif()
endfunction()
function(addObjCFlag)
if (ARGC EQUAL 1)
add_compile_options($<$<COMPILE_LANGUAGE:OBJC>:${ARGV0}>)
elseif (ARGC EQUAL 2)
getTarget(${ARGV1} TYPE)
target_compile_options(${ARGV1} ${TYPE} $<$<COMPILE_LANGUAGE:OBJC>:${ARGV0}>)
endif()
endfunction()
function(addLinkerFlag)
if (ARGC EQUAL 1)
add_link_options(${ARGV0})
elseif (ARGC EQUAL 2)
getTarget(${ARGV1} TYPE)
target_link_options(${ARGV1} ${TYPE} ${ARGV0})
endif()
endfunction()
function(addCCXXFlag)
addCFlag(${ARGV0} ${ARGV1})
addCXXFlag(${ARGV0} ${ARGV1})
endfunction()
function(addCommonFlag)
addCFlag(${ARGV0} ${ARGV1})
addCXXFlag(${ARGV0} ${ARGV1})
addObjCFlag(${ARGV0} ${ARGV1})
endfunction()
set(CMAKE_WARN_DEPRECATED OFF CACHE BOOL "Disable deprecated warnings" FORCE)
include(FetchContent)
@@ -73,7 +129,9 @@ macro(detectOS)
set(CMAKE_INSTALL_LIBDIR ".")
set(PLUGINS_INSTALL_LOCATION "plugins")
add_compile_definitions(WIN32_LEAN_AND_MEAN)
add_compile_definitions(NOMINMAX)
add_compile_definitions(UNICODE)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
elseif (APPLE)
add_compile_definitions(OS_MACOS)
set(CMAKE_INSTALL_BINDIR ".")
@@ -124,7 +182,7 @@ macro(configurePackingResources)
set(CPACK_WIX_PRODUCT_ICON "${PROJECT_SOURCE_DIR}/resources/dist/windows/icon.ico")
set(CPACK_WIX_UI_BANNER "${PROJECT_SOURCE_DIR}/resources/dist/windows/wix_banner.png")
set(CPACK_WIX_UI_DIALOG "${PROJECT_SOURCE_DIR}/resources/dist/windows/wix_dialog.png")
set(CPACK_WIX_CULTURES "en-US;de-DE;ja-JP;it-IT;pt-BR;zh-CN;zh-TW")
set(CPACK_WIX_CULTURES "en-US;de-DE;ja-JP;it-IT;pt-BR;zh-CN;zh-TW;ru-RU")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "ImHex")
set_property(INSTALL "$<TARGET_FILE_NAME:main>"
PROPERTY CPACK_START_MENU_SHORTCUTS "ImHex"
@@ -271,6 +329,7 @@ macro(createPackage)
install(FILES ${IMHEX_ICON} DESTINATION "${CMAKE_INSTALL_PREFIX}/${BUNDLE_NAME}/Contents/Resources")
install(TARGETS main BUNDLE DESTINATION ".")
install(TARGETS updater BUNDLE DESTINATION ".")
# Update library references to make the bundle portable
postprocess_bundle(imhex_all main)
@@ -323,6 +382,10 @@ endfunction()
macro(configureCMake)
message(STATUS "Configuring ImHex v${IMHEX_VERSION}")
if (DEFINED CMAKE_TOOLCHAIN_FILE)
message(STATUS "Using toolchain file: \"${CMAKE_TOOLCHAIN_FILE}\"")
endif()
set(CMAKE_POSITION_INDEPENDENT_CODE ON CACHE BOOL "Enable position independent code for all targets" FORCE)
# Configure use of recommended build tools
@@ -357,9 +420,9 @@ macro(configureCMake)
if (LD_LLD_PATH)
set(CMAKE_LINKER ${LD_LLD_PATH})
if (NOT XCODE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fuse-ld=lld")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=lld")
if (NOT XCODE AND NOT MSVC)
set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -fuse-ld=lld)
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -fuse-ld=lld)
endif()
else ()
message(WARNING "lld not found, using default linker!")
@@ -439,6 +502,8 @@ function(verifyCompiler)
message(FATAL_ERROR "ImHex requires GCC 12.0.0 or newer. Please use the latest GCC version.")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "17.0.0")
message(FATAL_ERROR "ImHex requires Clang 17.0.0 or newer. Please use the latest Clang version.")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
elseif (NOT (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
message(FATAL_ERROR "ImHex can only be compiled with GCC or Clang. ${CMAKE_CXX_COMPILER_ID} is not supported.")
endif()
@@ -506,16 +571,16 @@ function(downloadImHexPatternsFiles dest)
# Maybe patterns are cloned to a subdirectory
if (NOT EXISTS ${imhex_patterns_SOURCE_DIR})
set(imhex_patterns_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ImHex-Patterns")
set(imhex_patterns_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ImHex-Patterns")
endif()
# Or a sibling directory
if (NOT EXISTS ${imhex_patterns_SOURCE_DIR})
set(imhex_patterns_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../ImHex-Patterns")
set(imhex_patterns_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../ImHex-Patterns")
endif()
endif ()
if (NOT EXISTS ${imhex_patterns_SOURCE_DIR})
if (NOT EXISTS ${imhex_patterns_SOURCE_DIR})
message(WARNING "Failed to locate ImHex-Patterns repository, some resources will be missing during install!")
elseif(XCODE)
# The Xcode build has multiple configurations, which each need a copy of these files
@@ -558,34 +623,67 @@ macro(setupDebugCompressionFlag)
elseif (COMPRESS_AVAILABLE_COMPILER AND COMPRESS_AVAILABLE_LINKER)
message("Using default compression for debug info because both compiler and linker support it")
set(DEBUG_COMPRESSION_FLAG "-gz" CACHE STRING "Cache to use for debug info compression")
else()
set(DEBUG_COMPRESSION_FLAG "" CACHE STRING "Cache to use for debug info compression")
endif()
endif()
set(IMHEX_COMMON_FLAGS "${IMHEX_COMMON_FLAGS} ${DEBUG_COMPRESSION_FLAG}")
addCommonFlag(${DEBUG_COMPRESSION_FLAG})
endmacro()
macro(setupCompilerFlags target)
# IMHEX_COMMON_FLAGS: flags common for C, C++, Objective C, etc.. compilers
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
addCommonFlag("/W4" ${target})
addCommonFlag("/wd4127" ${target}) # conditional expression is constant
addCommonFlag("/wd4242" ${target}) # 'identifier': conversion from 'type1' to 'type2', possible loss of data
addCommonFlag("/wd4244" ${target}) # 'conversion': conversion from 'type1' to 'type2', possible loss of data
addCommonFlag("/wd4267" ${target}) # 'var': conversion from 'size_t' to 'type', possible loss of data
addCommonFlag("/wd4305" ${target}) # truncation from 'double' to 'float'
addCommonFlag("/wd4996" ${target}) # 'function': was declared deprecated
addCommonFlag("/wd5244" ${target}) # 'include' in the purview of module 'module' appears erroneous
if (IMHEX_STRICT_WARNINGS)
addCommonFlag("/WX" ${target})
endif()
elseif (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
addCommonFlag("-Wall" ${target})
addCommonFlag("-Wextra" ${target})
addCommonFlag("-Wpedantic" ${target})
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
# Define strict compilation flags
if (IMHEX_STRICT_WARNINGS)
set(IMHEX_COMMON_FLAGS "${IMHEX_COMMON_FLAGS} -Wall -Wextra -Wpedantic -Werror")
addCommonFlag("-Werror" ${target})
endif()
if (UNIX AND NOT APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU")
set(IMHEX_COMMON_FLAGS "${IMHEX_COMMON_FLAGS} -rdynamic")
addCommonFlag("-rdynamic" ${target})
endif()
set(IMHEX_CXX_FLAGS "-fexceptions -frtti")
addCXXFlag("-fexceptions" ${target})
addCXXFlag("-frtti" ${target})
addCommonFlag("-fno-omit-frame-pointer" ${target})
# Disable some warnings
set(IMHEX_C_CXX_FLAGS "-Wno-array-bounds -Wno-deprecated-declarations -Wno-unknown-pragmas")
addCCXXFlag("-Wno-array-bounds" ${target})
addCCXXFlag("-Wno-deprecated-declarations" ${target})
addCCXXFlag("-Wno-unknown-pragmas" ${target})
addCXXFlag("-Wno-include-angled-in-module-purview" ${target})
# Enable hardening flags
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
addCommonFlag("-U_FORTIFY_SOURCE" ${target})
addCommonFlag("-D_FORTIFY_SOURCE=3" ${target})
if (NOT EMSCRIPTEN)
addCommonFlag("-fstack-protector-strong" ${target})
endif()
endif()
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
if (IMHEX_ENABLE_UNITY_BUILD AND WIN32)
set(IMHEX_COMMON_FLAGS "${IMHEX_COMMON_FLAGS} -Wa,-mbig-obj")
if (WIN32)
addLinkerFlag("-Wa,mbig-obj" ${target})
endif ()
endif()
@@ -593,36 +691,51 @@ macro(setupCompilerFlags target)
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")
addCCXXFlag("-Wno-unknown-warning-option" ${target})
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
add_compile_definitions(_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG)
else()
add_compile_definitions(_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE)
endif()
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
addCommonFlag("/bigobj" ${target})
addCFlag("/std:clatest" ${target})
addCXXFlag("/std:c++latest" ${target})
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")
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
addCCXXFlag("-Wno-restrict" ${target})
addCCXXFlag("-Wno-stringop-overread" ${target})
addCCXXFlag("-Wno-stringop-overflow" ${target})
addCCXXFlag("-Wno-dangling-reference" ${target})
endif()
# Define emscripten-specific disabled warnings
if (EMSCRIPTEN)
set(IMHEX_C_CXX_FLAGS "${IMHEX_C_CXX_FLAGS} -pthread -Wno-dollar-in-identifier-extension -Wno-pthreads-mem-growth")
addCCXXFlag("-pthread" ${target})
addCCXXFlag("-Wno-dollar-in-identifier-extension" ${target})
addCCXXFlag("-Wno-pthreads-mem-growth" ${target})
endif ()
if (IMHEX_COMPRESS_DEBUG_INFO)
setupDebugCompressionFlag()
endif()
# Set actual CMake flags
set_target_properties(${target} PROPERTIES COMPILE_FLAGS "${IMHEX_COMMON_FLAGS} ${IMHEX_C_CXX_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${IMHEX_COMMON_FLAGS} ${IMHEX_C_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${IMHEX_COMMON_FLAGS} ${IMHEX_C_CXX_FLAGS} ${IMHEX_CXX_FLAGS}")
set(CMAKE_OBJC_FLAGS "${CMAKE_OBJC_FLAGS} ${IMHEX_COMMON_FLAGS}")
# Only generate minimal debug information for stacktraces in RelWithDebInfo builds
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -g1")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -g1")
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# Add flags for debug info in inline functions
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -gstatement-frontiers -ginline-points")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -gstatement-frontiers -ginline-points")
if (CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
addCCXXFlag("-g1" ${target})
endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# Add flags for debug info in inline functions
addCCXXFlag("-gstatement-frontiers" ${target})
addCCXXFlag("-ginline-points" ${target})
endif()
endif()
endmacro()
@@ -648,6 +761,15 @@ macro(addBundledLibraries)
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/microtar EXCLUDE_FROM_ALL)
set(CLIP_ENABLE_IMAGE OFF CACHE BOOL "")
set(CLIP_EXAMPLES OFF CACHE BOOL "")
set(CLIP_TESTS OFF CACHE BOOL "")
set(CLIP_INSTALL OFF CACHE BOOL "")
set(CLIP_X11_WITH_PNG OFF CACHE BOOL "")
set(CLIP_SUPPORT_WINXP OFF CACHE BOOL "")
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/clip EXCLUDE_FROM_ALL)
target_include_directories(clip INTERFACE $<BUILD_INTERFACE:${THIRD_PARTY_LIBS_FOLDER}/clip>)
add_subdirectory(${EXTERNAL_LIBS_FOLDER}/libwolv EXCLUDE_FROM_ALL)
set(XDGPP_INCLUDE_DIRS "${THIRD_PARTY_LIBS_FOLDER}/xdgpp")
@@ -694,8 +816,8 @@ macro(addBundledLibraries)
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/lunasvg EXCLUDE_FROM_ALL)
set(LUNASVG_LIBRARIES lunasvg)
else()
find_package(LunaSVG REQUIRED)
set(LUNASVG_LIBRARIES lunasvg)
find_package(lunasvg REQUIRED)
set(LUNASVG_LIBRARIES lunasvg::lunasvg)
endif()
if (NOT USE_SYSTEM_LLVM)
@@ -717,7 +839,7 @@ macro(addBundledLibraries)
endif()
if (USE_SYSTEM_BOOST)
find_package(Boost REQUIRED)
find_package(Boost REQUIRED CONFIG COMPONENTS regex)
set(BOOST_LIBRARIES Boost::regex)
else()
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/boost ${CMAKE_CURRENT_BINARY_DIR}/boost EXCLUDE_FROM_ALL)
@@ -727,11 +849,7 @@ macro(addBundledLibraries)
set(LIBPL_BUILD_CLI_AS_EXECUTABLE OFF CACHE BOOL "" FORCE)
set(LIBPL_ENABLE_PRECOMPILED_HEADERS ${IMHEX_ENABLE_PRECOMPILED_HEADERS} CACHE BOOL "" FORCE)
if (WIN32)
set(LIBPL_SHARED_LIBRARY ON CACHE BOOL "" FORCE)
else()
set(LIBPL_SHARED_LIBRARY OFF CACHE BOOL "" FORCE)
endif()
set(LIBPL_SHARED_LIBRARY OFF CACHE BOOL "" FORCE)
add_subdirectory(${EXTERNAL_LIBS_FOLDER}/pattern_language EXCLUDE_FROM_ALL)
add_subdirectory(${EXTERNAL_LIBS_FOLDER}/disassembler EXCLUDE_FROM_ALL)
@@ -759,30 +877,6 @@ macro(addBundledLibraries)
find_package(mbedTLS 3.4.0 REQUIRED)
find_package(Magic 5.39 REQUIRED)
if (NOT IMHEX_DISABLE_STACKTRACE)
if (WIN32)
message(STATUS "StackWalk enabled!")
set(LIBBACKTRACE_LIBRARIES DbgHelp.lib)
else ()
find_package(Backtrace)
if (${Backtrace_FOUND})
message(STATUS "Backtrace enabled! Header: ${Backtrace_HEADER}")
if (Backtrace_HEADER STREQUAL "backtrace.h")
set(LIBBACKTRACE_LIBRARIES ${Backtrace_LIBRARY})
set(LIBBACKTRACE_INCLUDE_DIRS ${Backtrace_INCLUDE_DIR})
add_compile_definitions(BACKTRACE_HEADER=<${Backtrace_HEADER}>)
add_compile_definitions(HEX_HAS_BACKTRACE)
elseif (Backtrace_HEADER STREQUAL "execinfo.h")
set(LIBBACKTRACE_LIBRARIES ${Backtrace_LIBRARY})
set(LIBBACKTRACE_INCLUDE_DIRS ${Backtrace_INCLUDE_DIR})
add_compile_definitions(BACKTRACE_HEADER=<${Backtrace_HEADER}>)
add_compile_definitions(HEX_HAS_EXECINFO)
endif()
endif()
endif()
endif()
endmacro()
function(enableUnityBuild TARGET)
@@ -791,18 +885,22 @@ function(enableUnityBuild TARGET)
endif ()
endfunction()
function(generateSDKDirectory)
function(setSDKPaths)
if (WIN32)
set(SDK_PATH "./sdk")
set(SDK_PATH "./sdk" PARENT_SCOPE)
elseif (APPLE)
set(SDK_PATH "${CMAKE_INSTALL_PREFIX}/${BUNDLE_NAME}/Contents/Resources/sdk")
set(SDK_PATH "${CMAKE_INSTALL_PREFIX}/${BUNDLE_NAME}/Contents/Resources/sdk" PARENT_SCOPE)
else()
set(SDK_PATH "share/imhex/sdk")
set(SDK_PATH "share/imhex/sdk" PARENT_SCOPE)
endif()
set(SDK_BUILD_PATH "${CMAKE_BINARY_DIR}/sdk")
set(SDK_BUILD_PATH "${CMAKE_BINARY_DIR}/sdk" PARENT_SCOPE)
endfunction()
function(generateSDKDirectory)
setSDKPaths()
install(DIRECTORY ${CMAKE_SOURCE_DIR}/lib/libimhex DESTINATION "${SDK_PATH}/lib" PATTERN "**/source/*" EXCLUDE)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/lib/trace DESTINATION "${SDK_PATH}/lib" PATTERN "**/source/*" EXCLUDE)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/lib/external DESTINATION "${SDK_PATH}/lib")
install(DIRECTORY ${CMAKE_SOURCE_DIR}/lib/third_party/imgui DESTINATION "${SDK_PATH}/lib/third_party" PATTERN "**/source/*" EXCLUDE)
if (NOT USE_SYSTEM_FMT)
@@ -819,12 +917,19 @@ 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(TARGETS tracing 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/ui/include DESTINATION "${SDK_PATH}/lib/ui/include")
install(FILES ${CMAKE_SOURCE_DIR}/plugins/ui/CMakeLists.txt DESTINATION "${SDK_PATH}/lib/ui/")
if (WIN32)
install(TARGETS ui ARCHIVE DESTINATION "${SDK_PATH}/lib")
endif()
install(DIRECTORY ${CMAKE_SOURCE_DIR}/plugins/fonts DESTINATION "${SDK_PATH}/lib" PATTERN "**/source/*" EXCLUDE)
install(TARGETS fonts ARCHIVE DESTINATION "${SDK_PATH}/lib")
install(DIRECTORY ${CMAKE_SOURCE_DIR}/plugins/fonts/include DESTINATION "${SDK_PATH}/lib/fonts/include")
install(FILES ${CMAKE_SOURCE_DIR}/plugins/fonts/CMakeLists.txt DESTINATION "${SDK_PATH}/lib/fonts/")
if (WIN32)
install(TARGETS fonts ARCHIVE DESTINATION "${SDK_PATH}/lib")
endif()
endfunction()
function(addIncludesFromLibrary target library)
@@ -845,4 +950,4 @@ function(precompileHeaders target includeFolder)
PUBLIC
"$<$<COMPILE_LANGUAGE:CXX>:${INCLUDES}>"
)
endfunction()
endfunction()

View File

@@ -40,7 +40,12 @@ IF(MBEDTLS_FOUND)
STRING(REGEX REPLACE "^lib" "" MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY_FILE})
STRING(REGEX REPLACE "^lib" "" MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY_FILE})
STRING(REGEX REPLACE "^lib" "" MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY_FILE})
SET(MBEDTLS_LIBRARIES "-L${MBEDTLS_LIBRARY_DIR} -l${MBEDTLS_LIBRARY_FILE} -l${MBEDX509_LIBRARY_FILE} -l${MBEDCRYPTO_LIBRARY_FILE}")
if (MSVC)
SET(MBEDTLS_LIBRARIES ${MBEDTLS_LIBRARY_FILE}.lib ${MBEDX509_LIBRARY_FILE}.lib ${MBEDCRYPTO_LIBRARY_FILE}.lib)
else()
SET(MBEDTLS_LIBRARIES "-L${MBEDTLS_LIBRARY_DIR} -l${MBEDTLS_LIBRARY_FILE} -l${MBEDX509_LIBRARY_FILE} -l${MBEDCRYPTO_LIBRARY_FILE}")
endif()
IF(NOT MBEDTLS_FIND_QUIETLY)
MESSAGE(STATUS "Found mbedTLS:")

View File

@@ -1,4 +1,5 @@
macro(add_imhex_plugin)
setSDKPaths()
# Parse arguments
set(options LIBRARY_PLUGIN)
set(oneValueArgs NAME IMHEX_VERSION)
@@ -28,6 +29,10 @@ macro(add_imhex_plugin)
endif()
endif()
if (IMHEX_PLUGIN_LIBRARY_PLUGIN)
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/" DESTINATION "${SDK_PATH}/lib/plugins/${IMHEX_PLUGIN_NAME}")
endif()
# Define new project for plugin
project(${IMHEX_PLUGIN_NAME})
@@ -62,7 +67,11 @@ macro(add_imhex_plugin)
)
# Set rpath of plugin libraries to the plugins folder
if (APPLE)
if (WIN32)
if (IMHEX_PLUGIN_LIBRARY_PLUGIN)
set_target_properties(${IMHEX_PLUGIN_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
endif()
elseif (APPLE)
set_target_properties(${IMHEX_PLUGIN_NAME} PROPERTIES BUILD_RPATH "@executable_path/../Frameworks;@executable_path/plugins")
endif()
@@ -147,4 +156,4 @@ macro (enable_plugin_feature feature)
remove_definitions(-DIMHEX_PLUGIN_${IMHEX_PLUGIN_NAME}_FEATURE_${feature}=0)
add_definitions(-DIMHEX_PLUGIN_${IMHEX_PLUGIN_NAME}_FEATURE_${feature}=1)
endmacro()
endmacro()

View File

@@ -38,25 +38,30 @@ add_subdirectory(lib/external/libwolv EXCLUDE_FROM_ALL)
set(LIBPL_ENABLE_CLI OFF CACHE BOOL "" FORCE)
add_subdirectory(lib/external/pattern_language EXCLUDE_FROM_ALL)
find_package(CURL REQUIRED)
find_package(mbedTLS 3.4.0 REQUIRED)
set(CURL_LIBRARIES ${CURL_LIBRARIES} PARENT_SCOPE)
set(MBEDTLS_LIBRARIES ${MBEDTLS_LIBRARIES} PARENT_SCOPE)
add_subdirectory(lib/libimhex)
add_subdirectory(lib/trace)
if (WIN32)
set_target_properties(libimhex PROPERTIES
IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/../libimhex.dll"
IMPORTED_IMPLIB "${CMAKE_CURRENT_SOURCE_DIR}/lib/liblibimhex.dll.a"
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/lib/libimhex/include")
set_target_properties(tracing PROPERTIES
IMPORTED_IMPLIB "${CMAKE_CURRENT_SOURCE_DIR}/lib/libtracing.a"
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/lib/trace/include")
elseif (APPLE)
file(GLOB LIBIMHEX_DYLIB "${CMAKE_CURRENT_SOURCE_DIR}/../../Frameworks/libimhex.*.dylib")
set_target_properties(libimhex PROPERTIES
IMPORTED_LOCATION "${LIBIMHEX_DYLIB}"
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/lib/libimhex/include")
set_target_properties(tracing PROPERTIES
IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/../libtracing.a"
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/lib/trace/include")
else()
set_target_properties(libimhex PROPERTIES
IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/../libimhex.so"
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/lib/libimhex/include")
set_target_properties(tracing PROPERTIES
IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/../libtracing.a"
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/lib/trace/include")
endif()

4
dist/Arch/PKGBUILD vendored
View File

@@ -8,8 +8,8 @@ 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 fontconfig freetype2 libglvnd dbus gtk3 curl fmt yara nlohmann-json zlib bzip2 xz zstd)
makedepends=(git)
depends=(glfw mbedtls fontconfig freetype2 libglvnd dbus gtk3 curl fmt yara zlib bzip2 xz zstd)
makedepends=(git nlohmann-json)
provides=(imhex)
conflicts=(imhex)
source=("$url/releases/download/v$pkgver/imhex-$pkgver-ArchLinux-x86_64.pkg.tar.zst")

View File

@@ -21,7 +21,6 @@ RDEPEND="${DEPEND}
media-libs/glfw
sys-apps/file
net-libs/mbedtls
dev-cpp/nlohmann_json
sys-apps/dbus
sys-apps/xdg-desktop-portal
sys-libs/zlib
@@ -30,4 +29,6 @@ RDEPEND="${DEPEND}
app-arch/zstd
app-arch/lz4
"
BDEPEND="${DEPEND}"
BDEPEND="${DEPEND}
dev-cpp/nlohmann_json
"

View File

@@ -9,7 +9,7 @@ On Linux, ImHex is built through regular GCC (or optionally Clang).
cd ImHex
mkdir -p build
cd build
CC=gcc-12 CXX=g++-12 \
CC=gcc-14 CXX=g++-14 \
cmake -G "Ninja" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="/usr" \

View File

@@ -3,7 +3,7 @@
On macOS, ImHex is built through regular GCC and LLVM clang.
1. Clone the repo using `git clone https://github.com/WerWolv/ImHex --recurse-submodules`
2. Install all the dependencies using `brew bundle --no-lock --file dist/Brewfile`
2. Install all the dependencies using `brew bundle --no-lock --file dist/macOS/Brewfile`
3. Build ImHex itself using the following commands:
```sh
cd ImHex
@@ -19,4 +19,4 @@ cmake -G "Ninja" \
-DIMHEX_GENERATE_PACKAGE=ON \
..
ninja install
```
```

View File

@@ -32,11 +32,17 @@ def main(args: list) -> int:
sorted_commits = {}
for commit in master_commits:
category, commit_name = commit.split(":", 1)
if commit == "":
continue
if category not in sorted_commits:
sorted_commits[category] = []
sorted_commits[category].append(commit_name)
try:
category, commit_name = commit.split(":", 1)
if category not in sorted_commits:
sorted_commits[category] = []
sorted_commits[category].append(commit_name)
except:
print(f"Failed to parse commit: {commit}")
for category in sorted_commits:
print(f"## {category}\n")

View File

@@ -5,6 +5,17 @@ ENV MACOSX_DEPLOYMENT_TARGET 13.0
# -- DOWNLOADING STUFF
# Update vcpkg
RUN <<EOF
cp /vcpkg/triplets/community/arm-osx-mytriplet.cmake /tmp/arm-osx-mytriplet.cmake
git -C /vcpkg clean -ffdx
git -C /vcpkg checkout origin/master
git -C /vcpkg reset --hard
git -C /vcpkg pull
/vcpkg/bootstrap-vcpkg.sh
cp /tmp/arm-osx-mytriplet.cmake /vcpkg/triplets/community/arm-osx-mytriplet.cmake
EOF
## Install make
RUN --mount=type=cache,target=/var/lib/apt/lists/ apt update && apt install -y make
@@ -35,7 +46,7 @@ EOF
## Download libmagic
### Clone libmagic
RUN git clone --depth 1 --branch FILE5_45 https://github.com/file/file /mnt/file
RUN git clone --depth 1 --branch FILE5_46 https://github.com/file/file /mnt/file
### Download libmagic dependencies
RUN --mount=type=cache,target=/var/lib/apt/lists/ apt update && apt install -y libtool autoconf

1
dist/rpm/imhex.spec vendored
View File

@@ -128,6 +128,5 @@ cp -a lib/third_party/xdgpp/LICENSE %{buildroot
%{_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/vcpkg.json vendored Normal file
View File

@@ -0,0 +1,16 @@
{
"name": "vcpkg",
"version": "1.0.0",
"builtin-baseline": "7e21420f775f72ae938bdeb5e6068f722088f06a",
"dependencies": [
"libmagic",
"freetype",
"mbedtls",
"zlib",
"bzip2",
"liblzma",
"zstd",
"glfw3",
"curl"
]
}

4
dist/web/Dockerfile vendored
View File

@@ -1,4 +1,4 @@
FROM emscripten/emsdk:3.1.51 AS build
FROM emscripten/emsdk:4.0.8 AS build
# Used to invalidate layer cache but not mount cache
# See https://github.com/moby/moby/issues/41715#issuecomment-733976493
@@ -13,6 +13,7 @@ RUN <<EOF
set -xe
git clone https://github.com/microsoft/vcpkg /vcpkg
git -C /vcpkg pull
/vcpkg/bootstrap-vcpkg.sh
sed -i 's/vcpkg_install_make(${EXTRA_ARGS})/vcpkg_install_make(${EXTRA_ARGS} SUBPATH src)/g' /vcpkg/ports/libmagic/portfile.cmake
EOF
@@ -86,7 +87,6 @@ COPY --from=build [ \
"/build/imhex.wasm", \
"/build/imhex.wasm.size", \
"/build/imhex.js", \
"/build/imhex.worker.js", \
\
# Static files \
"/build/index.html", \

View File

@@ -57,6 +57,11 @@
<loc>https://web.imhex.werwolv.net?lang=it-IT</loc>
<lastmod>2024-01-02T11:44:00+00:00</lastmod>
</url>
<url>
<title>Русский</title>
<loc>https://web.imhex.werwolv.net?lang=ru-RU</loc>
<lastmod>2024-01-02T11:44:00+00:00</lastmod>
</url>
</urlset>

View File

@@ -9,8 +9,9 @@ fetch("imhex.wasm.size").then(async (resp) => {
// inspired from: https://github.com/WordPress/wordpress-playground/pull/46 (but had to be modified)
function monkeyPatch(progressFun) {
const _instantiateStreaming = WebAssembly.instantiateStreaming;
WebAssembly.instantiateStreaming = (response, ...args) => {
WebAssembly.instantiateStreaming = async (responsePromise, ...args) => {
// Do not collect wasm content length here see above
let response = await responsePromise
const file = response.url.substring(
new URL(response.url).origin.length + 1
);
@@ -235,12 +236,11 @@ var Module = {
totalDependencies: 0,
monitorRunDependencies: function(left) {
},
instantiateWasm: function(imports, successCallback) {
instantiateWasm: async function(imports, successCallback) {
imports.env.glfwSetCursor = glfwSetCursorCustom
imports.env.glfwCreateStandardCursor = glfwCreateStandardCursorCustom
instantiateAsync(wasmBinary, wasmBinaryFile, imports, (result) => {
successCallback(result.instance, result.module)
});
let result = await instantiateAsync(null, findWasmBinary(), imports);
successCallback(result.instance, result.module)
},
arguments: []
};

View File

@@ -39,6 +39,10 @@ set(LIBIMHEX_SOURCES
source/helpers/default_paths.cpp
source/helpers/imgui_hooks.cpp
source/helpers/semantic_version.cpp
source/helpers/keys.cpp
source/helpers/freetype.cpp
source/helpers/udp_server.cpp
source/helpers/clipboard.cpp
source/test/tests.cpp
@@ -56,16 +60,19 @@ set(LIBIMHEX_SOURCES
)
if (APPLE)
set(OSX_11_0_SDK_PATH /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk)
set(OSX_SDK_PATH /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.sdk)
if (NOT CMAKE_OSX_SYSROOT)
if (IS_DIRECTORY ${OSX_11_0_SDK_PATH})
set(CMAKE_OSX_SYSROOT ${OSX_11_0_SDK_PATH})
if (IS_DIRECTORY ${OSX_SDK_PATH})
set(CMAKE_OSX_SYSROOT ${OSX_SDK_PATH})
else ()
message(WARNING "CMAKE_OSX_SYSROOT not set and macOS 10.9 SDK not found! Using default one.")
message(WARNING "CMAKE_OSX_SYSROOT not set and macOS SDK not found! Using default one.")
endif ()
endif ()
set(LIBIMHEX_SOURCES ${LIBIMHEX_SOURCES} source/helpers/utils_macos.m)
set(LIBIMHEX_SOURCES ${LIBIMHEX_SOURCES}
source/helpers/utils_macos.m
source/helpers/macos_menu.m
)
endif ()
if (IMHEX_EXTERNAL_PLUGIN_BUILD)
@@ -78,6 +85,15 @@ else()
add_library(libimhex SHARED ${LIBIMHEX_SOURCES})
endif()
if (IMHEX_ENABLE_CXX_MODULES)
target_sources(libimhex
PUBLIC
FILE_SET cxx_modules TYPE CXX_MODULES
FILES
include/hex.cppm
)
endif()
set(LIBIMHEX_LIBRARY_TYPE PUBLIC)
target_compile_definitions(libimhex PRIVATE IMHEX_PROJECT_NAME="${PROJECT_NAME}")
endif()
@@ -122,32 +138,40 @@ setupCompilerFlags(libimhex)
include(GenerateExportHeader)
generate_export_header(libimhex)
target_include_directories(libimhex ${LIBIMHEX_LIBRARY_TYPE} include ${XDGPP_INCLUDE_DIRS} ${MBEDTLS_INCLUDE_DIR} ${MAGIC_INCLUDE_DIRS} ${LLVM_INCLUDE_DIRS} ${FMT_INCLUDE_DIRS} ${LIBBACKTRACE_INCLUDE_DIRS})
target_link_directories(libimhex ${LIBIMHEX_LIBRARY_TYPE} ${MBEDTLS_LIBRARY_DIR} ${MAGIC_LIBRARY_DIRS})
if (NOT EMSCRIPTEN)
# curl is only used in non-emscripten builds
target_link_libraries(libimhex ${LIBIMHEX_LIBRARY_TYPE} CURL::libcurl)
endif()
target_include_directories(libimhex ${LIBIMHEX_LIBRARY_TYPE} include ${XDGPP_INCLUDE_DIRS} ${LLVM_INCLUDE_DIRS} ${FMT_INCLUDE_DIRS})
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)
if (NOT MSVC)
target_link_options(libimhex PRIVATE -Wl,--export-all-symbols)
endif()
target_link_libraries(libimhex PRIVATE Netapi32.lib)
target_compile_definitions(libimhex PRIVATE EXPORT_SYMBOLS=1)
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)
target_link_libraries(libimhex PUBLIC libpl ${IMGUI_LIBRARIES} ${JTHREAD_LIBRARIES})
target_link_libraries(libimhex PRIVATE libpl microtar ${NFD_LIBRARIES} magic)
target_link_libraries(libimhex PUBLIC libwolv libpl_includes libpl-gen ${IMGUI_LIBRARIES} ${JTHREAD_LIBRARIES})
if (NOT WIN32)
target_link_libraries(libimhex PRIVATE dl)
endif()
if (NOT EMSCRIPTEN)
target_link_libraries(libimhex ${LIBIMHEX_LIBRARY_TYPE} CURL::libcurl clip)
endif()
target_include_directories(libimhex ${LIBIMHEX_LIBRARY_TYPE} ${MBEDTLS_INCLUDE_DIR} ${LIBBACKTRACE_INCLUDE_DIRS} ${MAGIC_INCLUDE_DIRS})
target_link_libraries(libimhex ${LIBIMHEX_LIBRARY_TYPE} ${MBEDTLS_LIBRARIES})
target_link_directories(libimhex ${LIBIMHEX_LIBRARY_TYPE} ${MBEDTLS_LIBRARY_DIR} ${MAGIC_LIBRARY_DIRS})
precompileHeaders(libimhex "${CMAKE_CURRENT_SOURCE_DIR}/include")
endif()
target_link_libraries(libimhex ${LIBIMHEX_LIBRARY_TYPE} ${NLOHMANN_JSON_LIBRARIES} imgui_all_includes ${MBEDTLS_LIBRARIES} ${FMT_LIBRARIES} ${LUNASVG_LIBRARIES} ${BOOST_LIBRARIES})
target_link_libraries(libimhex ${LIBIMHEX_LIBRARY_TYPE} ${NLOHMANN_JSON_LIBRARIES} imgui_all_includes ${FMT_LIBRARIES} ${LUNASVG_LIBRARIES} ${BOOST_LIBRARIES} tracing)
set_property(TARGET libimhex PROPERTY INTERPROCEDURAL_OPTIMIZATION FALSE)

View File

@@ -0,0 +1,51 @@
module;
#include <cmath>
#include <map>
#include <string>
#include <string_view>
#include <vector>
#include <exception>
#include <algorithm>
#include <locale>
#include <array>
#include <filesystem>
#include <functional>
#include <memory>
#include <list>
#include <atomic>
#include <ranges>
#include <fstream>
#include <thread>
#include <future>
#include <fmt/format.h>
#include <nlohmann/json.hpp>
#include <wolv/io/file.hpp>
#include <imgui.h>
#include <imgui_internal.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <hex/helpers/auto_reset.hpp>
#include <hex/api/event_manager.hpp>
#include <hex/providers/provider.hpp>
#include <hex/providers/provider_data.hpp>
#include <hex/data_processor/node.hpp>
#include <hex/data_processor/link.hpp>
#include <hex/data_processor/attribute.hpp>
#include <pl/pattern_language.hpp>
export module hex;
#define HEX_MODULE_EXPORT
#include <hex/api/task_manager.hpp>
#include <hex/api/achievement_manager.hpp>
#include <hex/api/imhex_api.hpp>
#include <hex/api/layout_manager.hpp>
#include <hex/api/localization_manager.hpp>
#include <hex/api/plugin_manager.hpp>
#include <hex/api/shortcut_manager.hpp>
#include <hex/api/theme_manager.hpp>
#include <hex/api/tutorial_manager.hpp>
#include <hex/api/workspace_manager.hpp>

View File

@@ -1,3 +1,9 @@
#pragma once
#include <hex/helpers/types.hpp>
#if defined(HEX_MODULE_EXPORT)
#define EXPORT_MODULE export
#else
#define EXPORT_MODULE
#endif

View File

@@ -14,8 +14,9 @@
#include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <hex/api/localization_manager.hpp>
#include <hex/helpers/auto_reset.hpp>
namespace hex {
EXPORT_MODULE namespace hex {
class AchievementManager;
@@ -361,7 +362,7 @@ namespace hex {
* @brief Returns all registered achievements
* @return All achievements
*/
static const std::unordered_map<std::string, std::unordered_map<std::string, std::unique_ptr<Achievement>>>& getAchievements();
static const std::unordered_map<UnlocalizedString, std::unordered_map<UnlocalizedString, std::unique_ptr<Achievement>>>& getAchievements();
/**
* @brief Returns all achievement start nodes
@@ -369,14 +370,14 @@ namespace hex {
* @param rebuild Whether to rebuild the list of start nodes
* @return All achievement start nodes
*/
static const std::unordered_map<std::string, std::vector<AchievementNode*>>& getAchievementStartNodes(bool rebuild = true);
static const std::unordered_map<UnlocalizedString, std::vector<AchievementNode*>>& getAchievementStartNodes(bool rebuild = true);
/**
* @brief Returns all achievement nodes
* @param rebuild Whether to rebuild the list of nodes
* @return All achievement nodes
*/
static const std::unordered_map<std::string, std::list<AchievementNode>>& getAchievementNodes(bool rebuild = true);
static const std::unordered_map<UnlocalizedString, std::list<AchievementNode>>& getAchievementNodes(bool rebuild = true);
/**
* @brief Loads the progress of all achievements from the achievements save file
@@ -405,4 +406,4 @@ namespace hex {
static Achievement& addAchievementImpl(std::unique_ptr<Achievement> &&newAchievement);
};
}
}

View File

@@ -16,27 +16,31 @@
#include <nlohmann/json.hpp>
#include <wolv/io/fs.hpp>
using ImGuiDataType = int;
using ImGuiInputTextFlags = int;
struct ImColor;
enum ImGuiCustomCol : int;
typedef int ImGuiColorEditFlags;
#if !defined(HEX_MODULE_EXPORT)
using ImGuiDataType = int;
using ImGuiInputTextFlags = int;
struct ImColor;
enum ImGuiCustomCol : int;
typedef int ImGuiColorEditFlags;
#endif
namespace hex {
EXPORT_MODULE namespace hex {
class View;
class Task;
#if !defined(HEX_MODULE_EXPORT)
class View;
class Task;
namespace dp {
class Node;
}
namespace prv {
class Provider;
}
namespace dp {
class Node;
}
namespace prv {
class Provider;
}
namespace LocalizationManager {
class LanguageDefinition;
}
namespace LocalizationManager {
class LanguageDefinition;
}
#endif
/*
The Content Registry is the heart of all features in ImHex that are in some way extendable by Plugins.
@@ -328,7 +332,7 @@ namespace hex {
result = defaultValue;
return result.get<T>();
} catch (const nlohmann::json::exception &e) {
} catch (const nlohmann::json::exception &) {
return defaultValue;
}
}
@@ -576,7 +580,7 @@ namespace hex {
namespace impl {
void add(std::unique_ptr<View> &&view);
const std::map<std::string, std::unique_ptr<View>>& getEntries();
const std::map<UnlocalizedString, std::unique_ptr<View>>& getEntries();
}
@@ -597,6 +601,12 @@ namespace hex {
* @return The view if it exists, nullptr otherwise
*/
View* getViewByName(const UnlocalizedString &unlocalizedName);
/**
* @brief Gets the currently focused view
* @return The view that is focused right now. nullptr if none is focused
*/
View* getFocusedView();
}
/* Tools Registry. Allows adding new entries to the tools window */
@@ -721,7 +731,7 @@ namespace hex {
add(impl::Entry {
unlocalizedCategory,
unlocalizedName,
[=, ...args = std::forward<Args>(args)] mutable {
[=, ...args = std::forward<Args>(args)]() mutable {
auto node = std::make_unique<T>(std::forward<Args>(args)...);
node->setUnlocalizedName(unlocalizedName);
return node;
@@ -1002,7 +1012,7 @@ namespace hex {
void add(bool addToList = true) {
auto typeName = T().getTypeName();
impl::add(typeName, [] -> std::unique_ptr<prv::Provider> {
impl::add(typeName, []() -> std::unique_ptr<prv::Provider> {
return std::make_unique<T>();
});
@@ -1110,9 +1120,9 @@ namespace hex {
[[nodiscard]] const UnlocalizedString& getUnlocalizedName() const { return m_unlocalizedName; }
protected:
const static int TextInputFlags;
[[nodiscard]] static int DefaultTextInputFlags();
protected:
bool drawDefaultScalarEditingTextBox(u64 address, const char *format, ImGuiDataType dataType, u8 *data, ImGuiInputTextFlags flags) const;
bool drawDefaultTextEditingTextBox(u64 address, std::string &data, ImGuiInputTextFlags flags) const;

View File

@@ -14,24 +14,44 @@
#include <wolv/types/type_name.hpp>
#define EVENT_DEF_IMPL(event_name, event_name_string, should_log, ...) \
struct event_name final : public hex::impl::Event<__VA_ARGS__> { \
constexpr static auto Id = [] { return hex::impl::EventId(event_name_string); }(); \
constexpr static auto ShouldLog = (should_log); \
explicit event_name(Callback func) noexcept : Event(std::move(func)) { } \
\
static EventManager::EventList::iterator subscribe(Event::Callback function) { return EventManager::subscribe<event_name>(std::move(function)); } \
static void subscribe(void *token, Event::Callback function) { EventManager::subscribe<event_name>(token, std::move(function)); } \
static void unsubscribe(const EventManager::EventList::iterator &token) noexcept { EventManager::unsubscribe(token); } \
static void unsubscribe(void *token) noexcept { EventManager::unsubscribe<event_name>(token); } \
static void post(auto &&...args) { EventManager::post<event_name>(std::forward<decltype(args)>(args)...); } \
#define EVENT_DEF_IMPL(event_name, event_name_string, should_log, ...) \
struct event_name final : public hex::impl::Event<__VA_ARGS__> { \
constexpr static auto Id = [] { return hex::impl::EventId(event_name_string); }(); \
constexpr static auto ShouldLog = (should_log); \
explicit event_name(Callback func) noexcept : Event(std::move(func)) { } \
\
static EventManager::EventList::iterator subscribe(Event::Callback function) { \
return EventManager::subscribe<event_name>(std::move(function)); \
} \
template<typename = void> \
static EventManager::EventList::iterator subscribe(Event::BaseCallback function) \
requires (!std::same_as<Event::Callback, Event::BaseCallback>) { \
return EventManager::subscribe<event_name>([function = std::move(function)](auto && ...) { function(); }); \
} \
static void subscribe(void *token, Event::Callback function) { \
EventManager::subscribe<event_name>(token, std::move(function)); \
} \
template<typename = void> \
static void subscribe(void *token, Event::BaseCallback function) \
requires (!std::same_as<Event::Callback, Event::BaseCallback>) { \
return EventManager::subscribe<event_name>(token, [function = std::move(function)](auto && ...) { function(); }); \
} \
static void unsubscribe(const EventManager::EventList::iterator &token) noexcept { \
EventManager::unsubscribe(token); \
} \
static void unsubscribe(void *token) noexcept { \
EventManager::unsubscribe<event_name>(token); \
} \
static void post(auto &&...args) { \
EventManager::post<event_name>(std::forward<decltype(args)>(args)...); \
} \
}
#define EVENT_DEF(event_name, ...) EVENT_DEF_IMPL(event_name, #event_name, true, __VA_ARGS__)
#define EVENT_DEF_NO_LOG(event_name, ...) EVENT_DEF_IMPL(event_name, #event_name, false, __VA_ARGS__)
namespace hex {
EXPORT_MODULE namespace hex {
namespace impl {
@@ -65,6 +85,7 @@ namespace hex {
template<typename... Params>
struct Event : EventBase {
using Callback = std::function<void(Params...)>;
using BaseCallback = std::function<void()>;
explicit Event(Callback func) noexcept : m_func(std::move(func)) { }

View File

@@ -69,4 +69,10 @@ namespace hex {
*/
EVENT_DEF(EventProjectOpened);
/**
* @brief Called when a native message was received from another ImHex instance
* @param rawData Raw bytes received from other instance
*/
EVENT_DEF(EventNativeMessageReceived, std::vector<u8>);
}

View File

@@ -17,7 +17,7 @@ namespace hex {
*
* @param region the region that should be selected
*/
EVENT_DEF(RequestHexEditorSelectionChange, Region);
EVENT_DEF(RequestHexEditorSelectionChange, ImHexApi::HexEditor::ProviderRegion);
/**
* @brief Requests the Pattern editor to move selection

View File

@@ -3,6 +3,8 @@
#include <hex.hpp>
#include <hex/api/localization_manager.hpp>
#include <hex/helpers/semantic_version.hpp>
#include <hex/helpers/utils.hpp>
#include <hex/helpers/fs.hpp>
#include <functional>
#include <optional>
@@ -11,24 +13,28 @@
#include <vector>
#include <map>
#include <set>
#include <memory>
#include "imgui_internal.h"
#include <wolv/io/fs.hpp>
using ImGuiID = unsigned int;
struct ImVec2;
struct ImFontAtlas;
struct ImFont;
#if !defined(HEX_MODULE_EXPORT)
using ImGuiID = unsigned int;
struct ImVec2;
struct ImFontAtlas;
struct ImFont;
#endif
struct GLFWwindow;
namespace hex {
EXPORT_MODULE namespace hex {
namespace impl {
class AutoResetBase;
}
#if !defined(HEX_MODULE_EXPORT)
namespace impl {
class AutoResetBase;
}
namespace prv {
class Provider;
}
namespace prv {
class Provider;
}
#endif
namespace ImHexApi {
@@ -444,6 +450,8 @@ namespace hex {
bool isWindowResizable();
void addAutoResetObject(hex::impl::AutoResetBase *object);
void removeAutoResetObject(hex::impl::AutoResetBase *object);
void cleanup();
}
@@ -746,6 +754,7 @@ namespace hex {
std::vector<GlyphRange> glyphRanges;
Offset offset;
u32 flags;
std::optional<bool> scalable;
std::optional<u32> defaultSize;
};
@@ -762,14 +771,18 @@ namespace hex {
GlyphRange range(const char *glyphBegin, const char *glyphEnd);
GlyphRange range(u32 codepointBegin, u32 codepointEnd);
void loadFont(const std::fs::path &path, const std::vector<GlyphRange> &glyphRanges = {}, Offset offset = {}, u32 flags = 0, std::optional<u32> defaultSize = std::nullopt);
void loadFont(const std::string &name, const std::span<const u8> &data, const std::vector<GlyphRange> &glyphRanges = {}, Offset offset = {}, u32 flags = 0, std::optional<u32> defaultSize = std::nullopt);
void loadFont(const std::fs::path &path, const std::vector<GlyphRange> &glyphRanges = {}, Offset offset = {}, u32 flags = 0, std::optional<bool> scalable = std::nullopt, std::optional<u32> defaultSize = std::nullopt);
void loadFont(const std::string &name, const std::span<const u8> &data, const std::vector<GlyphRange> &glyphRanges = {}, Offset offset = {}, u32 flags = 0, std::optional<bool> scalable = std::nullopt, std::optional<u32> defaultSize = std::nullopt);
constexpr static float DefaultFontSize = 13.0;
constexpr float DefaultFontSize = 13.0;
void registerFont(const UnlocalizedString &fontName);
ImFont* getFont(const UnlocalizedString &fontName);
float getDpi();
float pixelsToPoints(float pixels);
float pointsToPixels(float points);
}
}

View File

@@ -4,9 +4,11 @@
#include <string>
struct ImGuiTextBuffer;
#if !defined(HEX_MODULE_EXPORT)
struct ImGuiTextBuffer;
#endif
namespace hex {
EXPORT_MODULE namespace hex {
class LayoutManager {
public:

View File

@@ -10,7 +10,7 @@
#include <fmt/core.h>
#include <wolv/types/static_string.hpp>
namespace hex {
EXPORT_MODULE namespace hex {
namespace LocalizationManager {
@@ -101,10 +101,9 @@ namespace hex {
public:
UnlocalizedString() = default;
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!");
}
UnlocalizedString(const std::string &string) : m_unlocalizedString(string) { }
UnlocalizedString(const char *string) : m_unlocalizedString(string) { }
UnlocalizedString(const Lang& arg) = delete;
[[nodiscard]] operator std::string() const {
return m_unlocalizedString;
@@ -149,3 +148,10 @@ namespace hex {
}
}
template<>
struct std::hash<hex::UnlocalizedString> {
std::size_t operator()(const hex::UnlocalizedString &string) const noexcept {
return std::hash<std::string>{}(string.get());
}
};

View File

@@ -10,16 +10,24 @@
#include <hex/helpers/logger.hpp>
#include <hex/helpers/auto_reset.hpp>
struct ImGuiContext;
#if !defined(HEX_MODULE_EXPORT)
struct ImGuiContext;
#endif
namespace hex {
EXPORT_MODULE namespace hex {
struct SubCommand {
enum class Type : u8 {
Option,
SubCommand
};
std::string commandLong;
std::string commandShort;
std::string commandDescription;
std::function<void(const std::vector<std::string>&)> callback;
Type type = Type::Option;
};
struct Feature {

View File

@@ -9,7 +9,7 @@
* that want to store any data to a Project File.
*
*/
namespace hex {
EXPORT_MODULE namespace hex {
namespace prv {
class Provider;

View File

@@ -9,7 +9,9 @@
#include <set>
#include <string>
struct ImGuiWindow;
#if !defined(HEX_MODULE_EXPORT)
struct ImGuiWindow;
#endif
struct KeyEquivalent {
bool valid;
@@ -17,7 +19,7 @@ struct KeyEquivalent {
int key;
};
namespace hex {
EXPORT_MODULE namespace hex {
class View;
@@ -135,6 +137,14 @@ namespace hex {
*/
static void processGlobals(bool ctrl, bool alt, bool shift, bool super, u32 keyCode);
/**
* @brief Runs the callback of a shortcut as if it was pressed on the keyboard
* @param shortcut Shortcut to run
* @param view View the shortcut belongs to or nullptr to run a global shortcut
* @return True if a callback was executed, false if not
*/
static bool runShortcut(const Shortcut &shortcut, const View *view = nullptr);
/**
* @brief Clear all shortcuts
*/

View File

@@ -11,7 +11,7 @@
#include <condition_variable>
#include <source_location>
namespace hex {
EXPORT_MODULE namespace hex {
class TaskHolder;
class TaskManager;
@@ -22,7 +22,7 @@ namespace hex {
class Task {
public:
Task() = default;
Task(const UnlocalizedString &unlocalizedName, u64 maxValue, bool background, std::function<void(Task &)> function);
Task(const UnlocalizedString &unlocalizedName, u64 maxValue, bool background, bool blocking, std::function<void(Task &)> function);
Task(const Task&) = delete;
Task(Task &&other) noexcept;
@@ -57,6 +57,7 @@ namespace hex {
void setInterruptCallback(std::function<void()> callback);
[[nodiscard]] bool isBackgroundTask() const;
[[nodiscard]] bool isBlocking() const;
[[nodiscard]] bool isFinished() const;
[[nodiscard]] bool hadException() const;
[[nodiscard]] bool wasInterrupted() const;
@@ -84,6 +85,7 @@ namespace hex {
std::atomic<bool> m_shouldInterrupt = false;
std::atomic<bool> m_background = true;
std::atomic<bool> m_blocking = false;
std::atomic<bool> m_interrupted = false;
std::atomic<bool> m_finished = false;
@@ -162,6 +164,24 @@ namespace hex {
*/
static TaskHolder createBackgroundTask(const UnlocalizedString &unlocalizedName, std::function<void()> function);
/**
* @brief Creates a new asynchronous task that shows a blocking modal window
* @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 createBlockingTask(const UnlocalizedString &unlocalizedName, u64 maxValue, std::function<void(Task &)> function);
/**
* @brief Creates a new asynchronous task that shows a blocking modal window
* @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 createBlockingTask(const UnlocalizedString &unlocalizedName, u64 maxValue, std::function<void()> function);
/**
* @brief Creates a new synchronous task that will execute the given function at the start of the next frame
* @param function Function to be executed
@@ -202,12 +222,13 @@ namespace hex {
static size_t getRunningTaskCount();
static size_t getRunningBackgroundTaskCount();
static size_t getRunningBlockingTaskCount();
static const std::list<std::shared_ptr<Task>>& getRunningTasks();
static void runDeferredCalls();
private:
static TaskHolder createTask(const UnlocalizedString &unlocalizedName, u64 maxValue, bool background, std::function<void(Task &)> function);
static TaskHolder createTask(const UnlocalizedString &unlocalizedName, u64 maxValue, bool background, bool blocking, std::function<void(Task &)> function);
};
}

View File

@@ -9,7 +9,7 @@
#include <nlohmann/json_fwd.hpp>
#include <imgui.h>
namespace hex {
EXPORT_MODULE namespace hex {
/**
* @brief The Theme Manager takes care of loading and applying themes

View File

@@ -10,7 +10,7 @@
#include <hex/ui/imgui_imhex_extensions.h>
namespace hex {
EXPORT_MODULE namespace hex {
class TutorialManager {
public:

View File

@@ -6,7 +6,7 @@
#include <map>
#include <string>
namespace hex {
EXPORT_MODULE namespace hex {
class WorkspaceManager {
public:
@@ -24,8 +24,8 @@ namespace hex {
static void removeWorkspace(const std::string &name);
static const auto& getWorkspaces() { return *s_workspaces; }
static const auto& getCurrentWorkspace() { return s_currentWorkspace; }
static const std::map<std::string, Workspace>& getWorkspaces();
static const std::map<std::string, Workspace>::iterator& getCurrentWorkspace();
static void reset();
static void reload();
@@ -34,9 +34,6 @@ namespace hex {
private:
WorkspaceManager() = default;
static AutoReset<std::map<std::string, Workspace>> s_workspaces;
static decltype(s_workspaces)::Type::iterator s_currentWorkspace, s_previousWorkspace, s_workspaceToRemove;
};
}

View File

@@ -23,6 +23,20 @@ namespace hex {
ImHexApi::System::impl::addAutoResetObject(this);
}
AutoReset(const T &value) : AutoReset() {
m_value = value;
m_valid = true;
}
AutoReset(T &&value) noexcept : AutoReset() {
m_value = std::move(value);
m_valid = true;
}
~AutoReset() {
ImHexApi::System::impl::removeAutoResetObject(this);
}
T* operator->() {
return &m_value;
}

View File

@@ -0,0 +1,16 @@
#pragma once
#include <hex.hpp>
#include <span>
#include <string>
#include <vector>
namespace hex::clipboard {
void init();
void setBinaryData(std::span<const u8> data);
[[nodiscard]] std::vector<u8> getBinaryData();
void setTextData(const std::string &string);
[[nodiscard]] std::string getTextData();
}

View File

@@ -2,6 +2,7 @@
#include <hex/helpers/fs.hpp>
#include <array>
#include <vector>
namespace hex::paths {

View File

@@ -3,6 +3,7 @@
#include <string_view>
#include <fmt/core.h>
#include <fmt/ranges.h>
#include <fmt/ostream.h>
namespace hex {

View File

@@ -0,0 +1,60 @@
#pragma once
#include "imgui.h"
#include <vector>
namespace hex::ft {
class Bitmap {
ImU32 m_width;
ImU32 m_height;
ImU32 m_pitch;
std::vector <ImU8> m_data;
public:
Bitmap(ImU32 width, ImU32 height, ImU32 pitch, ImU8 *data) : m_width(width), m_height(height), m_pitch(pitch), m_data(std::vector<ImU8>(data, data + pitch * height)) {}
Bitmap(ImU32 width, ImU32 height, ImU32 pitch) : m_width(width), m_height(height), m_pitch(pitch) { m_data.resize(pitch * height); }
void clear() { m_data.clear(); }
ImU32 getWidth() const { return m_width; }
ImU32 getHeight() const { return m_height; }
ImU32 getPitch() const { return m_pitch; }
const std::vector <ImU8> &getData() const { return m_data; }
ImU8 *getData() { return m_data.data(); }
void lcdFilter();
};
class RGBA {
public:
static ImU32 addAlpha(ImU8 r, ImU8 g, ImU8 b) {
color.rgbaVec[0] = r;
color.rgbaVec[1] = g;
color.rgbaVec[2] = b;
color.rgbaVec[3] = (r + g + b) / 3;//luminance
return color.rgba;
}
RGBA(ImU8 r, ImU8 g, ImU8 b, ImU8 a) {
color.rgbaVec[0] = r;
color.rgbaVec[1] = b;
color.rgbaVec[2] = g;
color.rgbaVec[3] = a;
}
explicit RGBA(ImU32 rgba) {
color.rgba = rgba;
}
union RGBAU {
ImU8 rgbaVec[4];
ImU32 rgba;
};
inline static RGBAU color;
};
}

View File

@@ -1,5 +1,6 @@
#pragma once
#include <hex.hpp>
#include <string>
#include <vector>
#include <filesystem>
@@ -7,7 +8,7 @@
#include <wolv/io/fs.hpp>
namespace hex::fs {
EXPORT_MODULE namespace hex::fs {
enum class DialogMode {
Open,

View File

@@ -12,10 +12,6 @@
#if defined(OS_WEB)
#include <emscripten/fetch.h>
using curl_off_t = long;
#else
#include <curl/curl.h>
#endif
typedef void CURL;
@@ -121,18 +117,18 @@ namespace hex {
static std::string urlDecode(const std::string &input);
protected:
void setDefaultConfig();
void setProgress(float progress) { m_progress = progress; }
bool isCanceled() const { return m_canceled; }
static size_t writeToVector(void *contents, size_t size, size_t nmemb, void *userdata);
static size_t writeToFile(void *contents, size_t size, size_t nmemb, void *userdata);
template<typename T>
Result<T> executeImpl(std::vector<u8> &data);
static size_t writeToVector(void *contents, size_t size, size_t nmemb, void *userdata);
static size_t writeToFile(void *contents, size_t size, size_t nmemb, void *userdata);
static int progressCallback(void *contents, curl_off_t dlTotal, curl_off_t dlNow, curl_off_t ulTotal, curl_off_t ulNow);
private:
static void checkProxyErrors();
void setDefaultConfig();
private:
#if defined(OS_WEB)

View File

@@ -4,8 +4,7 @@
#include <string>
#include <future>
#include <curl/curl.h>
#include <mutex>
#include <hex/helpers/logger.hpp>
#include <hex/helpers/fmt.hpp>
@@ -14,14 +13,26 @@
namespace hex {
namespace impl {
void setWriteFunctions(CURL *curl, wolv::io::File &file);
void setWriteFunctions(CURL *curl, std::vector<u8> &data);
void setupFileUpload(CURL *curl, wolv::io::File &file, const std::string &fileName, const std::string &mimeName);
void setupFileUpload(CURL *curl, const std::vector<u8> &data, const std::fs::path &fileName, const std::string &mimeName);
int executeCurl(CURL *curl, const std::string &url, const std::string &method, const std::string &body, std::map<std::string, std::string> &headers);
long getStatusCode(CURL *curl);
std::string getStatusText(int result);
}
template<typename T>
std::future<HttpRequest::Result<T>> HttpRequest::downloadFile(const std::fs::path &path) {
return std::async(std::launch::async, [this, path] {
std::vector<u8> response;
wolv::io::File file(path, wolv::io::File::Mode::Create);
curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, writeToFile);
curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &file);
impl::setWriteFunctions(m_curl, file);
return this->executeImpl<T>(response);
});
@@ -31,40 +42,12 @@
std::future<HttpRequest::Result<T>> HttpRequest::uploadFile(const std::fs::path &path, const std::string &mimeName) {
return std::async(std::launch::async, [this, path, mimeName]{
auto fileName = wolv::util::toUTF8String(path.filename());
curl_mime *mime = curl_mime_init(m_curl);
curl_mimepart *part = curl_mime_addpart(mime);
wolv::io::File file(path, wolv::io::File::Mode::Read);
curl_mime_data_cb(part, file.getSize(),
[](char *buffer, size_t size, size_t nitems, void *arg) -> size_t {
auto handle = static_cast<FILE*>(arg);
return fread(buffer, size, nitems, handle);
},
[](void *arg, curl_off_t offset, int origin) -> int {
auto handle = static_cast<FILE*>(arg);
if (fseek(handle, offset, origin) != 0)
return CURL_SEEKFUNC_CANTSEEK;
else
return CURL_SEEKFUNC_OK;
},
[](void *arg) {
auto handle = static_cast<FILE*>(arg);
fclose(handle);
},
file.getHandle());
curl_mime_filename(part, fileName.c_str());
curl_mime_name(part, mimeName.c_str());
curl_easy_setopt(m_curl, CURLOPT_MIMEPOST, mime);
impl::setupFileUpload(m_curl, file, fileName, mimeName);
std::vector<u8> responseData;
curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, writeToVector);
curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &responseData);
impl::setWriteFunctions(m_curl, responseData);
return this->executeImpl<T>(responseData);
});
@@ -73,19 +56,10 @@
template<typename T>
std::future<HttpRequest::Result<T>> HttpRequest::uploadFile(std::vector<u8> data, const std::string &mimeName, const std::fs::path &fileName) {
return std::async(std::launch::async, [this, data = std::move(data), mimeName, fileName]{
curl_mime *mime = curl_mime_init(m_curl);
curl_mimepart *part = curl_mime_addpart(mime);
curl_mime_data(part, reinterpret_cast<const char *>(data.data()), data.size());
auto fileNameStr = wolv::util::toUTF8String(fileName.filename());
curl_mime_filename(part, fileNameStr.c_str());
curl_mime_name(part, mimeName.c_str());
curl_easy_setopt(m_curl, CURLOPT_MIMEPOST, mime);
impl::setupFileUpload(m_curl, data, fileName, mimeName);
std::vector<u8> responseData;
curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, writeToVector);
curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &responseData);
impl::setWriteFunctions(m_curl, responseData);
return this->executeImpl<T>(responseData);
});
@@ -96,8 +70,7 @@
return std::async(std::launch::async, [this] {
std::vector<u8> responseData;
curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, writeToVector);
curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &responseData);
impl::setWriteFunctions(m_curl, responseData);
return this->executeImpl<T>(responseData);
});
@@ -105,43 +78,16 @@
template<typename T>
HttpRequest::Result<T> HttpRequest::executeImpl(std::vector<u8> &data) {
curl_easy_setopt(m_curl, CURLOPT_URL, m_url.c_str());
curl_easy_setopt(m_curl, CURLOPT_CUSTOMREQUEST, m_method.c_str());
setDefaultConfig();
if (!m_body.empty()) {
curl_easy_setopt(m_curl, CURLOPT_POSTFIELDS, m_body.c_str());
std::scoped_lock lock(m_transmissionMutex);
if (auto result = impl::executeCurl(m_curl, m_url, m_method, m_body, m_headers); result != 0) {
log::error("Http request '{0} {1}' failed with error {2}: '{3}'", m_method, m_url, u32(result), impl::getStatusText(result));
checkProxyErrors();
}
curl_slist *headers = nullptr;
headers = curl_slist_append(headers, "Cache-Control: no-cache");
ON_SCOPE_EXIT { curl_slist_free_all(headers); };
for (auto &[key, value] : m_headers) {
std::string header = hex::format("{}: {}", key, value);
headers = curl_slist_append(headers, header.c_str());
}
curl_easy_setopt(m_curl, CURLOPT_HTTPHEADER, headers);
{
std::scoped_lock lock(m_transmissionMutex);
auto result = curl_easy_perform(m_curl);
if (result != CURLE_OK){
char *url = nullptr;
curl_easy_getinfo(m_curl, CURLINFO_EFFECTIVE_URL, &url);
log::error("Http request '{0} {1}' failed with error {2}: '{3}'", m_method, url, u32(result), curl_easy_strerror(result));
checkProxyErrors();
return { };
}
}
long statusCode = 0;
curl_easy_getinfo(m_curl, CURLINFO_RESPONSE_CODE, &statusCode);
return Result<T>(statusCode, { data.begin(), data.end() });
return Result<T>(impl::getStatusCode(m_curl), { data.begin(), data.end() });
}
}

View File

@@ -1,122 +1,124 @@
#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,
Invalid,
Space,
Apostrophe,
Comma,
Minus,
Period,
Slash,
Num0,
Num1,
Num2,
Num3,
Num4,
Num5,
Num6,
Num7,
Num8,
Num9,
Semicolon,
Equals,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
LeftBracket,
Backslash,
RightBracket,
GraveAccent,
World1,
World2,
Escape,
Enter,
Tab,
Backspace,
Insert,
Delete,
Right,
Left,
Down,
Up,
PageUp,
PageDown,
Home,
End,
CapsLock,
ScrollLock,
NumLock,
PrintScreen,
Pause,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
F13,
F14,
F15,
F16,
F17,
F18,
F19,
F20,
F21,
F22,
F23,
F24,
F25,
KeyPad0,
KeyPad1,
KeyPad2,
KeyPad3,
KeyPad4,
KeyPad5,
KeyPad6,
KeyPad7,
KeyPad8,
KeyPad9,
KeyPadDecimal,
KeyPadDivide,
KeyPadMultiply,
KeyPadSubtract,
KeyPadAdd,
KeyPadEnter,
KeyPadEqual,
Menu
};
enum Keys scanCodeToKey(int scanCode);
int keyToScanCode(enum Keys key);

View File

@@ -8,7 +8,7 @@
#include <wolv/io/file.hpp>
#include <wolv/utils/guards.hpp>
namespace hex::log {
EXPORT_MODULE namespace hex::log {
namespace impl {

View File

@@ -9,9 +9,9 @@
#include <map>
#include <span>
#include <string>
#include <numbers>
#include <opengl_support.h>
#include <GLFW/glfw3.h>
#include "imgui.h"
namespace hex::gl {
@@ -188,43 +188,43 @@ namespace hex::gl {
T &getElement(int row,int col) {
return this->mat[row*Columns+col];
return this->mat[row * Columns+col];
}
Vector<T,Rows> getColumn(int col) {
Vector<T,Rows> result;
for (size_t i = 0; i < Rows; i++)
result[i] = this->mat[i*Columns+col];
result[i] = this->mat[i * Columns + col];
return result;
}
Vector<T,Columns> getRow(int row) {
Vector<T,Columns> result;
for (size_t i = 0; i < Columns; i++)
result[i] = this->mat[row*Columns+i];
result[i] = this->mat[row * Columns+i];
return result;
}
void updateRow(int row, Vector<T,Columns> values) {
for (size_t i = 0; i < Columns; i++)
this->mat[row*Columns+i] = values[i];
this->mat[row * Columns + i] = values[i];
}
void updateColumn(int col, Vector<T,Rows> values) {
for (size_t i = 0; i < Rows; i++)
this->mat[i*Columns+col] = values[i];
this->mat[i * Columns + col] = values[i];
}
void updateElement( int row,int col, T value) {
this->mat[row*Columns + col] = value;
void updateElement(int row, int col, T value) {
this->mat[row * Columns + col] = value;
}
T &operator()( const int &row,const int &col) {
return this->mat[row*Columns + col];
T &operator()(const unsigned &row, const unsigned &col) {
return this->mat[row * Columns + col];
}
const T &operator()(const unsigned& row,const unsigned& col ) const {
return this->mat[row*Columns + col];
const T &operator()(const unsigned &row, const unsigned &col) const {
return this->mat[row * Columns + col];
}
Matrix& operator=(const Matrix& A) {
@@ -242,7 +242,7 @@ namespace hex::gl {
for (size_t i = 0; i < Rows; i++)
for (size_t j = 0; j < Columns; j++)
result(i, j) = this->mat[i*Columns+j] + A(i, j);
result(i, j) = this->mat[i * Columns + j] + A(i, j);
return result;
}
@@ -251,7 +251,7 @@ namespace hex::gl {
for (size_t i = 0; i < Rows; i++)
for (size_t j = 0; j < Columns; j++)
result(i, j) = this->mat[i*Columns+j] - A(i, j);
result(i, j) = this->mat[i * Columns + j] - A(i, j);
return result;
}
@@ -268,7 +268,7 @@ namespace hex::gl {
Matrix t(0);
for (size_t i = 0; i < Columns; i++)
for (size_t j = 0; j < Rows; j++)
t.updateElement(i, j, this->mat[j*Rows+i]);
t.updateElement(i, j, this->mat[j * Rows + i]);
return t;
}
@@ -400,8 +400,8 @@ namespace hex::gl {
T Sx, Cx, Sy, Cy, Sz, Cz;
Vector<T,3> angles = ypr;
if(!radians)
angles *= M_PI/180;
if (!radians)
angles *= std::numbers::pi_v<T> / 180;
Sx = -sin(angles[0]); Cx = cos(angles[0]);
Sy = -sin(angles[1]); Cy = cos(angles[1]);
@@ -524,7 +524,7 @@ namespace hex::gl {
Vector<T,3> rotationVector3 = {{rotationVector[0], rotationVector[1], rotationVector[2]}};
T theta = rotationVector3.magnitude();
if (!radians)
theta *= M_PI / 180;
theta *= std::numbers::pi / 180;
Vector<T,3> axis = rotationVector3;
if (theta != 0)
axis = axis.normalize();
@@ -814,11 +814,11 @@ namespace hex::gl {
template<size_t N>
void setUniform(std::string_view name, const Vector<float, N> &value) {
if (N == 2)
if constexpr (N == 2)
glUniform2f(getUniformLocation(name), value[0], value[1]);
else if (N == 3)
else if constexpr (N == 3)
glUniform3f(getUniformLocation(name), value[0], value[1], value[2]);
else if (N == 4)
else if constexpr (N == 4)
glUniform4f(getUniformLocation(name), value[0], value[1], value[2],value[3]);
}

View File

@@ -6,7 +6,7 @@
#include <string>
#include <vector>
namespace hex {
EXPORT_MODULE namespace hex {
class SemanticVersion {
public:

View File

@@ -6,17 +6,10 @@
#include <concepts>
#include <type_traits>
using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;
using u128 = __uint128_t;
#include <wolv/types.hpp>
using i8 = std::int8_t;
using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using i128 = __int128_t;
using namespace wolv::unsigned_integers;
using namespace wolv::signed_integers;
using color_t = u32;

View File

@@ -0,0 +1,59 @@
#pragma once
#include <hex.hpp>
#include <functional>
#include <thread>
#include <atomic>
#include <span>
namespace hex {
class UDPServer {
public:
using Callback = std::function<void(std::span<const u8> data)>;
UDPServer() = default;
UDPServer(u16 port, Callback callback);
~UDPServer();
UDPServer(const UDPServer&) = delete;
UDPServer& operator=(const UDPServer&) = delete;
UDPServer(UDPServer &&other) noexcept {
m_port = other.m_port;
m_callback = std::move(other.m_callback);
m_thread = std::move(other.m_thread);
m_running = other.m_running.load();
other.m_running = false;
m_socketFd = other.m_socketFd;
other.m_socketFd = -1;
}
UDPServer& operator=(UDPServer &&other) noexcept {
if (this != &other) {
m_port = other.m_port;
m_callback = std::move(other.m_callback);
m_thread = std::move(other.m_thread);
m_running = other.m_running.load();
other.m_running = false;
m_socketFd = other.m_socketFd;
other.m_socketFd = -1;
}
return *this;
}
void start();
void stop();
[[nodiscard]] u16 getPort() const { return m_port; }
private:
void run();
u16 m_port;
Callback m_callback;
std::thread m_thread;
std::atomic<bool> m_running;
int m_socketFd;
};
}

View File

@@ -30,14 +30,16 @@
namespace hex {
namespace prv {
class Provider;
}
#if !defined(HEX_MODULE_EXPORT)
namespace prv {
class Provider;
}
#endif
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 signalLength = std::max<double>(1.0, double(data.size()) / channels);
size_t stride = std::max(1.0, double(signalLength) / count);
@@ -109,13 +111,13 @@ namespace hex {
[[nodiscard]] std::wstring utf8ToUtf16(const std::string& utf8);
[[nodiscard]] std::string utf16ToUtf8(const std::wstring& utf16);
[[nodiscard]] constexpr u64 extract(u8 from, u8 to, const std::unsigned_integral auto &value) {
[[nodiscard]] constexpr u64 extract(u8 from, u8 to, const auto &value) {
if (from < to) std::swap(from, to);
using ValueType = std::remove_cvref_t<decltype(value)>;
ValueType mask = (std::numeric_limits<ValueType>::max() >> (((sizeof(value) * 8) - 1) - (from - to))) << to;
return (value & mask) >> to;
return u64((value & mask) >> to);
}
[[nodiscard]] inline u64 extract(u32 from, u32 to, const std::vector<u8> &bytes) {
@@ -278,7 +280,7 @@ namespace hex {
std::string result;
for (i16 bit = hex::bit_width(number) - 1; bit >= 0; bit -= 1)
result += (number & (0b1 << bit)) == 0 ? '0' : '1';
result += (number & (0b1LLU << bit)) == 0 ? '0' : '1';
return result;
}

View File

@@ -4,7 +4,9 @@
#if defined(OS_MACOS)
struct GLFWwindow;
#if !defined(HEX_MODULE_EXPORT)
struct GLFWwindow;
#endif
extern "C" {
@@ -24,6 +26,10 @@
void macosMarkContentEdited(GLFWwindow *window, bool edited = true);
void macosGetKey(Keys key, int *output);
bool macosIsMainInstance();
void macosSendMessageToMainInstance(const unsigned char *data, size_t size);
void macosInstallEventListener();
}
#endif

View File

@@ -13,6 +13,13 @@
#include <wolv/utils/preproc.hpp>
#include <wolv/utils/guards.hpp>
#if defined(_MSC_VER)
#include <windows.h>
#define PLUGIN_ENTRY_POINT extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) { return TRUE; }
#else
#define PLUGIN_ENTRY_POINT
#endif
namespace {
struct PluginFunctionHelperInstantiation {};
}
@@ -45,7 +52,11 @@ void* PluginSubCommandsFunctionHelper<T>::getSubCommands() {
#if defined (IMHEX_STATIC_LINK_PLUGINS)
#define IMHEX_PLUGIN_VISIBILITY_PREFIX static
#else
#define IMHEX_PLUGIN_VISIBILITY_PREFIX extern "C" [[gnu::visibility("default")]]
#if defined(_MSC_VER)
#define IMHEX_PLUGIN_VISIBILITY_PREFIX extern "C" __declspec(dllexport)
#else
#define IMHEX_PLUGIN_VISIBILITY_PREFIX extern "C" [[gnu::visibility("default")]]
#endif
#endif
#define IMHEX_FEATURE_ENABLED(feature) WOLV_TOKEN_CONCAT(WOLV_TOKEN_CONCAT(WOLV_TOKEN_CONCAT(IMHEX_PLUGIN_, IMHEX_PLUGIN_NAME), _FEATURE_), feature)
@@ -70,14 +81,13 @@ 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::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) { \
ImGui::SetCurrentContext(ctx); \
GImGui = ctx; \
} \
extern "C" [[gnu::visibility("default")]] void WOLV_TOKEN_CONCAT(forceLinkPlugin_, IMHEX_PLUGIN_NAME)() { \
extern "C" void WOLV_TOKEN_CONCAT(forceLinkPlugin_, IMHEX_PLUGIN_NAME)() { \
hex::PluginManager::addPlugin(name, hex::PluginFunctions { \
nullptr, \
WOLV_TOKEN_CONCAT(initializeLibrary_, IMHEX_PLUGIN_NAME), \
@@ -92,10 +102,10 @@ void* PluginSubCommandsFunctionHelper<T>::getSubCommands() {
nullptr \
}); \
} \
PLUGIN_ENTRY_POINT \
IMHEX_PLUGIN_VISIBILITY_PREFIX void WOLV_TOKEN_CONCAT(initializeLibrary_, IMHEX_PLUGIN_NAME)()
#define IMHEX_PLUGIN_SETUP_IMPL(name, author, description) \
namespace { static struct EXIT_HANDLER { ~EXIT_HANDLER() { hex::log::debug("Unloaded plugin '{}'", name); } } HANDLER; } \
IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getPluginName() { return name; } \
IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getPluginAuthor() { return author; } \
IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getPluginDescription() { return description; } \
@@ -112,7 +122,7 @@ void* PluginSubCommandsFunctionHelper<T>::getSubCommands() {
return PluginSubCommandsFunctionHelper<PluginFunctionHelperInstantiation>::getSubCommands(); \
} \
IMHEX_PLUGIN_VISIBILITY_PREFIX void initializePlugin(); \
extern "C" [[gnu::visibility("default")]] void WOLV_TOKEN_CONCAT(forceLinkPlugin_, IMHEX_PLUGIN_NAME)() { \
extern "C" void WOLV_TOKEN_CONCAT(forceLinkPlugin_, IMHEX_PLUGIN_NAME)() { \
hex::PluginManager::addPlugin(name, hex::PluginFunctions { \
initializePlugin, \
nullptr, \
@@ -127,6 +137,7 @@ void* PluginSubCommandsFunctionHelper<T>::getSubCommands() {
getFeatures \
}); \
} \
PLUGIN_ENTRY_POINT \
IMHEX_PLUGIN_VISIBILITY_PREFIX void initializePlugin()
/**

View File

@@ -114,7 +114,7 @@ namespace hex::prv {
* @param size number of bytes to read
* @param overlays apply overlays and patches is true. Same as readRaw() if false
*/
void read(u64 offset, void *buffer, size_t size, bool overlays = true);
virtual void read(u64 offset, void *buffer, size_t size, bool overlays = true);
/**
* @brief Write data to the patches of this provider. Will not directly modify provider.
@@ -122,7 +122,7 @@ namespace hex::prv {
* @param buffer buffer to take data to write from
* @param size number of bytes to write
*/
void write(u64 offset, const void *buffer, size_t size);
virtual void write(u64 offset, const void *buffer, size_t size);
/**
* @brief Read data from this provider, without applying overlays and patches
@@ -194,11 +194,11 @@ namespace hex::prv {
[[nodiscard]] virtual std::vector<Description> getDataDescription() const;
[[nodiscard]] virtual std::variant<std::string, i128> queryInformation(const std::string &category, const std::string &argument);
void undo();
void redo();
virtual void undo();
virtual void redo();
[[nodiscard]] bool canUndo() const;
[[nodiscard]] bool canRedo() const;
[[nodiscard]] virtual bool canUndo() const;
[[nodiscard]] virtual bool canRedo() const;
[[nodiscard]] virtual bool hasFilePicker() const;
virtual bool handleFilePicker();
@@ -232,7 +232,7 @@ namespace hex::prv {
return m_undoRedoStack.add<T>(std::forward<decltype(args)...>(args)...);
}
[[nodiscard]] undo::Stack& getUndoStack() { return m_undoRedoStack; }
[[nodiscard]] virtual undo::Stack& getUndoStack() { return m_undoRedoStack; }
protected:
u32 m_currPage = 0;

View File

@@ -12,9 +12,11 @@
namespace hex {
namespace prv {
class Provider;
}
#if !defined(HEX_MODULE_EXPORT)
namespace prv {
class Provider;
}
#endif
template<typename T>
class PerProvider {
@@ -36,18 +38,30 @@ namespace hex {
}
T& get(const prv::Provider *provider = ImHexApi::Provider::get()) {
if (provider == nullptr) [[unlikely]]
throw std::invalid_argument("PerProvider::get called with nullptr");
return m_data[provider];
}
const T& get(const prv::Provider *provider = ImHexApi::Provider::get()) const {
if (provider == nullptr) [[unlikely]]
throw std::invalid_argument("PerProvider::get called with nullptr");
return m_data.at(provider);
}
void set(const T &data, const prv::Provider *provider = ImHexApi::Provider::get()) {
if (provider == nullptr) [[unlikely]]
throw std::invalid_argument("PerProvider::set called with nullptr");
m_data[provider] = data;
}
void set(T &&data, const prv::Provider *provider = ImHexApi::Provider::get()) {
if (provider == nullptr) [[unlikely]]
throw std::invalid_argument("PerProvider::set called with nullptr");
m_data[provider] = std::move(data);
}

View File

@@ -2,7 +2,6 @@
#include <hex.hpp>
#include <hex/api/localization_manager.hpp>
#include <hex/api/events/events_interaction.hpp>
#include <hex/providers/undo_redo/operations/operation.hpp>
@@ -35,7 +34,6 @@ namespace hex::prv::undo {
template<std::derived_from<Operation> T>
bool add(auto && ... args) {
auto result = this->add(std::make_unique<T>(std::forward<decltype(args)>(args)...));
EventDataChanged::post(m_provider);
return result;
}

View File

@@ -79,17 +79,16 @@ namespace ImGuiExt {
Texture(const Texture&) = delete;
Texture(Texture&& other) noexcept;
[[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);
[[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();
@@ -114,6 +113,10 @@ namespace ImGuiExt {
return float(m_width) / float(m_height);
}
[[nodiscard]] std::vector<u8> toBytes() const noexcept;
void reset();
private:
ImTextureID m_textureId = 0;
int m_width = 0, m_height = 0;
@@ -158,6 +161,8 @@ namespace ImGuiExt {
void OpenPopupInWindow(const char *window_name, const char *popup_name);
void DisableWindowResize(ImGuiDir dir);
struct ImHexCustomData {
ImVec4 Colors[ImGuiCustomCol_COUNT];
@@ -183,7 +188,7 @@ namespace ImGuiExt {
void StyleCustomColorsLight();
void StyleCustomColorsClassic();
void SmallProgressBar(float fraction, float yOffset = 0.0F);
void ProgressBar(float fraction, ImVec2 size_value = ImVec2(0, 0), float yOffset = 0.0F);
inline void TextFormatted(std::string_view fmt, auto &&...args) {
if constexpr (sizeof...(args) == 0) {
@@ -200,6 +205,7 @@ namespace ImGuiExt {
ImGui::PushID(text.c_str());
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2());
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0F);
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4());
ImGui::PushItemWidth(ImGui::CalcTextSize(text.c_str()).x + ImGui::GetStyle().FramePadding.x * 2);
@@ -207,7 +213,7 @@ namespace ImGuiExt {
ImGui::PopItemWidth();
ImGui::PopStyleColor();
ImGui::PopStyleVar();
ImGui::PopStyleVar(2);
ImGui::PopID();
}
@@ -246,6 +252,7 @@ namespace ImGuiExt {
ImGui::PushID(text.c_str());
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2());
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0F);
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4());
ImGui::PushItemWidth(ImGui::CalcTextSize(text.c_str()).x + ImGui::GetStyle().FramePadding.x * 2);
@@ -259,7 +266,7 @@ namespace ImGuiExt {
ImGui::PopItemWidth();
ImGui::PopStyleColor();
ImGui::PopStyleVar();
ImGui::PopStyleVar(2);
ImGui::PopID();
}

View File

@@ -98,6 +98,14 @@ namespace hex {
[[nodiscard]] static std::string toWindowName(const UnlocalizedString &unlocalizedName);
[[nodiscard]] bool isFocused() const { return m_focused; }
/**
* @brief Used for focus handling. Don't use this directly
* @param focused Whether this view is focused
*/
void setFocused(bool focused) { m_focused = focused; }
public:
class Window;
class Special;
@@ -110,6 +118,7 @@ namespace hex {
std::map<Shortcut, ShortcutManager::ShortcutEntry> m_shortcuts;
bool m_windowJustOpened = false;
const char *m_icon;
bool m_focused = false;
friend class ShortcutManager;
};
@@ -174,7 +183,7 @@ namespace hex {
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5F, 0.5F));
ImGui::SetNextWindowSizeConstraints(this->getMinSize(), this->getMaxSize());
if (ImGui::BeginPopupModal(View::toWindowName(this->getUnlocalizedName()).c_str(), this->hasCloseButton() ? &this->getWindowOpenState() : nullptr, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_AlwaysAutoResize | this->getWindowFlags())) {
if (ImGui::BeginPopupModal(View::toWindowName(this->getUnlocalizedName()).c_str(), this->hasCloseButton() ? &this->getWindowOpenState() : nullptr, ImGuiWindowFlags_NoCollapse | this->getWindowFlags())) {
this->drawContent();
ImGui::EndPopup();

View File

@@ -12,13 +12,13 @@
namespace hex {
static AutoReset<std::unordered_map<std::string, std::unordered_map<std::string, std::unique_ptr<Achievement>>>> s_achievements;
const std::unordered_map<std::string, std::unordered_map<std::string, std::unique_ptr<Achievement>>> &AchievementManager::getAchievements() {
static AutoReset<std::unordered_map<UnlocalizedString, std::unordered_map<UnlocalizedString, std::unique_ptr<Achievement>>>> s_achievements;
const std::unordered_map<UnlocalizedString, std::unordered_map<UnlocalizedString, std::unique_ptr<Achievement>>> &AchievementManager::getAchievements() {
return *s_achievements;
}
static AutoReset<std::unordered_map<std::string, std::list<AchievementManager::AchievementNode>>> s_nodeCategoryStorage;
std::unordered_map<std::string, std::list<AchievementManager::AchievementNode>>& getAchievementNodesMutable(bool rebuild) {
static AutoReset<std::unordered_map<UnlocalizedString, std::list<AchievementManager::AchievementNode>>> s_nodeCategoryStorage;
std::unordered_map<UnlocalizedString, std::list<AchievementManager::AchievementNode>>& getAchievementNodesMutable(bool rebuild) {
if (!s_nodeCategoryStorage->empty() || !rebuild)
return s_nodeCategoryStorage;
@@ -36,12 +36,12 @@ namespace hex {
return s_nodeCategoryStorage;
}
const std::unordered_map<std::string, std::list<AchievementManager::AchievementNode>>& AchievementManager::getAchievementNodes(bool rebuild) {
const std::unordered_map<UnlocalizedString, std::list<AchievementManager::AchievementNode>>& AchievementManager::getAchievementNodes(bool rebuild) {
return getAchievementNodesMutable(rebuild);
}
static AutoReset<std::unordered_map<std::string, std::vector<AchievementManager::AchievementNode*>>> s_startNodes;
const std::unordered_map<std::string, std::vector<AchievementManager::AchievementNode*>>& AchievementManager::getAchievementStartNodes(bool rebuild) {
static AutoReset<std::unordered_map<UnlocalizedString, std::vector<AchievementManager::AchievementNode*>>> s_startNodes;
const std::unordered_map<UnlocalizedString, std::vector<AchievementManager::AchievementNode*>>& AchievementManager::getAchievementStartNodes(bool rebuild) {
if (!s_startNodes->empty() || !rebuild)
return s_startNodes;
@@ -187,10 +187,10 @@ namespace hex {
const auto &category = newAchievement->getUnlocalizedCategory();
const auto &name = newAchievement->getUnlocalizedName();
auto [categoryIter, categoryInserted] = s_achievements->insert({ category, std::unordered_map<std::string, std::unique_ptr<Achievement>>{} });
auto [categoryIter, categoryInserted] = s_achievements->insert({ category, std::unordered_map<UnlocalizedString, std::unique_ptr<Achievement>>{} });
auto &[categoryKey, achievements] = *categoryIter;
auto [achievementIter, achievementInserted] = achievements.insert({ name, std::move(newAchievement) });
auto [achievementIter, achievementInserted] = achievements.emplace(name, std::move(newAchievement));
auto &[achievementKey, achievement] = *achievementIter;
achievementAdded();
@@ -239,7 +239,7 @@ namespace hex {
achievement->setProgress(progress);
} catch (const std::exception &e) {
log::warn("Failed to load achievement progress for '{}::{}': {}", categoryName, achievementName, e.what());
log::warn("Failed to load achievement progress for '{}::{}': {}", categoryName.get(), achievementName.get(), e.what());
}
}
}

View File

@@ -33,7 +33,7 @@ namespace hex {
namespace impl {
struct OnChange {
u32 id;
u64 id;
OnChangeCallback callback;
};
@@ -714,15 +714,15 @@ namespace hex {
namespace impl {
static AutoReset<std::map<std::string, std::unique_ptr<View>>> s_views;
const std::map<std::string, std::unique_ptr<View>>& getEntries() {
static AutoReset<std::map<UnlocalizedString, std::unique_ptr<View>>> s_views;
const std::map<UnlocalizedString, std::unique_ptr<View>>& getEntries() {
return *s_views;
}
void add(std::unique_ptr<View> &&view) {
log::debug("Registered new view: {}", view->getUnlocalizedName().get());
s_views->insert({ view->getUnlocalizedName(), std::move(view) });
s_views->emplace(view->getUnlocalizedName(), std::move(view));
}
}
@@ -736,6 +736,15 @@ namespace hex {
return nullptr;
}
View* getFocusedView() {
for (const auto &[unlocalizedName, view] : *impl::s_views) {
if (view->isFocused())
return view.get();
}
return nullptr;
}
}
namespace ContentRegistry::Tools {
@@ -1126,7 +1135,9 @@ namespace hex {
namespace ContentRegistry::HexEditor {
const int DataVisualizer::TextInputFlags = ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_NoHorizontalScroll | ImGuiInputTextFlags_AlwaysOverwrite;
int DataVisualizer::DefaultTextInputFlags() {
return ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_NoHorizontalScroll | ImGuiInputTextFlags_AlwaysOverwrite;
}
bool DataVisualizer::drawDefaultScalarEditingTextBox(u64 address, const char *format, ImGuiDataType dataType, u8 *data, ImGuiInputTextFlags flags) const {
struct UserData {
@@ -1144,7 +1155,7 @@ namespace hex {
};
ImGui::PushID(reinterpret_cast<void*>(address));
ImGuiExt::InputScalarCallback("##editing_input", dataType, data, format, flags | TextInputFlags | ImGuiInputTextFlags_CallbackEdit, [](ImGuiInputTextCallbackData *data) -> int {
ImGuiExt::InputScalarCallback("##editing_input", dataType, data, format, flags | DefaultTextInputFlags() | ImGuiInputTextFlags_CallbackEdit, [](ImGuiInputTextCallbackData *data) -> int {
auto &userData = *static_cast<UserData*>(data->UserData);
if (data->CursorPos >= userData.maxChars)
@@ -1175,7 +1186,7 @@ namespace hex {
};
ImGui::PushID(reinterpret_cast<void*>(address));
ImGui::InputText("##editing_input", data.data(), data.size() + 1, flags | TextInputFlags | ImGuiInputTextFlags_CallbackEdit, [](ImGuiInputTextCallbackData *data) -> int {
ImGui::InputText("##editing_input", data.data(), data.size() + 1, flags | DefaultTextInputFlags() | ImGuiInputTextFlags_CallbackEdit, [](ImGuiInputTextCallbackData *data) -> int {
auto &userData = *static_cast<UserData*>(data->UserData);
userData.data->resize(data->BufSize);

View File

@@ -7,6 +7,7 @@
#include <hex/api/events/requests_lifecycle.hpp>
#include <hex/api/events/requests_provider.hpp>
#include <hex/api/events/requests_gui.hpp>
#include <hex/api/events/events_interaction.hpp>
#include <hex/api/task_manager.hpp>
#include <hex/helpers/fmt.hpp>
@@ -101,6 +102,9 @@ namespace hex {
static PerProvider<std::optional<Region>> s_hoveredRegion;
void setHoveredRegion(const prv::Provider *provider, const Region &region) {
if (provider == nullptr)
return;
if (region == Region::Invalid())
s_hoveredRegion.get(provider).reset();
else
@@ -462,7 +466,7 @@ namespace hex {
if (s_providers->empty())
EventProviderChanged::post(provider, nullptr);
EventProviderClosed::post(it->get());
EventProviderClosed::post(providerToRemove);
RequestUpdateWindowTitle::post();
// Do the destruction of the provider in the background once all tasks have finished
@@ -574,13 +578,22 @@ namespace hex {
return s_windowResizable;
}
static std::vector<hex::impl::AutoResetBase*> s_autoResetObjects;
static auto& getAutoResetObjects() {
static std::set<hex::impl::AutoResetBase*> autoResetObjects;
return autoResetObjects;
}
void addAutoResetObject(hex::impl::AutoResetBase *object) {
s_autoResetObjects.emplace_back(object);
getAutoResetObjects().insert(object);
}
void removeAutoResetObject(hex::impl::AutoResetBase *object) {
getAutoResetObjects().erase(object);
}
void cleanup() {
for (const auto &object : s_autoResetObjects)
for (const auto &object : getAutoResetObjects())
object->reset();
}
@@ -629,7 +642,8 @@ namespace hex {
#elif defined(OS_MACOS)
return ::getBackingScaleFactor();
#elif defined(OS_LINUX)
if (std::string_view(::getenv("XDG_SESSION_TYPE")) == "x11")
const auto sessionType = hex::getEnvironmentVariable("XDG_SESSION_TYPE");
if (!sessionType.has_value() || sessionType == "x11")
return 1.0F;
else {
float xScale = 0, yScale = 0;
@@ -739,13 +753,14 @@ namespace hex {
DSROLE_PRIMARY_DOMAIN_INFO_BASIC * info;
if ((DsRoleGetPrimaryDomainInformation(NULL, DsRolePrimaryDomainInfoBasic, (PBYTE *)&info) == ERROR_SUCCESS) && (info != nullptr))
{
bool result = std::wstring(info->DomainNameFlat).empty();
bool result = std::wstring(info->DomainNameFlat) != L"WORKGROUP";
DsRoleFreeMemory(info);
return result;
} else {
DWORD size = 1024;
::GetComputerNameExA(ComputerNameDnsDomain, nullptr, &size);
DWORD size = 128;
char buffer[128];
::GetComputerNameExA(ComputerNameDnsDomain, buffer, &size);
return size > 0;
}
}
@@ -861,7 +876,8 @@ namespace hex {
SemanticVersion getImHexVersion() {
#if defined IMHEX_VERSION
return SemanticVersion(IMHEX_VERSION);
static auto version = SemanticVersion(IMHEX_VERSION);
return version;
#else
return {};
#endif
@@ -925,7 +941,7 @@ namespace hex {
}
EventImHexClosing::subscribe([executablePath, updateTypeString] {
hex::executeCommand(
hex::startProgram(
hex::format("\"{}\" \"{}\"",
wolv::util::toUTF8String(executablePath),
updateTypeString
@@ -1052,7 +1068,7 @@ namespace hex {
};
}
void loadFont(const std::fs::path &path, const std::vector<GlyphRange> &glyphRanges, Offset offset, u32 flags, std::optional<u32> defaultSize) {
void loadFont(const std::fs::path &path, const std::vector<GlyphRange> &glyphRanges, Offset offset, u32 flags, std::optional<bool> scalable, std::optional<u32> defaultSize) {
wolv::io::File fontFile(path, wolv::io::File::Mode::Read);
if (!fontFile.isValid()) {
log::error("Failed to load font from file '{}'", wolv::util::toUTF8String(path));
@@ -1065,17 +1081,19 @@ namespace hex {
glyphRanges,
offset,
flags,
scalable,
defaultSize
});
}
void loadFont(const std::string &name, const std::span<const u8> &data, const std::vector<GlyphRange> &glyphRanges, Offset offset, u32 flags, std::optional<u32> defaultSize) {
void loadFont(const std::string &name, const std::span<const u8> &data, const std::vector<GlyphRange> &glyphRanges, Offset offset, u32 flags, std::optional<bool> scalable, std::optional<u32> defaultSize) {
impl::s_fonts->emplace_back(Font {
name,
{ data.begin(), data.end() },
glyphRanges,
offset,
flags,
scalable,
defaultSize
});
}
@@ -1104,6 +1122,18 @@ namespace hex {
return impl::s_italicFont;
}
float getDpi() {
auto dpi = ImGui::GetCurrentContext()->CurrentDpiScale * 96.0F;
return dpi ? dpi : 96.0F;
}
float pixelsToPoints(float pixels) {
return pixels * (72.0 / getDpi());
}
float pointsToPixels(float points) {
return points / (72.0 / getDpi());
}
}

View File

@@ -41,21 +41,27 @@ namespace hex {
std::ranges::transform(fileName, fileName.begin(), tolower);
fileName += ".hexlyt";
std::fs::path layoutPath;
for (const auto &path : paths::Layouts.write()) {
layoutPath = path / fileName;
}
size_t outSize = 0;
const char* iniData = ImGui::SaveIniSettingsToMemory(&outSize);
if (layoutPath.empty()) {
log::error("Failed to save layout '{}'. No writable path found", name);
std::fs::path layoutPath = path / fileName;
wolv::io::File file = wolv::io::File(layoutPath, wolv::io::File::Mode::Write);
if (!file.isValid()) {
log::warn("Failed to save layout '{}'. Could not open file '{}', continuing with next path", name, wolv::util::toUTF8String(layoutPath));
continue;
}
const size_t written = file.writeBuffer(reinterpret_cast<const u8*>(iniData), outSize);
if (written != outSize) {
log::warn("Failed to save layout '{}'. Could not write file '{}', continuing with next path", name, wolv::util::toUTF8String(layoutPath));
continue;
}
log::info("Layout '{}' saved to '{}'", name, wolv::util::toUTF8String(layoutPath));
LayoutManager::reload();
return;
}
const auto pathString = wolv::util::toUTF8String(layoutPath);
ImGui::SaveIniSettingsToDisk(pathString.c_str());
log::info("Layout '{}' saved to {}", name, pathString);
LayoutManager::reload();
log::error("Failed to save layout '{}'. No writable path found", name);
}
std::string LayoutManager::saveToString() {

View File

@@ -30,7 +30,11 @@ namespace hex {
return handle;
#else
auto handle = uintptr_t(dlopen(wolv::util::toUTF8String(path).c_str(), RTLD_LAZY));
const auto pathString = wolv::util::toUTF8String(path);
auto handle = uintptr_t(dlopen(pathString.c_str(), RTLD_NOLOAD));
if (handle == 0)
handle = uintptr_t(dlopen(pathString.c_str(), RTLD_NOW | RTLD_GLOBAL));
if (handle == 0) {
log::error("Loading library '{}' failed: {}!", wolv::util::toUTF8String(path.filename()), dlerror());

View File

@@ -310,16 +310,17 @@ namespace hex {
if (focused)
pressedShortcut += CurrentView;
pressedShortcut += static_cast<Keys>(keyCode);
pressedShortcut += scanCodeToKey(keyCode);
return pressedShortcut;
}
static void processShortcut(Shortcut shortcut, const std::map<Shortcut, ShortcutManager::ShortcutEntry> &shortcuts) {
if (s_paused) return;
static bool processShortcut(Shortcut shortcut, const std::map<Shortcut, ShortcutManager::ShortcutEntry> &shortcuts) {
if (s_paused)
return true;
if (ImGui::IsPopupOpen(ImGuiID(0), ImGuiPopupFlags_AnyPopupId))
return;
return true;
const bool currentlyTyping = ImGui::GetIO().WantTextInput;
@@ -338,8 +339,19 @@ namespace hex {
if (!entry.unlocalizedName.empty()) {
s_lastShortcutMainMenu = entry.unlocalizedName.front();
}
return true;
}
}
return false;
}
bool ShortcutManager::runShortcut(const Shortcut &shortcut, const View *view) {
if (view == nullptr)
return processShortcut(shortcut, s_globalShortcuts);
else
return processShortcut(shortcut, view->m_shortcuts);
}
void ShortcutManager::process(const View *currentView, bool ctrl, bool alt, bool shift, bool super, bool focused, u32 keyCode) {
@@ -347,7 +359,7 @@ namespace hex {
if (keyCode != 0)
s_prevShortcut = Shortcut(pressedShortcut.getKeys());
processShortcut(pressedShortcut, currentView->m_shortcuts);
runShortcut(pressedShortcut, currentView);
}
void ShortcutManager::processGlobals(bool ctrl, bool alt, bool shift, bool super, u32 keyCode) {
@@ -355,7 +367,7 @@ namespace hex {
if (keyCode != 0)
s_prevShortcut = Shortcut(pressedShortcut.getKeys());
processShortcut(pressedShortcut, s_globalShortcuts);
runShortcut(pressedShortcut);
}
std::optional<UnlocalizedString> ShortcutManager::getLastActivatedMenu() {

View File

@@ -63,8 +63,11 @@ namespace hex {
}
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(const UnlocalizedString &unlocalizedName, u64 maxValue, bool background, bool blocking, std::function<void(Task &)> function)
: m_unlocalizedName(std::move(unlocalizedName)),
m_maxValue(maxValue),
m_function(std::move(function)),
m_background(background), m_blocking(blocking) { }
Task::Task(hex::Task &&other) noexcept {
{
@@ -133,6 +136,11 @@ namespace hex {
return m_background;
}
bool Task::isBlocking() const {
return m_blocking;
}
bool Task::isFinished() const {
return m_finished;
}
@@ -327,11 +335,11 @@ namespace hex {
s_tasksFinishedCallbacks.clear();
}
TaskHolder TaskManager::createTask(const UnlocalizedString &unlocalizedName, u64 maxValue, bool background, std::function<void(Task&)> function) {
TaskHolder TaskManager::createTask(const UnlocalizedString &unlocalizedName, u64 maxValue, bool background, bool blocking, std::function<void(Task&)> function) {
std::scoped_lock lock(s_queueMutex);
// Construct new task
auto task = std::make_shared<Task>(std::move(unlocalizedName), maxValue, background, std::move(function));
auto task = std::make_shared<Task>(std::move(unlocalizedName), maxValue, background, blocking, std::move(function));
s_tasks.emplace_back(task);
@@ -346,12 +354,12 @@ namespace hex {
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));
return createTask(std::move(unlocalizedName), maxValue, false, false, 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,
return createTask(std::move(unlocalizedName), maxValue, false, false,
[function = std::move(function)](Task&) {
function();
}
@@ -360,12 +368,26 @@ namespace hex {
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));
return createTask(std::move(unlocalizedName), 0, true, false, 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,
return createTask(std::move(unlocalizedName), 0, true, false,
[function = std::move(function)](Task&) {
function();
}
);
}
TaskHolder TaskManager::createBlockingTask(const UnlocalizedString &unlocalizedName, u64 maxValue, std::function<void(Task &)> function) {
log::debug("Creating blocking task {}", unlocalizedName.get());
return createTask(std::move(unlocalizedName), maxValue, true, true, std::move(function));
}
TaskHolder TaskManager::createBlockingTask(const UnlocalizedString &unlocalizedName, u64 maxValue, std::function<void()> function) {
log::debug("Creating blocking task {}", unlocalizedName.get());
return createTask(std::move(unlocalizedName), maxValue, true, true,
[function = std::move(function)](Task&) {
function();
}
@@ -414,6 +436,14 @@ namespace hex {
});
}
size_t TaskManager::getRunningBlockingTaskCount() {
std::scoped_lock lock(s_queueMutex);
return std::ranges::count_if(s_tasks, [](const auto &task){
return task->isBlocking();
});
}
void TaskManager::doLater(const std::function<void()> &function) {
std::scoped_lock lock(s_deferredCallsMutex);

View File

@@ -327,6 +327,7 @@ namespace hex {
}
ImGui::SetNextWindowPos(position, ImGuiCond_Always, pivot);
ImGui::SetNextWindowViewport(ImGui::GetMainViewport()->ID);
if (ImGui::Begin("##TutorialMessage", nullptr, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoFocusOnAppearing)) {
ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindowRead());

View File

@@ -14,10 +14,10 @@
namespace hex {
AutoReset<std::map<std::string, WorkspaceManager::Workspace>> WorkspaceManager::s_workspaces;
decltype(WorkspaceManager::s_workspaces)::Type::iterator WorkspaceManager::s_currentWorkspace = s_workspaces->end();
decltype(WorkspaceManager::s_workspaces)::Type::iterator WorkspaceManager::s_previousWorkspace = s_workspaces->end();
decltype(WorkspaceManager::s_workspaces)::Type::iterator WorkspaceManager::s_workspaceToRemove = s_workspaces->end();
static AutoReset<std::map<std::string, WorkspaceManager::Workspace>> s_workspaces;
static decltype(s_workspaces)::Type::iterator s_currentWorkspace = s_workspaces->end();
static decltype(s_workspaces)::Type::iterator s_previousWorkspace = s_workspaces->end();
static decltype(s_workspaces)::Type::iterator s_workspaceToRemove = s_workspaces->end();
void WorkspaceManager::createWorkspace(const std::string& name, const std::string &layout) {
s_currentWorkspace = s_workspaces->insert_or_assign(name, Workspace {
@@ -133,7 +133,10 @@ namespace hex {
if (s_previousWorkspace != s_currentWorkspace) {
log::info("Updating workspace");
if (s_previousWorkspace != s_workspaces->end()) {
auto newWorkspace = s_currentWorkspace;
s_currentWorkspace = s_previousWorkspace;
exportToFile(s_previousWorkspace->second.path, s_previousWorkspace->first, s_previousWorkspace->second.builtin);
s_currentWorkspace = newWorkspace;
}
LayoutManager::closeAllViews();
@@ -174,7 +177,13 @@ namespace hex {
}
}
const std::map<std::string, WorkspaceManager::Workspace>& WorkspaceManager::getWorkspaces() {
return *s_workspaces;
}
const std::map<std::string, WorkspaceManager::Workspace>::iterator& WorkspaceManager::getCurrentWorkspace() {
return s_currentWorkspace;
}
}

View File

@@ -41,7 +41,7 @@ namespace hex::dp {
const i128& Node::getIntegerOnInput(u32 index) {
auto attribute = this->getConnectedInputAttribute(index);
auto &outputData = [&] -> std::vector<u8>& {
auto &outputData = [&]() -> std::vector<u8>&{
if (attribute != nullptr) {
if (attribute->getType() != Attribute::Type::Integer)
throwNodeError("Tried to read integer from non-integer attribute");
@@ -68,7 +68,7 @@ namespace hex::dp {
const double& Node::getFloatOnInput(u32 index) {
auto attribute = this->getConnectedInputAttribute(index);
auto &outputData = [&] -> std::vector<u8>& {
auto &outputData = [&]() -> std::vector<u8>&{
if (attribute != nullptr) {
if (attribute->getType() != Attribute::Type::Float)
throwNodeError("Tried to read integer from non-float attribute");

View File

@@ -0,0 +1,91 @@
#include <hex/helpers/clipboard.hpp>
#if __has_include(<clip.h>)
#define CLIP_LIBRARY
#endif
#if defined(CLIP_LIBRARY)
#include <clip.h>
#else
#include <imgui.h>
#include <fmt/color.h>
#include <hex/helpers/utils.hpp>
#endif
namespace hex::clipboard {
#if defined(CLIP_LIBRARY)
static clip::format s_binaryFormat;
static clip::format s_textFormat;
void init() {
s_binaryFormat = clip::register_format("net.werwolv.imhex.binary");
s_textFormat = clip::text_format();
}
void setBinaryData(std::span<const u8> data) {
clip::lock l;
l.set_data(s_binaryFormat, reinterpret_cast<const char*>(data.data()), data.size());
}
std::vector<u8> getBinaryData() {
clip::lock l;
const auto size = l.get_data_length(s_binaryFormat);
std::vector<u8> data(size);
l.get_data(s_binaryFormat, reinterpret_cast<char*>(data.data()), size);
return data;
}
void setTextData(const std::string &string) {
clip::lock l;
l.set_data(s_textFormat, string.data(), string.size());
}
std::string getTextData() {
clip::lock l;
const auto size = l.get_data_length(s_binaryFormat);
std::string data(size, 0x00);
l.get_data(s_textFormat, data.data(), size);
return data;
}
#else
void init() {}
void setBinaryData(std::span<const u8> data) {
constexpr static auto Format = "{0:02X} ";
std::string result;
result.reserve(fmt::format(Format, 0x00).size() * data.size_bytes());
for (const auto &byte : data)
result += fmt::format(Format, byte);
result.pop_back();
ImGui::SetClipboardText(result.c_str());
}
std::vector<u8> getBinaryData() {
auto clipboard = ImGui::GetClipboardText();
if (clipboard == nullptr)
return {};
return parseHexString(clipboard);
}
void setTextData(const std::string &string) {
ImGui::SetClipboardText(string.c_str());
}
std::string getTextData() {
return ImGui::GetClipboardText();
}
#endif
}

View File

@@ -20,6 +20,7 @@
#include <cstddef>
#include <cstdint>
#include <bit>
#include <span>
#if MBEDTLS_VERSION_MAJOR <= 2
@@ -470,7 +471,7 @@ namespace hex::crypt {
std::vector<u8> bytes;
u8 byte;
while (true) {
byte = value & 0x7F;
byte = u8(value & 0x7F);
value >>= 7;
if constexpr(std::signed_integral<T>) {
if (value == 0 && (byte & 0x40) == 0) {

View File

@@ -44,7 +44,7 @@ namespace hex::paths {
if (includeSystemFolders) {
if (auto executablePath = wolv::io::fs::getExecutablePath(); executablePath.has_value()) {
paths.push_back(*executablePath);
paths.push_back(executablePath->parent_path());
}
}

View File

@@ -0,0 +1,60 @@
#include "hex/helpers/freetype.hpp"
#include "imgui.h"
namespace hex::ft {
void Bitmap::lcdFilter() {
if (m_width * m_height == 0)
return;
std::vector <ImU8> h = {8, 0x4D, 0x55, 0x4D, 8};
auto paddedWidth = m_width + 4;
auto fWidth = paddedWidth + ((3 - (paddedWidth % 3)) % 3);
auto fPitch = (fWidth + 3) & (-4);
Bitmap f(fWidth, m_height, fPitch);
//std::vector<std::vector<ImU8>> fir(3, std::vector<ImU8>(3, 0));
// first output: h[0]*input[0]/255.0f;
// 2nd output: (h[1]*input[0] + h[0]*input[1])/255.0f;
// 3rd output: (h[2]*input[0] + h[1]*input[1] + h[0]*input[2])/255.0f;
// 4th output: (h[1]*input[0] + h[2]*input[1] + h[1]*input[2] + h[0]*input[3])/255.0f;
// ith output: (h[0]*input[5+i] + h[1]*input[i+6] + h[2]*input[i+7] + h[1]*input[i+8] + h[0]*input[i+9])/255.0f;
// aap output: (h[0]*input[N-4] + h[1]*input[N-3] + h[2]*input[N-2] + h[1]*input[N-1])/255.0f;
// ap output: (h[0]*input[N-3] + h[1]*input[N-2] + h[2]*input[N-1])/255.0f;
// p output: (h[0]*input[N-2] + h[1]*input[N-1] )/255.0f;
// last output: h[0]*input[N-1]/255.0f;
for (ImU32 y = 0; y < m_height; y++) {
auto fp = y * fPitch;
auto yp = y * m_pitch;
bool done = false;
for (ImU32 x = 0; x < 4; x++) {
ImU32 head = 0;
ImU32 tail = 0;
if (m_width >= x + 1) {
for (ImU32 i = 0; i < x + 1; i++) {
head += h[x - i] * m_data[yp + i];
tail += h[i] * m_data[yp + m_width - 1 - x + i];
}
f.m_data[fp + x] = head >> 8;
f.m_data[fp + paddedWidth - 1 - x] = tail >> 8;
} else {
done = true;
break;
}
}
if (done)
continue;
for (ImU32 x = 4; x < paddedWidth - 4; x++) {
ImU32 head = 0;
for (ImS32 i = 0; i < 5; i++) {
head += h[i] * m_data[yp + i + x - 4];
}
f.m_data[fp + x] = head >> 8;
}
}
clear();
m_width = f.m_width;
m_height = f.m_height;
m_pitch = f.m_pitch;
m_data = std::move(f.m_data);
}
}

View File

@@ -49,15 +49,6 @@ namespace hex {
}
void HttpRequest::checkProxyErrors() { }
int HttpRequest::progressCallback(void *contents, curl_off_t dlTotal, curl_off_t dlNow, curl_off_t ulTotal, curl_off_t ulNow) {
std::ignore = contents;
std::ignore = dlTotal;
std::ignore = dlNow;
std::ignore = ulTotal;
std::ignore = ulNow;
return -1;
}
}
#endif

View File

@@ -1,6 +1,7 @@
#if !defined(OS_WEB)
#include <hex/helpers/http_requests.hpp>
#include <curl/curl.h>
namespace hex {
@@ -11,6 +12,19 @@ namespace hex {
}
int progressCallback(void *contents, curl_off_t dlTotal, curl_off_t dlNow, curl_off_t ulTotal, curl_off_t ulNow) {
auto &request = *static_cast<HttpRequest *>(contents);
if (dlTotal > 0)
request.setProgress(float(dlNow) / dlTotal);
else if (ulTotal > 0)
request.setProgress(float(ulNow) / ulTotal);
else
request.setProgress(0.0F);
return request.isCanceled() ? CURLE_ABORTED_BY_CALLBACK : CURLE_OK;
}
HttpRequest::HttpRequest(std::string method, std::string url) : m_method(std::move(method)), m_url(std::move(url)) {
AT_FIRST_TIME {
curl_global_init(CURL_GLOBAL_ALL);
@@ -95,19 +109,101 @@ namespace hex {
}
}
int HttpRequest::progressCallback(void *contents, curl_off_t dlTotal, curl_off_t dlNow, curl_off_t ulTotal, curl_off_t ulNow) {
auto &request = *static_cast<HttpRequest *>(contents);
namespace impl {
if (dlTotal > 0)
request.m_progress = float(dlNow) / dlTotal;
else if (ulTotal > 0)
request.m_progress = float(ulNow) / ulTotal;
else
request.m_progress = 0.0F;
void setWriteFunctions(CURL *curl, wolv::io::File &file) {
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HttpRequest::writeToFile);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &file);
}
void setWriteFunctions(CURL *curl, std::vector<u8> &data) {
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HttpRequest::writeToVector);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data);
}
void setupFileUpload(CURL *curl, wolv::io::File &file, const std::string &fileName, const std::string &mimeName) {
curl_mime *mime = curl_mime_init(curl);
curl_mimepart *part = curl_mime_addpart(mime);
curl_mime_data_cb(part, file.getSize(),
[](char *buffer, size_t size, size_t nitems, void *arg) -> size_t {
auto handle = static_cast<FILE*>(arg);
return fread(buffer, size, nitems, handle);
},
[](void *arg, curl_off_t offset, int origin) -> int {
auto handle = static_cast<FILE*>(arg);
if (fseek(handle, offset, origin) != 0)
return CURL_SEEKFUNC_CANTSEEK;
else
return CURL_SEEKFUNC_OK;
},
[](void *arg) {
auto handle = static_cast<FILE*>(arg);
fclose(handle);
},
file.getHandle());
curl_mime_filename(part, fileName.c_str());
curl_mime_name(part, mimeName.c_str());
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
}
void setupFileUpload(CURL *curl, const std::vector<u8> &data, const std::fs::path &fileName, const std::string &mimeName) {
curl_mime *mime = curl_mime_init(curl);
curl_mimepart *part = curl_mime_addpart(mime);
curl_mime_data(part, reinterpret_cast<const char *>(data.data()), data.size());
auto fileNameStr = wolv::util::toUTF8String(fileName.filename());
curl_mime_filename(part, fileNameStr.c_str());
curl_mime_name(part, mimeName.c_str());
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
}
int executeCurl(CURL *curl, const std::string &url, const std::string &method, const std::string &body, std::map<std::string, std::string> &headers) {
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, method.c_str());
if (!body.empty()) {
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
}
curl_slist *headersList = nullptr;
headersList = curl_slist_append(headersList, "Cache-Control: no-cache");
ON_SCOPE_EXIT { curl_slist_free_all(headersList); };
for (auto &[key, value] : headers) {
std::string header = hex::format("{}: {}", key, value);
headersList = curl_slist_append(headersList, header.c_str());
}
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headersList);
auto result = curl_easy_perform(curl);
if (result != CURLE_OK){
return result;
}
return 0;
}
long getStatusCode(CURL *curl) {
long statusCode = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &statusCode);
return statusCode;
}
std::string getStatusText(int result) {
return curl_easy_strerror(CURLcode(result));
}
return request.m_canceled ? CURLE_ABORTED_BY_CALLBACK : CURLE_OK;
}
}

View File

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

View File

@@ -83,7 +83,8 @@ namespace hex::log {
for (const auto &path : paths::Logs.all()) {
wolv::io::fs::createDirectories(path);
s_loggerFile = wolv::io::File(path / hex::format("{0:%Y%m%d_%H%M%S}.log", fmt::localtime(std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()))), wolv::io::File::Mode::Create);
time_t time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
s_loggerFile = wolv::io::File(path / hex::format("{0:%Y%m%d_%H%M%S}.log", *std::localtime(&time)), wolv::io::File::Mode::Create);
s_loggerFile.disableBuffering();
if (s_loggerFile.isValid()) {
@@ -120,7 +121,8 @@ namespace hex::log {
void printPrefix(FILE *dest, const fmt::text_style &ts, const std::string &level, const char *projectName) {
const auto now = fmt::localtime(std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()));
const auto time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
const auto now = *std::localtime(&time);
fmt::print(dest, "[{0:%H:%M:%S}] ", now);

View File

@@ -15,7 +15,12 @@
#include <string>
#include <magic.h>
#include <unistd.h>
#if defined(_MSC_VER)
#include <direct.h>
#else
#include <unistd.h>
#endif
#if defined(OS_WINDOWS)
#define MAGIC_PATH_SEPARATOR ";"

View File

@@ -170,7 +170,7 @@ namespace hex::gl {
m_buffer = other.m_buffer;
m_size = other.m_size;
m_type = other.m_type;
other.m_buffer = -1;
other.m_buffer = 0;
}
template<typename T>
@@ -178,7 +178,7 @@ namespace hex::gl {
m_buffer = other.m_buffer;
m_size = other.m_size;
m_type = other.m_type;
other.m_buffer = -1;
other.m_buffer = 0;
return *this;
}
@@ -231,12 +231,12 @@ namespace hex::gl {
VertexArray::VertexArray(VertexArray &&other) noexcept {
m_array = other.m_array;
other.m_array = -1;
other.m_array = 0;
}
VertexArray& VertexArray::operator=(VertexArray &&other) noexcept {
m_array = other.m_array;
other.m_array = -1;
other.m_array = 0;
return *this;
}
@@ -268,7 +268,7 @@ namespace hex::gl {
Texture::Texture(Texture &&other) noexcept {
m_texture = other.m_texture;
other.m_texture = -1;
other.m_texture = 0;
m_width = other.m_width;
m_height = other.m_height;
@@ -276,7 +276,7 @@ namespace hex::gl {
Texture& Texture::operator=(Texture &&other) noexcept {
m_texture = other.m_texture;
other.m_texture = -1;
other.m_texture = 0;
return *this;
}
@@ -302,7 +302,7 @@ namespace hex::gl {
GLuint Texture::release() {
auto copy = m_texture;
m_texture = -1;
m_texture = 0;
return copy;
}
@@ -327,16 +327,16 @@ namespace hex::gl {
FrameBuffer::FrameBuffer(FrameBuffer &&other) noexcept {
m_frameBuffer = other.m_frameBuffer;
other.m_frameBuffer = -1;
other.m_frameBuffer = 0;
m_renderBuffer = other.m_renderBuffer;
other.m_renderBuffer = -1;
other.m_renderBuffer = 0;
}
FrameBuffer& FrameBuffer::operator=(FrameBuffer &&other) noexcept {
m_frameBuffer = other.m_frameBuffer;
other.m_frameBuffer = -1;
other.m_frameBuffer = 0;
m_renderBuffer = other.m_renderBuffer;
other.m_renderBuffer = -1;
other.m_renderBuffer = 0;
return *this;
}

View File

@@ -0,0 +1,69 @@
#include <hex/helpers/udp_server.hpp>
#if defined(OS_WINDOWS)
#include <winsock2.h>
#include <ws2tcpip.h>
using socklen_t = int;
#else
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#endif
namespace hex {
UDPServer::UDPServer(u16 port, Callback callback)
: m_port(port), m_callback(std::move(callback)), m_running(false), m_socketFd(-1) {
}
UDPServer::~UDPServer() {
stop();
}
void UDPServer::start() {
m_running = true;
m_thread = std::thread(&UDPServer::run, this);
}
void UDPServer::stop() {
m_running = false;
if (m_thread.joinable()) m_thread.join();
if (m_socketFd >= 0) {
#if defined(OS_WINDOWS)
::closesocket(m_socketFd);
#else
::close(m_socketFd);
#endif
}
}
void UDPServer::run() {
m_socketFd = ::socket(AF_INET, SOCK_DGRAM, 0);
if (m_socketFd < 0) {
return;
}
sockaddr_in addr = { };
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(m_port);
if (bind(m_socketFd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0) {
return;
}
std::vector<u8> buffer(64 * 1024, 0x00);
while (m_running) {
sockaddr_in client{};
socklen_t len = sizeof(client);
const auto bytes = ::recvfrom(m_socketFd, reinterpret_cast<char*>(buffer.data()), buffer.size(), 0, reinterpret_cast<sockaddr*>(&client), &len);
if (bytes > 0) {
buffer[bytes] = '\0';
m_callback({ buffer.data(), buffer.data() + bytes });
}
}
}
}

View File

@@ -11,6 +11,7 @@
#include <imgui_internal.h>
#include <GLFW/glfw3.h>
#include <hex/api/events/events_lifecycle.hpp>
#if defined(OS_WINDOWS)
#include <windows.h>
@@ -30,7 +31,6 @@
#endif
namespace hex {
float operator""_scaled(long double value) {
return value * ImHexApi::System::getGlobalScale();
}
@@ -52,7 +52,7 @@ namespace hex {
u8 index = sizeof(data) - 2;
while (value != 0 && index != 0) {
data[index] = '0' + value % 10;
data[index] = static_cast<char>('0' + (value % 10));
value /= 10;
index--;
}
@@ -67,7 +67,7 @@ namespace hex {
u8 index = sizeof(data) - 2;
while (unsignedValue != 0 && index != 0) {
data[index] = '0' + unsignedValue % 10;
data[index] = static_cast<char>('0' + (unsignedValue % 10));
unsignedValue /= 10;
index--;
}
@@ -163,25 +163,25 @@ namespace hex {
switch (unitIndex) {
case 0:
result += ((value == 1) ? " Byte" : " Bytes");
break;
break;
case 1:
result += " kiB";
break;
break;
case 2:
result += " MiB";
break;
break;
case 3:
result += " GiB";
break;
break;
case 4:
result += " TiB";
break;
break;
case 5:
result += " PiB";
break;
break;
case 6:
result += " EiB";
break;
break;
default:
result = "A lot!";
}
@@ -338,15 +338,15 @@ namespace hex {
void startProgram(const std::string &command) {
#if defined(OS_WINDOWS)
std::ignore = system(hex::format("start {0}", command).c_str());
#elif defined(OS_MACOS)
std::ignore = system(hex::format("open {0}", command).c_str());
#elif defined(OS_LINUX)
executeCmd({"xdg-open", command});
#elif defined(OS_WEB)
std::ignore = command;
#endif
#if defined(OS_WINDOWS)
std::ignore = system(hex::format("start \"\" {0}", command).c_str());
#elif defined(OS_MACOS)
std::ignore = system(hex::format("{0}", command).c_str());
#elif defined(OS_LINUX)
executeCmd({"xdg-open", command});
#elif defined(OS_WEB)
std::ignore = command;
#endif
}
int executeCommand(const std::string &command) {
@@ -357,19 +357,19 @@ namespace hex {
if (!url.contains("://"))
url = "https://" + url;
#if defined(OS_WINDOWS)
ShellExecuteA(nullptr, "open", url.c_str(), nullptr, nullptr, SW_SHOWNORMAL);
#elif defined(OS_MACOS)
openWebpageMacos(url.c_str());
#elif defined(OS_LINUX)
executeCmd({"xdg-open", url});
#elif defined(OS_WEB)
EM_ASM({
window.open(UTF8ToString($0), '_blank');
}, url.c_str());
#else
#warning "Unknown OS, can't open webpages"
#endif
#if defined(OS_WINDOWS)
ShellExecuteA(nullptr, "open", url.c_str(), nullptr, nullptr, SW_SHOWNORMAL);
#elif defined(OS_MACOS)
openWebpageMacos(url.c_str());
#elif defined(OS_LINUX)
executeCmd({"xdg-open", url});
#elif defined(OS_WEB)
EM_ASM({
window.open(UTF8ToString($0), '_blank');
}, url.c_str());
#else
#warning "Unknown OS, can't open webpages"
#endif
}
std::optional<u8> hexCharToValue(char c) {
@@ -391,31 +391,31 @@ namespace hex {
switch (byte) {
case '\\':
result += "\\";
break;
break;
case '\a':
result += "\\a";
break;
break;
case '\b':
result += "\\b";
break;
break;
case '\f':
result += "\\f";
break;
break;
case '\n':
result += "\\n";
break;
break;
case '\r':
result += "\\r";
break;
break;
case '\t':
result += "\\t";
break;
break;
case '\v':
result += "\\v";
break;
break;
default:
result += hex::format("\\x{:02X}", byte);
break;
break;
}
}
}
@@ -442,46 +442,46 @@ namespace hex {
switch (escapeChar) {
case 'a':
result.push_back('\a');
break;
break;
case 'b':
result.push_back('\b');
break;
break;
case 'f':
result.push_back('\f');
break;
break;
case 'n':
result.push_back('\n');
break;
break;
case 'r':
result.push_back('\r');
break;
break;
case 't':
result.push_back('\t');
break;
break;
case 'v':
result.push_back('\v');
break;
break;
case '\\':
result.push_back('\\');
break;
break;
case 'x':
{
u8 byte = 0x00;
if ((offset + 1) >= string.length()) return {};
{
u8 byte = 0x00;
if ((offset + 1) >= string.length()) return {};
for (u8 i = 0; i < 2; i++) {
byte <<= 4;
if (auto hexValue = hexCharToValue(c()); hexValue.has_value())
byte |= hexValue.value();
else
return {};
for (u8 i = 0; i < 2; i++) {
byte <<= 4;
if (auto hexValue = hexCharToValue(c()); hexValue.has_value())
byte |= hexValue.value();
else
return {};
offset++;
}
result.push_back(byte);
offset++;
}
break;
result.push_back(byte);
}
break;
default:
return {};
}
@@ -650,27 +650,27 @@ namespace hex {
}
bool isProcessElevated() {
#if defined(OS_WINDOWS)
bool elevated = false;
HANDLE token = INVALID_HANDLE_VALUE;
#if defined(OS_WINDOWS)
bool elevated = false;
HANDLE token = INVALID_HANDLE_VALUE;
if (::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &token)) {
TOKEN_ELEVATION elevation;
DWORD elevationSize = sizeof(TOKEN_ELEVATION);
if (::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &token)) {
TOKEN_ELEVATION elevation;
DWORD elevationSize = sizeof(TOKEN_ELEVATION);
if (::GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &elevationSize))
elevated = elevation.TokenIsElevated;
}
if (::GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &elevationSize))
elevated = elevation.TokenIsElevated;
}
if (token != INVALID_HANDLE_VALUE)
::CloseHandle(token);
if (token != INVALID_HANDLE_VALUE)
::CloseHandle(token);
return elevated;
#elif defined(OS_LINUX) || defined(OS_MACOS)
return getuid() == 0 || getuid() != geteuid();
#else
return false;
#endif
return elevated;
#elif defined(OS_LINUX) || defined(OS_MACOS)
return getuid() == 0 || getuid() != geteuid();
#else
return false;
#endif
}
std::optional<std::string> getEnvironmentVariable(const std::string &env) {
@@ -806,45 +806,45 @@ namespace hex {
}
std::string formatSystemError(i32 error) {
#if defined(OS_WINDOWS)
wchar_t *message = nullptr;
auto wLength = FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(wchar_t*)&message, 0,
nullptr
);
ON_SCOPE_EXIT { LocalFree(message); };
#if defined(OS_WINDOWS)
wchar_t *message = nullptr;
auto wLength = FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(wchar_t*)&message, 0,
nullptr
);
ON_SCOPE_EXIT { LocalFree(message); };
auto length = ::WideCharToMultiByte(CP_UTF8, 0, message, wLength, nullptr, 0, nullptr, nullptr);
std::string result(length, '\x00');
::WideCharToMultiByte(CP_UTF8, 0, message, wLength, result.data(), length, nullptr, nullptr);
auto length = ::WideCharToMultiByte(CP_UTF8, 0, message, wLength, nullptr, 0, nullptr, nullptr);
std::string result(length, '\x00');
::WideCharToMultiByte(CP_UTF8, 0, message, wLength, result.data(), length, nullptr, nullptr);
return result;
#else
return std::system_category().message(error);
#endif
return result;
#else
return std::system_category().message(error);
#endif
}
void* getContainingModule(void* symbol) {
#if defined(OS_WINDOWS)
MEMORY_BASIC_INFORMATION mbi;
if (VirtualQuery(symbol, &mbi, sizeof(mbi)))
return mbi.AllocationBase;
#if defined(OS_WINDOWS)
MEMORY_BASIC_INFORMATION mbi;
if (VirtualQuery(symbol, &mbi, sizeof(mbi)))
return mbi.AllocationBase;
return nullptr;
#elif !defined(OS_WEB)
Dl_info info = {};
if (dladdr(symbol, &info) == 0)
return nullptr;
#elif !defined(OS_WEB)
Dl_info info = {};
if (dladdr(symbol, &info) == 0)
return nullptr;
return dlopen(info.dli_fname, RTLD_LAZY);
#else
std::ignore = symbol;
return nullptr;
#endif
return dlopen(info.dli_fname, RTLD_LAZY);
#else
std::ignore = symbol;
return nullptr;
#endif
}
std::optional<ImColor> blendColors(const std::optional<ImColor> &a, const std::optional<ImColor> &b) {
@@ -865,4 +865,8 @@ namespace hex {
glfwIconifyWindow(windowHandle);
}
extern "C" void macosEventDataReceived(const u8 *data, size_t length) {
EventNativeMessageReceived::post(std::vector<u8>(data, data + length));
}
}

View File

@@ -17,6 +17,7 @@
#import <Cocoa/Cocoa.h>
#import <Foundation/Foundation.h>
#import <AppleScriptObjC/AppleScriptObjC.h>
#include <hex/helpers/keys.hpp>
@@ -147,6 +148,74 @@
[cocoaWindow setDocumentEdited:edited];
}
static NSArray* getRunningInstances(NSString *bundleIdentifier) {
return [NSRunningApplication runningApplicationsWithBundleIdentifier: bundleIdentifier];
}
bool macosIsMainInstance(void) {
NSArray *applications = getRunningInstances(@"net.WerWolv.ImHex");
return applications.count == 0;
}
extern void macosEventDataReceived(const unsigned char *data, size_t length);
static OSErr handleAppleEvent(const AppleEvent *event, AppleEvent *reply, void *refcon) {
(void)reply;
(void)refcon;
// Extract the raw binary data from the event's parameter
AEDesc paramDesc;
OSErr err = AEGetParamDesc(event, keyDirectObject, typeWildCard, &paramDesc);
if (err != noErr) {
NSLog(@"Failed to get parameter: %d", err);
return err;
}
// Convert the AEDesc to NSData
NSAppleEventDescriptor *descriptor = [[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&paramDesc];
NSData *binaryData = descriptor.data;
// Process the binary data
if (binaryData) {
macosEventDataReceived(binaryData.bytes, binaryData.length);
}
return noErr;
}
void macosInstallEventListener(void) {
AEInstallEventHandler('misc', 'imhx', NewAEEventHandlerUPP(handleAppleEvent), 0, false);
}
void macosSendMessageToMainInstance(const unsigned char *data, size_t size) {
NSString *bundleIdentifier = @"net.WerWolv.ImHex";
NSData *binaryData = [NSData dataWithBytes:data length:size];
// Find the target application by its bundle identifier
NSAppleEventDescriptor *targetApp = [NSAppleEventDescriptor descriptorWithBundleIdentifier:bundleIdentifier];
if (!targetApp) {
NSLog(@"Application with bundle identifier %@ not found.", bundleIdentifier);
return;
}
// Create the Apple event
NSAppleEventDescriptor *event = [[NSAppleEventDescriptor alloc] initWithEventClass:'misc'
eventID:'imhx'
targetDescriptor:targetApp
returnID:kAutoGenerateReturnID
transactionID:kAnyTransactionID];
// Add a parameter with raw binary data
NSAppleEventDescriptor *binaryDescriptor = [NSAppleEventDescriptor descriptorWithDescriptorType:typeData
data:binaryData];
[event setParamDescriptor:binaryDescriptor forKeyword:keyDirectObject];
// Send the event
OSStatus status = AESendMessage([event aeDesc], NULL, kAENoReply, kAEDefaultTimeout);
if (status != noErr) {
NSLog(@"Failed to send Apple event: %d", status);
}
}
@interface HexDocument : NSDocument
@end

View File

@@ -2,6 +2,7 @@
#include <hex.hpp>
#include <hex/api/events/events_provider.hpp>
#include <hex/api/events/events_interaction.hpp>
#include <cmath>
#include <cstring>
@@ -107,8 +108,8 @@ namespace hex::prv {
auto newSize = oldSize + size;
this->resizeRaw(newSize);
std::vector<u8> buffer(0x1000);
const std::vector<u8> zeroBuffer(0x1000);
std::vector<u8> buffer(0x1000, 0x00);
const std::vector<u8> zeroBuffer(0x1000, 0x00);
auto position = oldSize;
while (position > offset) {
@@ -154,10 +155,10 @@ namespace hex::prv {
auto overlayOffset = overlay->getAddress();
auto overlaySize = overlay->getSize();
i128 overlapMin = std::max(offset, overlayOffset);
i128 overlapMax = std::min(offset + size, overlayOffset + overlaySize);
u64 overlapMin = std::max(offset, overlayOffset);
u64 overlapMax = std::min(offset + size, overlayOffset + overlaySize);
if (overlapMax > overlapMin)
std::memcpy(static_cast<u8 *>(buffer) + std::max<i128>(0, overlapMin - offset), overlay->getData().data() + std::max<i128>(0, overlapMin - overlayOffset), overlapMax - overlapMin);
std::memcpy(static_cast<u8 *>(buffer) + std::max<u64>(0, overlapMin - offset), overlay->getData().data() + std::max<u64>(0, overlapMin - overlayOffset), overlapMax - overlapMin);
}
}
@@ -332,7 +333,7 @@ namespace hex::prv {
else if (category == "description")
return magic::getDescription(this);
else if (category == "provider_type")
return this->getTypeName();
return this->getTypeName().get();
else
return 0;
}

View File

@@ -1,5 +1,6 @@
#include <hex/providers/undo_redo/stack.hpp>
#include <hex/providers/undo_redo/operations/operation_group.hpp>
#include <hex/api/events/events_interaction.hpp>
#include <hex/providers/provider.hpp>
@@ -122,6 +123,8 @@ namespace hex::prv::undo {
// Do the operation
this->getLastOperation()->redo(m_provider);
EventDataChanged::post(m_provider);
return true;
}

View File

@@ -53,7 +53,7 @@ namespace hex::subcommands {
while (argsIter != args.end()) {
const std::string &arg = *argsIter;
if (arg == "--othercmd") {
if (!currentSubCommandArgs.empty() && arg.starts_with("--") && !(currentSubCommand.has_value() && currentSubCommand->type == SubCommand::Type::SubCommand)) {
// Save command to run
if (currentSubCommand) {
subCommands.emplace_back(*currentSubCommand, currentSubCommandArgs);
@@ -61,10 +61,10 @@ namespace hex::subcommands {
currentSubCommand = std::nullopt;
currentSubCommandArgs = { };
} else if (currentSubCommand) {
// Add current argument to the current command
currentSubCommandArgs.push_back(arg);
argsIter += 1;
} else {
// Get next subcommand from current argument
currentSubCommand = findSubCommand(arg);
@@ -72,9 +72,9 @@ namespace hex::subcommands {
log::error("No subcommand named '{}' found", arg);
exit(EXIT_FAILURE);
}
}
argsIter += 1;
argsIter += 1;
}
}
// Save last command to run
@@ -83,8 +83,8 @@ namespace hex::subcommands {
}
// Run the subcommands
for (auto &[subcommand, args] : subCommands) {
subcommand.callback(args);
for (auto &[subcommand, subCommandArgs] : subCommands) {
subcommand.callback(subCommandArgs);
}
// Exit the process if it's not the main instance (the commands have been forwarded to another instance)

View File

@@ -260,9 +260,6 @@ namespace ImGuiExt {
}
Texture::Texture(Texture&& other) noexcept {
if (m_textureId != 0)
glDeleteTextures(1, reinterpret_cast<GLuint*>(&m_textureId));
m_textureId = other.m_textureId;
m_width = other.m_width;
m_height = other.m_height;
@@ -271,8 +268,10 @@ namespace ImGuiExt {
}
Texture& Texture::operator=(Texture&& other) noexcept {
if (m_textureId != 0)
glDeleteTextures(1, reinterpret_cast<GLuint*>(&m_textureId));
if (this == &other)
return *this;
this->reset();
m_textureId = other.m_textureId;
m_width = other.m_width;
@@ -284,10 +283,41 @@ namespace ImGuiExt {
}
Texture::~Texture() {
if (m_textureId == 0)
return;
this->reset();
}
glDeleteTextures(1, reinterpret_cast<GLuint*>(&m_textureId));
void Texture::reset() {
#if !defined(OS_WEB)
if (glDeleteTextures == nullptr)
return;
#endif
if (m_textureId != 0) {
glDeleteTextures(1, reinterpret_cast<GLuint*>(&m_textureId));
m_textureId = 0;
}
}
std::vector<u8> Texture::toBytes() const noexcept {
std::vector<u8> result(m_width * m_height * 4);
#if defined(OS_WEB)
GLuint fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_textureId, 0);
glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, result.data());
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &fbo);
#else
glBindTexture(GL_TEXTURE_2D, m_textureId);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, result.data());
glBindTexture(GL_TEXTURE_2D, 0);
#endif
return result;
}
float GetTextWrapPos() {
@@ -326,16 +356,21 @@ namespace ImGuiExt {
bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags);
// Render
BeginGroup();
TextDisabled("%s", icon);
SameLine();
const ImU32 col = hovered ? GetColorU32(ImGuiCol_ButtonHovered) : GetColorU32(ImGuiCol_ButtonActive);
PushStyleColor(ImGuiCol_Text, ImU32(col));
Text("%s %s", icon, label);
TextUnformatted(label);
if (hovered)
GetWindowDrawList()->AddLine(ImVec2(pos.x, pos.y + size.y), pos + size, ImU32(col));
PopStyleColor();
EndGroup();
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
return pressed;
}
@@ -663,10 +698,8 @@ namespace ImGuiExt {
}
ImVec2 GetCustomStyleVec2(ImGuiCustomStyle idx) {
switch (idx) {
default:
return { };
}
std::ignore = idx;
return {};
}
void StyleCustomColorsDark() {
@@ -741,6 +774,17 @@ namespace ImGuiExt {
End();
}
void DisableWindowResize(ImGuiDir dir) {
const auto window = GetCurrentWindow();
const auto borderId = GetWindowResizeBorderID(window, dir);
if (borderId == GetHoveredID()) {
GImGui->ActiveIdMouseButton = 0;
SetHoveredID(0);
}
if (borderId == GetActiveID())
SetActiveID(0, window);
}
bool TitleBarButton(const char *label, ImVec2 size_arg) {
ImGuiWindow *window = GetCurrentWindow();
@@ -808,8 +852,11 @@ namespace ImGuiExt {
PushStyleColor(ImGuiCol_Text, color);
// Render
const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered
: ImGuiCol_MenuBarBg);
ImU32 col = 0x00;
if (held)
col = GetColorU32(ImGuiCol_ScrollbarGrabActive);
else if (hovered)
col = GetColorU32(ImGuiCol_ScrollbarGrabHovered);
RenderNavCursor(bb, id);
RenderFrame(bb.Min, bb.Max, col, false, style.FrameRounding);
RenderTextClipped(bb.Min + padding, bb.Max - padding, symbol, nullptr, &size, style.ButtonTextAlign, &bb);
@@ -855,7 +902,7 @@ namespace ImGuiExt {
: ImGuiCol_Button);
RenderNavCursor(bb, id);
RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding);
RenderTextClipped(bb.Min + style.FramePadding * ImVec2(1.3, 1) + iconOffset, bb.Max - style.FramePadding, symbol, nullptr, &label_size, style.ButtonTextAlign, &bb);
RenderTextClipped(bb.Min + style.FramePadding * ImVec2(1.3F, 1) + iconOffset, bb.Max - style.FramePadding, symbol, nullptr, &label_size, style.ButtonTextAlign, &bb);
PopStyleColor();
@@ -937,7 +984,7 @@ namespace ImGuiExt {
return result;
}
void SmallProgressBar(float fraction, float yOffset) {
void ProgressBar(float fraction, ImVec2 size_value, float yOffset) {
ImGuiWindow *window = GetCurrentWindow();
if (window->SkipItems)
return;
@@ -946,7 +993,7 @@ namespace ImGuiExt {
const ImGuiStyle &style = g.Style;
ImVec2 pos = window->DC.CursorPos + ImVec2(0, yOffset);
ImVec2 size = CalcItemSize(ImVec2(100, 5) * hex::ImHexApi::System::getGlobalScale(), 100, g.FontSize + style.FramePadding.y * 2.0F);
ImVec2 size = CalcItemSize(size_value, ImGui::GetContentRegionAvail().x, g.FontSize + style.FramePadding.y * 2.0F);
ImRect bb(pos, pos + size);
ItemSize(size, 0);
if (!ItemAdd(bb, 0))

1
lib/third_party/clip vendored Submodule

Submodule lib/third_party/clip added at 7a60eabaad

View File

@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.16)
project(imgui)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 23)
add_library(imgui_all_includes INTERFACE)
@@ -13,4 +13,11 @@ add_subdirectory(imnodes)
add_subdirectory(backend)
add_subdirectory(ColorTextEditor)
set(IMGUI_LIBRARIES imgui_imgui imgui_cimgui imgui_implot imgui_implot3d imgui_imnodes imgui_backend imgui_color_text_editor PARENT_SCOPE)
set(IMGUI_LIBRARIES imgui_imgui imgui_cimgui imgui_implot imgui_implot3d imgui_imnodes imgui_backend imgui_color_text_editor)
set(IMGUI_LIBRARIES ${IMGUI_LIBRARIES} PARENT_SCOPE)
if (NOT IMHEX_EXTERNAL_PLUGIN_BUILD)
foreach (LIBRARY IN LISTS IMGUI_LIBRARIES)
target_compile_definitions(${LIBRARY} PRIVATE EXPORT_SYMBOLS=1)
endforeach ()
endif()

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