mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-31 13:26:02 -05:00
Compare commits
348 Commits
feature/ap
...
feature/cl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f517dc9829 | ||
|
|
fe1309fb3d | ||
|
|
0ea3adcb75 | ||
|
|
12d59ce3e4 | ||
|
|
96ef758bbd | ||
|
|
224fa83c65 | ||
|
|
f591ac8780 | ||
|
|
11e70511e6 | ||
|
|
c1e4121d1e | ||
|
|
03884ddd05 | ||
|
|
ac67e985af | ||
|
|
9d12cd64d3 | ||
|
|
702b5f2888 | ||
|
|
a5eef3f34d | ||
|
|
1bc9277e3c | ||
|
|
b33cb07dc0 | ||
|
|
ce74915c14 | ||
|
|
f341413248 | ||
|
|
ed3e2f65f8 | ||
|
|
6e5878b5d6 | ||
|
|
39242097dd | ||
|
|
0aec3fffe1 | ||
|
|
38ef00548a | ||
|
|
c78c8072e9 | ||
|
|
7c98411abe | ||
|
|
e22516662f | ||
|
|
24c1f48522 | ||
|
|
69b07d40e4 | ||
|
|
b96692b1ba | ||
|
|
53afb7cba0 | ||
|
|
8e0953af1e | ||
|
|
724f9aa524 | ||
|
|
7067ffafe7 | ||
|
|
145c88db31 | ||
|
|
56615d6c06 | ||
|
|
d26bcc1abe | ||
|
|
04f817c042 | ||
|
|
b58f97c1f1 | ||
|
|
96dc386694 | ||
|
|
c6c70daa5e | ||
|
|
de16375903 | ||
|
|
c6548d5ad1 | ||
|
|
bd8c4e807c | ||
|
|
553549302c | ||
|
|
c69a7012c5 | ||
|
|
7acc5fc02e | ||
|
|
39bc165f36 | ||
|
|
707a92281b | ||
|
|
823013a3d9 | ||
|
|
7089561b21 | ||
|
|
0f0bff1685 | ||
|
|
b6387c3f64 | ||
|
|
ff0bcfb7da | ||
|
|
f729d36214 | ||
|
|
d5a07b6a5b | ||
|
|
bda0b3ce18 | ||
|
|
14d95a7e46 | ||
|
|
2ef2cdd874 | ||
|
|
57c2d84122 | ||
|
|
d263962a06 | ||
|
|
e32c5784af | ||
|
|
1496a6e755 | ||
|
|
6dab1063a1 | ||
|
|
ff286f3e05 | ||
|
|
6f112c2d16 | ||
|
|
8f222dab99 | ||
|
|
828951ffe9 | ||
|
|
616f34e210 | ||
|
|
fa3ed7e618 | ||
|
|
a207969dec | ||
|
|
7fde40b04e | ||
|
|
1bce588cdd | ||
|
|
5a095cc993 | ||
|
|
431eab47a2 | ||
|
|
e9e3d25315 | ||
|
|
e2735e283e | ||
|
|
3e9cb57dd6 | ||
|
|
5c4cf7379f | ||
|
|
8cd961596e | ||
|
|
d2344418d6 | ||
|
|
33aa2248d2 | ||
|
|
feb5b209ed | ||
|
|
34722404f4 | ||
|
|
b78a234fe1 | ||
|
|
f19478374f | ||
|
|
51a01c860b | ||
|
|
eedd044716 | ||
|
|
0a327f4ad3 | ||
|
|
eec6a5da0a | ||
|
|
fc87bc0cf1 | ||
|
|
1f213408a1 | ||
|
|
bac6fd803f | ||
|
|
5a74d7e3e2 | ||
|
|
e289380c39 | ||
|
|
8081dff6b6 | ||
|
|
7dcf09118b | ||
|
|
4b9a3d121d | ||
|
|
cd24cba240 | ||
|
|
d33fad9d23 | ||
|
|
b02aa51e09 | ||
|
|
36eeee5f9c | ||
|
|
4883ed0e5a | ||
|
|
78ad0d2592 | ||
|
|
f6def74b29 | ||
|
|
be44676b01 | ||
|
|
60c1c22a73 | ||
|
|
02cadc264e | ||
|
|
a0ca5b8072 | ||
|
|
31fdb73b0e | ||
|
|
d2caa1859d | ||
|
|
f6c25b30ae | ||
|
|
379d826f18 | ||
|
|
96afccc46c | ||
|
|
c0a222644b | ||
|
|
653173945f | ||
|
|
7d09cc6d25 | ||
|
|
a4360dfe76 | ||
|
|
9887117e7a | ||
|
|
9be7eafa39 | ||
|
|
774eb18a42 | ||
|
|
4e582d02f5 | ||
|
|
38d11dacb7 | ||
|
|
e17490ee04 | ||
|
|
f3a9ca6d6f | ||
|
|
2653740a36 | ||
|
|
335042ec08 | ||
|
|
f6944b15f3 | ||
|
|
d7960dccb4 | ||
|
|
c974c4257d | ||
|
|
40d74dd633 | ||
|
|
602c85b57d | ||
|
|
f96fa596b3 | ||
|
|
8c13d0096e | ||
|
|
7879f8b6a4 | ||
|
|
4c0e8bc1d6 | ||
|
|
6644df3958 | ||
|
|
2b5551d719 | ||
|
|
137063dd21 | ||
|
|
ca403869ab | ||
|
|
daf676b277 | ||
|
|
66bbdbe6ec | ||
|
|
d3c2516f5f | ||
|
|
c39ae84922 | ||
|
|
a83843fdab | ||
|
|
2d48da1c4a | ||
|
|
af0c15f69d | ||
|
|
7898df9c2c | ||
|
|
48abdeaf6b | ||
|
|
99a4979b65 | ||
|
|
d8beff4f6b | ||
|
|
ccaf1e33c0 | ||
|
|
3f119b957e | ||
|
|
abf97212fe | ||
|
|
b81c3d2f75 | ||
|
|
5651c4d95c | ||
|
|
c83a5cc1b7 | ||
|
|
0499807597 | ||
|
|
f846afd8a9 | ||
|
|
b822c82d18 | ||
|
|
e4de551008 | ||
|
|
5333d0180f | ||
|
|
658d4c4d72 | ||
|
|
efa50a8c39 | ||
|
|
677dc6192d | ||
|
|
1ed56c1b1d | ||
|
|
983be04722 | ||
|
|
1bd9c918f6 | ||
|
|
0ba16485bb | ||
|
|
1d9934830b | ||
|
|
806d6148eb | ||
|
|
e484587778 | ||
|
|
1e4b5104b7 | ||
|
|
676d2e2ef5 | ||
|
|
6122d44bd9 | ||
|
|
eb9f0cdf0c | ||
|
|
01f4595aab | ||
|
|
bf10d333cd | ||
|
|
267ef37cb6 | ||
|
|
879e4c9d58 | ||
|
|
67340e1526 | ||
|
|
6ec8f9efe5 | ||
|
|
c2b0560d91 | ||
|
|
388071557e | ||
|
|
f6e3ede178 | ||
|
|
a907550567 | ||
|
|
c75a15dc3b | ||
|
|
83904aa1f1 | ||
|
|
7d527fd2a6 | ||
|
|
007e04bf37 | ||
|
|
caff49504e | ||
|
|
aad38beaf5 | ||
|
|
bdad733331 | ||
|
|
bc26ade57e | ||
|
|
ee52ff3b11 | ||
|
|
40b95f02e4 | ||
|
|
8777a85630 | ||
|
|
870aeb34fc | ||
|
|
b03be212b3 | ||
|
|
c8f7dbf85e | ||
|
|
9e826b4c8b | ||
|
|
05d528b39a | ||
|
|
6828c7c077 | ||
|
|
54f3bc0262 | ||
|
|
e232a2b33d | ||
|
|
73a3b217a4 | ||
|
|
19f925c60b | ||
|
|
5fb488236b | ||
|
|
c84786f9ee | ||
|
|
c1925ddf8d | ||
|
|
cf194e332c | ||
|
|
d8877e7d8b | ||
|
|
8b2184f8e3 | ||
|
|
a42e4c5299 | ||
|
|
419787e17c | ||
|
|
2d6da52a86 | ||
|
|
b46deb3fa0 | ||
|
|
b70120a248 | ||
|
|
3a6a4011d0 | ||
|
|
999c4d07b7 | ||
|
|
44b182c6ae | ||
|
|
de7bec547a | ||
|
|
5542c0bc00 | ||
|
|
83e0ce0042 | ||
|
|
4685dea075 | ||
|
|
599f63bc67 | ||
|
|
199f2aea77 | ||
|
|
bff9b8b4b1 | ||
|
|
a83610bc06 | ||
|
|
b3d208e6e6 | ||
|
|
e8b391c0f6 | ||
|
|
02b5df03ab | ||
|
|
e1580e51cf | ||
|
|
3a7578879f | ||
|
|
ea3d4b41a9 | ||
|
|
e0c2a39ce7 | ||
|
|
1fa27b7f09 | ||
|
|
f980f1dae2 | ||
|
|
b81ad53449 | ||
|
|
a9727171e2 | ||
|
|
a1634fb337 | ||
|
|
94a2f9460e | ||
|
|
18cd39270a | ||
|
|
72c2bca363 | ||
|
|
4c153dc76d | ||
|
|
e63606f6bb | ||
|
|
ed6da7fe14 | ||
|
|
a588c96440 | ||
|
|
4c284b224e | ||
|
|
96afa650d1 | ||
|
|
f17d0d3ae1 | ||
|
|
930d2b4280 | ||
|
|
f67b78bd91 | ||
|
|
540e8ed602 | ||
|
|
99cb51e813 | ||
|
|
db000c4b12 | ||
|
|
0cd557a686 | ||
|
|
6142bf859b | ||
|
|
b6498b5c2d | ||
|
|
c15030e96e | ||
|
|
cd2acd73b4 | ||
|
|
cfe06ea1b6 | ||
|
|
ca5c3e0e94 | ||
|
|
6252fd399a | ||
|
|
de571e2c2a | ||
|
|
0cbd052b91 | ||
|
|
aa3ec3ece8 | ||
|
|
6b11028b72 | ||
|
|
269c3e7398 | ||
|
|
08335041f5 | ||
|
|
d75b9cf942 | ||
|
|
b55c40523f | ||
|
|
99a2dee7a2 | ||
|
|
c94265c77b | ||
|
|
7ddfba1b4c | ||
|
|
9ecdd28eea | ||
|
|
d8b36242f6 | ||
|
|
3f470aabe9 | ||
|
|
1e8dd54b3e | ||
|
|
0a6681ccb7 | ||
|
|
0140e24822 | ||
|
|
9fb38922ea | ||
|
|
7752354598 | ||
|
|
497670c4c3 | ||
|
|
84954cd2f1 | ||
|
|
8b6eab401e | ||
|
|
71c11a5923 | ||
|
|
f345edb252 | ||
|
|
be40fd9563 | ||
|
|
5ee2ebfb4f | ||
|
|
cfa6b706a8 | ||
|
|
42f2a62d62 | ||
|
|
41b6ef930a | ||
|
|
948cbe0a9c | ||
|
|
18669f3230 | ||
|
|
4e9f944204 | ||
|
|
fe18cbaa41 | ||
|
|
ed3712e1b9 | ||
|
|
20dc4f31f0 | ||
|
|
19f9296a40 | ||
|
|
06c019387c | ||
|
|
645b43e9cc | ||
|
|
ed37a3711f | ||
|
|
a3460de9dc | ||
|
|
5084009d62 | ||
|
|
e5c003d726 | ||
|
|
327a02b87d | ||
|
|
e9bf1a9f7a | ||
|
|
0c6fa768ea | ||
|
|
483468a6c7 | ||
|
|
8039ae1b90 | ||
|
|
466b372d41 | ||
|
|
3f6b5203ca | ||
|
|
8d1352ddff | ||
|
|
e6ab2c3b7e | ||
|
|
e603c75bd3 | ||
|
|
4f28f97141 | ||
|
|
d0b32e5224 | ||
|
|
2062a23347 | ||
|
|
8c9236a066 | ||
|
|
2f981ef91e | ||
|
|
6725c170ea | ||
|
|
c8cf6e7c08 | ||
|
|
e0b4acee12 | ||
|
|
803ebe34ed | ||
|
|
e981eff1e6 | ||
|
|
aee7a09b6c | ||
|
|
e74e4e92a0 | ||
|
|
6dba15defd | ||
|
|
fee7a16692 | ||
|
|
141030344b | ||
|
|
4fa9586206 | ||
|
|
fbbc430b7c | ||
|
|
bfc68c4d28 | ||
|
|
53fc018ada | ||
|
|
d45dd45720 | ||
|
|
19a9786bbf | ||
|
|
b8caf41423 | ||
|
|
0b3866a56a | ||
|
|
53a7577416 | ||
|
|
f5515417d6 | ||
|
|
24e7c2f3db | ||
|
|
6e6c5bbc67 | ||
|
|
f4403ff480 | ||
|
|
098da20761 | ||
|
|
ef2373e8c0 | ||
|
|
b2c8ed17d5 | ||
|
|
bb594a459f | ||
|
|
7340a30650 |
157
.github/workflows/build.yml
vendored
157
.github/workflows/build.yml
vendored
@@ -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
|
||||
|
||||
3
.github/workflows/release.yml
vendored
3
.github/workflows/release.yml
vendored
@@ -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
5
.gitignore
vendored
@@ -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
7
.gitmodules
vendored
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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": [
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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:")
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
4
dist/Arch/PKGBUILD
vendored
@@ -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")
|
||||
|
||||
5
dist/ImHex-9999.ebuild
vendored
5
dist/ImHex-9999.ebuild
vendored
@@ -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
|
||||
"
|
||||
|
||||
2
dist/compiling/linux.md
vendored
2
dist/compiling/linux.md
vendored
@@ -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" \
|
||||
|
||||
4
dist/compiling/macos.md
vendored
4
dist/compiling/macos.md
vendored
@@ -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
|
||||
```
|
||||
```
|
||||
|
||||
14
dist/gen_release_notes.py
vendored
14
dist/gen_release_notes.py
vendored
@@ -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")
|
||||
|
||||
13
dist/macOS/arm64.Dockerfile
vendored
13
dist/macOS/arm64.Dockerfile
vendored
@@ -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
1
dist/rpm/imhex.spec
vendored
@@ -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
16
dist/vcpkg.json
vendored
Normal 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
4
dist/web/Dockerfile
vendored
@@ -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", \
|
||||
|
||||
5
dist/web/source/sitemap.xml
vendored
5
dist/web/source/sitemap.xml
vendored
@@ -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>
|
||||
10
dist/web/source/wasm-config.js
vendored
10
dist/web/source/wasm-config.js
vendored
@@ -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: []
|
||||
};
|
||||
|
||||
2
lib/external/disassembler
vendored
2
lib/external/disassembler
vendored
Submodule lib/external/disassembler updated: 172c61ec3f...7235352627
2
lib/external/libromfs
vendored
2
lib/external/libromfs
vendored
Submodule lib/external/libromfs updated: 60ba28a53b...4f42f099b2
2
lib/external/libwolv
vendored
2
lib/external/libwolv
vendored
Submodule lib/external/libwolv updated: 323ad9e4f0...a50a748ce7
2
lib/external/pattern_language
vendored
2
lib/external/pattern_language
vendored
Submodule lib/external/pattern_language updated: 947b99cbe7...7a741cef11
@@ -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)
|
||||
|
||||
|
||||
51
lib/libimhex/include/hex.cppm
Normal file
51
lib/libimhex/include/hex.cppm
Normal 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>
|
||||
@@ -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
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)) { }
|
||||
|
||||
|
||||
@@ -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>);
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
};
|
||||
@@ -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 {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* that want to store any data to a Project File.
|
||||
*
|
||||
*/
|
||||
namespace hex {
|
||||
EXPORT_MODULE namespace hex {
|
||||
|
||||
namespace prv {
|
||||
class Provider;
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
|
||||
namespace hex {
|
||||
EXPORT_MODULE namespace hex {
|
||||
|
||||
class TutorialManager {
|
||||
public:
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
16
lib/libimhex/include/hex/helpers/clipboard.hpp
Normal file
16
lib/libimhex/include/hex/helpers/clipboard.hpp
Normal 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();
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <hex/helpers/fs.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
namespace hex::paths {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <string_view>
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/ranges.h>
|
||||
#include <fmt/ostream.h>
|
||||
|
||||
namespace hex {
|
||||
|
||||
|
||||
60
lib/libimhex/include/hex/helpers/freetype.hpp
Normal file
60
lib/libimhex/include/hex/helpers/freetype.hpp
Normal 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;
|
||||
};
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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() });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <wolv/io/file.hpp>
|
||||
#include <wolv/utils/guards.hpp>
|
||||
|
||||
namespace hex::log {
|
||||
EXPORT_MODULE namespace hex::log {
|
||||
|
||||
namespace impl {
|
||||
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace hex {
|
||||
EXPORT_MODULE namespace hex {
|
||||
|
||||
class SemanticVersion {
|
||||
public:
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
59
lib/libimhex/include/hex/helpers/udp_server.hpp
Normal file
59
lib/libimhex/include/hex/helpers/udp_server.hpp
Normal 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;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 ®ion) {
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
91
lib/libimhex/source/helpers/clipboard.cpp
Normal file
91
lib/libimhex/source/helpers/clipboard.cpp
Normal 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
|
||||
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
60
lib/libimhex/source/helpers/freetype.cpp
Normal file
60
lib/libimhex/source/helpers/freetype.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
239
lib/libimhex/source/helpers/keys.cpp
Normal file
239
lib/libimhex/source/helpers/keys.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 ";"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
69
lib/libimhex/source/helpers/udp_server.cpp
Normal file
69
lib/libimhex/source/helpers/udp_server.cpp
Normal 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 });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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, ¶mDesc);
|
||||
if (err != noErr) {
|
||||
NSLog(@"Failed to get parameter: %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
// Convert the AEDesc to NSData
|
||||
NSAppleEventDescriptor *descriptor = [[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:¶mDesc];
|
||||
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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
2
lib/third_party/capstone
vendored
2
lib/third_party/capstone
vendored
Submodule lib/third_party/capstone updated: 5cca00533d...accf4df62f
1
lib/third_party/clip
vendored
Submodule
1
lib/third_party/clip
vendored
Submodule
Submodule lib/third_party/clip added at 7a60eabaad
2
lib/third_party/edlib
vendored
2
lib/third_party/edlib
vendored
Submodule lib/third_party/edlib updated: 42aa8fa705...2a6d305917
2
lib/third_party/fmt
vendored
2
lib/third_party/fmt
vendored
Submodule lib/third_party/fmt updated: 8303d140a1...40626af88b
11
lib/third_party/imgui/CMakeLists.txt
vendored
11
lib/third_party/imgui/CMakeLists.txt
vendored
@@ -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
Reference in New Issue
Block a user