mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-28 15:57:03 -05:00
Compare commits
155 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
54b31b8a55 | ||
|
|
93aa1247df | ||
|
|
fb4c21b97a | ||
|
|
d356993e33 | ||
|
|
cf017540e2 | ||
|
|
c776bb6c03 | ||
|
|
e7399d223d | ||
|
|
8aff20b374 | ||
|
|
3b8b95a22f | ||
|
|
2cb65aac72 | ||
|
|
0c8deecfc5 | ||
|
|
74f17fd638 | ||
|
|
f3f13ae4d3 | ||
|
|
daffa4e555 | ||
|
|
c618eec843 | ||
|
|
71a7ae70d0 | ||
|
|
c1a2697e42 | ||
|
|
d4dd57c7c8 | ||
|
|
9e3c6898ad | ||
|
|
b6d7fd6984 | ||
|
|
d8eb027c94 | ||
|
|
80d47b658e | ||
|
|
51f2b24daa | ||
|
|
fe86f69da3 | ||
|
|
2fb51d1a56 | ||
|
|
ca3b5b72ca | ||
|
|
3db8e2aec2 | ||
|
|
499b68b7ad | ||
|
|
2e3bb8e555 | ||
|
|
0c9eab70d5 | ||
|
|
0d3eaa5d86 | ||
|
|
c20634e093 | ||
|
|
5ee3b550bc | ||
|
|
831dac9b47 | ||
|
|
626c34dce8 | ||
|
|
ed67c20cba | ||
|
|
35c209c791 | ||
|
|
315109aa1f | ||
|
|
a57fa34f82 | ||
|
|
d1a2f7d6ed | ||
|
|
8382f68601 | ||
|
|
3aa1dd1e06 | ||
|
|
0571fe383c | ||
|
|
461c5eac3e | ||
|
|
e34f94bb79 | ||
|
|
071bae345e | ||
|
|
9f4625aa00 | ||
|
|
9837473810 | ||
|
|
9d3759c6cd | ||
|
|
6aa55eb056 | ||
|
|
c8b7f350ad | ||
|
|
b6b5045340 | ||
|
|
ab4f17a6f4 | ||
|
|
541f1d5550 | ||
|
|
12942a4e71 | ||
|
|
1a378381bd | ||
|
|
1354c913a4 | ||
|
|
c752fba1c4 | ||
|
|
d40a445f33 | ||
|
|
e0cae1dacb | ||
|
|
31a746f3fc | ||
|
|
b401059678 | ||
|
|
a30f49c75e | ||
|
|
e981fa53f3 | ||
|
|
4cd390ab02 | ||
|
|
716d6ae850 | ||
|
|
ceb07b7425 | ||
|
|
4885175ac6 | ||
|
|
d0f1a40f16 | ||
|
|
fc20d751bb | ||
|
|
dfc22abf35 | ||
|
|
de269e7a48 | ||
|
|
0ed885fe0f | ||
|
|
f9fc7051fc | ||
|
|
ab1f4df9d9 | ||
|
|
710771b8b1 | ||
|
|
2d982e2088 | ||
|
|
ef5fbba56b | ||
|
|
eadcc6f38c | ||
|
|
3db50a690c | ||
|
|
96aa929c31 | ||
|
|
e07fc76abf | ||
|
|
f01e227c87 | ||
|
|
cd34d567a7 | ||
|
|
bb429aae62 | ||
|
|
19f99bab0c | ||
|
|
1f433fc36d | ||
|
|
034cc0cd2f | ||
|
|
3efdc02fed | ||
|
|
501d141e13 | ||
|
|
9c1006f3ae | ||
|
|
5b0813478e | ||
|
|
ac964dc5ec | ||
|
|
11c2f240a1 | ||
|
|
8db2bdb6a7 | ||
|
|
7242eb8f4c | ||
|
|
60c6abbfcc | ||
|
|
a4c432f435 | ||
|
|
d50be26771 | ||
|
|
673027c82d | ||
|
|
e02ccd9b9b | ||
|
|
956276d1ee | ||
|
|
a936cf1ce4 | ||
|
|
5800546369 | ||
|
|
01adc8a2cd | ||
|
|
b1b33b2ae4 | ||
|
|
6506291e4e | ||
|
|
3471b314dd | ||
|
|
546d0a4922 | ||
|
|
c6989c2ef7 | ||
|
|
a5aa002752 | ||
|
|
b89490bca3 | ||
|
|
e33726f526 | ||
|
|
c238767750 | ||
|
|
116aeede2d | ||
|
|
662d80abea | ||
|
|
f6ddb3c5e7 | ||
|
|
6490e565d3 | ||
|
|
6b7ade8d61 | ||
|
|
9b77d7b5e2 | ||
|
|
1785088456 | ||
|
|
4dcd26a21f | ||
|
|
12e99a9d4c | ||
|
|
5e67a1f27b | ||
|
|
2a76e45dc5 | ||
|
|
6266883e81 | ||
|
|
aed9d15625 | ||
|
|
5551e82fea | ||
|
|
653a688fe6 | ||
|
|
dfc1dc2529 | ||
|
|
1e511acf37 | ||
|
|
141ee62af9 | ||
|
|
a5d202ffc8 | ||
|
|
f243ac7464 | ||
|
|
91ac9ca120 | ||
|
|
a56ba50cf9 | ||
|
|
fdaad55cc6 | ||
|
|
9d19214be9 | ||
|
|
038a6b9757 | ||
|
|
bad109ef8d | ||
|
|
5623e1342b | ||
|
|
6bad50c78b | ||
|
|
6929ffb865 | ||
|
|
2d7fdc0896 | ||
|
|
d1d73bcff6 | ||
|
|
bf1441223c | ||
|
|
fadca9a34a | ||
|
|
2ef3a0c157 | ||
|
|
c96a0a7bda | ||
|
|
fe6be686b7 | ||
|
|
05862ae991 | ||
|
|
6a6b6b94cf | ||
|
|
4701b1b67c | ||
|
|
f1b2d5881e | ||
|
|
efed07ac8b |
30
.github/workflows/analysis.yml
vendored
30
.github/workflows/analysis.yml
vendored
@@ -3,11 +3,12 @@ name: "CodeQL"
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
codeql:
|
||||
name: 🐛 CodeQL
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
@@ -15,24 +16,30 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
|
||||
- name: ✋ Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: 'cpp'
|
||||
|
||||
- name: 📜 Restore cache
|
||||
uses: actions/cache@v2
|
||||
- name: 📜 Restore ccache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.ccache
|
||||
~/.cache/ccache
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build
|
||||
|
||||
- name: 📜 Restore CMakeCache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
build/CMakeCache.txt
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
|
||||
- name: ⬇️ Install dependencies
|
||||
run: |
|
||||
sudo apt update
|
||||
@@ -42,15 +49,16 @@ jobs:
|
||||
run: |
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=gcc-10 CXX=g++-10 cmake \
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCMAKE_INSTALL_PREFIX="$PWD/install" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
..
|
||||
make -j 4 install
|
||||
|
||||
- name: 🗯️ Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
uses: github/codeql-action/analyze@v2
|
||||
253
.github/workflows/build.yml
vendored
253
.github/workflows/build.yml
vendored
@@ -2,7 +2,9 @@ name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["*"]
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
@@ -22,11 +24,33 @@ jobs:
|
||||
CCACHE_COMPRESS: "true"
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
|
||||
- name: 📜 Prepare Cache
|
||||
id: prep-ccache
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p "${CCACHE_DIR}"
|
||||
echo "::set-output name=dir::$CCACHE_DIR"
|
||||
|
||||
- name: 📜 Restore ccache
|
||||
uses: actions/cache@v3
|
||||
id: cache-ccache
|
||||
with:
|
||||
path: |
|
||||
${{ steps.prep-ccache.outputs.dir }}
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build
|
||||
|
||||
- name: 📜 Restore CMakeCache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
build/CMakeCache.txt
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
- name: 🟦 Install msys2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
@@ -52,21 +76,6 @@ jobs:
|
||||
$USERPROFILE/.cargo/bin/rustup.exe target add x86_64-pc-windows-gnu
|
||||
$USERPROFILE/.cargo/bin/rustup.exe default nightly
|
||||
|
||||
- name: 📜 Prepare Cache
|
||||
id: prep-ccache
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p "${CCACHE_DIR}"
|
||||
echo "::set-output name=dir::$CCACHE_DIR"
|
||||
|
||||
- name: 📜 Restore Cache
|
||||
uses: actions/cache@v1
|
||||
id: cache-ccache
|
||||
with:
|
||||
path: ${{ steps.prep-ccache.outputs.dir }}
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
mkdir -p build
|
||||
@@ -84,20 +93,23 @@ jobs:
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
|
||||
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||
-DRUST_PATH="$USERPROFILE/.cargo/bin/" \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
..
|
||||
mingw32-make -j4 install
|
||||
cpack
|
||||
|
||||
- name: ⬆️ Upload Portable ZIP
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Windows Portable ZIP
|
||||
name: Windows Portable
|
||||
path: |
|
||||
build/install/*
|
||||
|
||||
- name: ⬆️ Upload Windows Installer
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Windows Installer
|
||||
path: |
|
||||
@@ -105,72 +117,90 @@ jobs:
|
||||
|
||||
# MacOS build
|
||||
macos:
|
||||
runs-on: macos-11.0
|
||||
runs-on: macos-11
|
||||
name: 🍎 macOS 11.0
|
||||
steps:
|
||||
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
|
||||
- name: 📜 Restore ccache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/Library/Caches/ccache
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build
|
||||
|
||||
|
||||
- name: 📜 Restore CMakeCache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
build/CMakeCache.txt
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
- name: ⬇️ Install dependencies
|
||||
run: |
|
||||
brew bundle --no-lock --file dist/Brewfile
|
||||
|
||||
- name: 📜 Restore cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.ccache
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=$(brew --prefix llvm)/bin/clang \
|
||||
CXX=$(brew --prefix llvm)/bin/clang++ \
|
||||
CC=$(brew --prefix gcc@12)/bin/gcc-12 \
|
||||
CXX=$(brew --prefix gcc@12)/bin/g++-12 \
|
||||
OBJC=$(brew --prefix llvm)/bin/clang \
|
||||
OBJCXX=$(brew --prefix llvm)/bin/clang++ \
|
||||
PKG_CONFIG_PATH="$(brew --prefix openssl)/lib/pkgconfig":"$(brew --prefix)/lib/pkgconfig" \
|
||||
MACOSX_DEPLOYMENT_TARGET="10.15" \
|
||||
cmake \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCREATE_BUNDLE=ON \
|
||||
-DCREATE_PACKAGE=ON \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
MACOSX_DEPLOYMENT_TARGET="10.15" \
|
||||
cmake \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCREATE_BUNDLE=ON \
|
||||
-DCREATE_PACKAGE=ON \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
..
|
||||
make -j4 package
|
||||
|
||||
- name: ⬆️ Upload DMG
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: macOS DMG
|
||||
path: build/*.dmg
|
||||
|
||||
# Linux build
|
||||
linux:
|
||||
runs-on: ubuntu-20.04
|
||||
name: 🐧 Ubuntu 20.04
|
||||
runs-on: ubuntu-22.04
|
||||
name: 🐧 Ubuntu 22.04
|
||||
steps:
|
||||
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
|
||||
- name: 📜 Restore cache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.ccache
|
||||
~/.cache/ccache
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build
|
||||
|
||||
- name: 📜 Restore other caches
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
build/CMakeCache.txt
|
||||
.flatpak-builder
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
|
||||
- name: ⬇️ Install dependencies
|
||||
run: |
|
||||
sudo rm -rf /usr/share/dotnet
|
||||
@@ -197,17 +227,24 @@ jobs:
|
||||
run: |
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=gcc-11 CXX=g++-11 cmake \
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
|
||||
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||
-DRUST_PATH="$HOME/.cargo/bin/" \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
..
|
||||
make -j 4 install DESTDIR=AppDir
|
||||
|
||||
- name: 📜 Set version variable
|
||||
run: |
|
||||
echo "IMHEX_VERSION=`cat VERSION`" >> $GITHUB_ENV
|
||||
|
||||
#- name: 📦 Bundle Flatpak
|
||||
# run: |
|
||||
# sudo apt install flatpak flatpak-builder
|
||||
@@ -217,45 +254,125 @@ jobs:
|
||||
# flatpak-builder --jobs=4 --repo=imhex _flatpak dist/net.werwolv.ImHex.yaml --ccache --keep-build-dirs
|
||||
# flatpak build-bundle imhex imhex.flatpak net.werwolv.ImHex stable
|
||||
|
||||
- name: ⬆️ Upload ELF
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Linux ELF
|
||||
path: |
|
||||
build/AppDir/*
|
||||
|
||||
- name: 📦 Bundle DEB
|
||||
run: |
|
||||
cp -r build/DEBIAN build/AppDir
|
||||
dpkg-deb --build build/AppDir
|
||||
mv build/AppDir.deb imhex.deb
|
||||
mv build/AppDir.deb imhex-${{env.IMHEX_VERSION}}.deb
|
||||
rm -rf build/AppDir/DEBIAN
|
||||
|
||||
- name: 📦 Bundle AppImage
|
||||
run: |
|
||||
cd build
|
||||
appimage-builder --recipe ../dist/AppImageBuilder.yml
|
||||
mv ImHex-AppImage-x86_64.AppImage ../imhex.AppImage
|
||||
mv ImHex-AppImage-x86_64.AppImage ../imhex-${{env.IMHEX_VERSION}}.AppImage
|
||||
cd ..
|
||||
|
||||
#- name: ⬆️ Upload Flatpak
|
||||
# uses: actions/upload-artifact@v2
|
||||
# uses: actions/upload-artifact@v3
|
||||
# with:
|
||||
# name: Linux Flatpak
|
||||
# path: |
|
||||
# imhex.flatpak
|
||||
|
||||
- name: ⬆️ Upload DEB
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Linux DEB
|
||||
path: |
|
||||
imhex.deb
|
||||
name: Linux DEB (Ubuntu 22.04)
|
||||
path: '*.deb'
|
||||
|
||||
- name: ⬆️ Upload AppImage
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Linux AppImage
|
||||
path: |
|
||||
imhex.AppImage
|
||||
path: '*.AppImage'
|
||||
|
||||
archlinux-build:
|
||||
name: 🐧 ArchLinux
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
container:
|
||||
image: archlinux:base-devel
|
||||
|
||||
steps:
|
||||
- name: ⬇️ Update all packages
|
||||
run: |
|
||||
pacman -Syyu --noconfirm
|
||||
|
||||
- name: ⬇️ Install setup dependencies
|
||||
run: |
|
||||
pacman -Syu git ccache --noconfirm
|
||||
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: ⬇️ Install ImHex dependencies
|
||||
run: |
|
||||
dist/get_deps_archlinux.sh --noconfirm
|
||||
|
||||
- name: 📜 Restore ccache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.cache/ccache
|
||||
key: archlinux-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: archlinux-${{ secrets.CACHE_VERSION }}-build
|
||||
|
||||
- name: 📜 Restore CMakeCache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
build/CMakeCache.txt
|
||||
key: archlinux-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=gcc CXX=g++ cmake \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
|
||||
-DRUST_PATH="$HOME/.cargo/bin/" \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
..
|
||||
make -j 4 install DESTDIR=installDir
|
||||
|
||||
- name: 📜 Set version variable
|
||||
run: |
|
||||
echo "IMHEX_VERSION=`cat VERSION`" >> $GITHUB_ENV
|
||||
|
||||
- name: ✒️ Prepare PKGBUILD
|
||||
run: |
|
||||
cp dist/Arch/PKGBUILD build
|
||||
sed -i 's/%version%/${{env.IMHEX_VERSION}}/g' build/PKGBUILD
|
||||
|
||||
# makepkg doesn't want to run as root, so I had to chmod 777 all over
|
||||
- name: 📦 Package ArchLinux .pkg.tar.zst
|
||||
run: |
|
||||
cd build
|
||||
|
||||
# the name is a small trick to make makepkg recognize it as the source
|
||||
# else, it would try to download the file from the release
|
||||
tar -cvf imhex-${{env.IMHEX_VERSION}}-ArchLinux.pkg.tar.zst -C installDir .
|
||||
|
||||
chmod -R 777 .
|
||||
|
||||
sudo -u nobody makepkg
|
||||
|
||||
# Remplace the old file
|
||||
rm imhex-${{env.IMHEX_VERSION}}-ArchLinux.pkg.tar.zst
|
||||
mv *.pkg.tar.zst imhex-${{env.IMHEX_VERSION}}-ArchLinux.pkg.tar.zst
|
||||
|
||||
- name: ⬆️ Upload imhex-archlinux.pkg.tar.zst
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ArchLinux .pkg.tar.zst
|
||||
path: |
|
||||
build/imhex-${{env.IMHEX_VERSION}}-ArchLinux.pkg.tar.zst
|
||||
|
||||
|
||||
112
.github/workflows/release.yml
vendored
Normal file
112
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
name: Release
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
name: Release
|
||||
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: ImHex
|
||||
submodules: recursive
|
||||
|
||||
- name: 📜 Verify version and set version variable
|
||||
run: |
|
||||
project_version=`cat ImHex/VERSION`
|
||||
tag_version="${{github.event.release.tag_name}}"
|
||||
tag_version="${tag_version:1}"
|
||||
if [ "$project_version" != "$tag_version" ]; then
|
||||
echo "::warning::$project_version and $tag_version are not the same ! Refusing to populate release"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "IMHEX_VERSION=$project_version" >> $GITHUB_ENV
|
||||
|
||||
- name: 🗜️ Create tarball from sources with dependencies
|
||||
run: tar --exclude-vcs -czvf Full.Sources.tar.gz ImHex
|
||||
|
||||
- name: ⬇️ Download artifacts from latest workflow
|
||||
uses: dawidd6/action-download-artifact@v2
|
||||
with:
|
||||
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||
workflow: build.yml
|
||||
branch: ${{ github.event.release.target_commitish }}
|
||||
workflow_conclusion: success
|
||||
skip_unpack: true
|
||||
|
||||
- name: 🗜️ Unzip files when needed
|
||||
run: |
|
||||
for zipfile in ./*.zip
|
||||
do
|
||||
if [ `zipinfo -1 "$zipfile" | wc -l` -eq 1 ];
|
||||
then
|
||||
echo "unzipping $zipfile"
|
||||
unzip "$zipfile"
|
||||
rm "$zipfile"
|
||||
else
|
||||
echo "keeping $zipfile zipped"
|
||||
fi
|
||||
done
|
||||
|
||||
- name: 🟩 Rename Windows Portable Zip
|
||||
run: mv "Windows Portable.zip" imhex-${{env.IMHEX_VERSION}}-Windows-Portable.zip
|
||||
|
||||
- name: ⬆️ Upload everything to release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
files: '*'
|
||||
|
||||
- name: ✒️ Prepare PKGBUILD
|
||||
run: |
|
||||
cp ImHex/dist/Arch/PKGBUILD .
|
||||
|
||||
hash=`md5sum imhex-${{env.IMHEX_VERSION}}-ArchLinux.pkg.tar.zst | cut -d ' ' -f 1`
|
||||
|
||||
sed -i 's/%version%/${{env.IMHEX_VERSION}}/g' PKGBUILD
|
||||
sed -i "s/(SKIP)/($hash)/g" PKGBUILD
|
||||
|
||||
- name: ⬆️ Publish AUR package
|
||||
|
||||
# I couldn't make the condition in the env directly for some reason
|
||||
env:
|
||||
AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
|
||||
if: "${{ env.AUR_SSH_PRIVATE_KEY != '' }}"
|
||||
|
||||
uses: KSXGitHub/github-actions-deploy-aur@v2
|
||||
with:
|
||||
pkgname: imhex-bin
|
||||
pkgbuild: ./PKGBUILD
|
||||
commit_username: iTrooz
|
||||
commit_email: itrooz@protonmail.com
|
||||
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
|
||||
commit_message: Bump to version ${{env.IMHEX_VERSION}}
|
||||
ssh_keyscan_types: rsa,dsa,ecdsa,ed25519
|
||||
|
||||
- name: 🎫 Create PatternLanguage release
|
||||
uses: ncipollo/release-action@v1
|
||||
env:
|
||||
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
if: "${{ env.RELEASE_TOKEN != '' }}"
|
||||
with:
|
||||
tag: ImHex-v${{env.IMHEX_VERSION}}
|
||||
repo: PatternLanguage
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
|
||||
- name: 🎫 Create ImHex-Patterns release
|
||||
uses: ncipollo/release-action@v1
|
||||
env:
|
||||
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
if: "${{ env.RELEASE_TOKEN != '' }}"
|
||||
with:
|
||||
tag: ImHex-v${{env.IMHEX_VERSION}}
|
||||
repo: ImHex-Patterns
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
27
.github/workflows/tests.yml
vendored
27
.github/workflows/tests.yml
vendored
@@ -5,11 +5,12 @@ on:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
name: 🧪 Unit Tests
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
@@ -17,19 +18,26 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
|
||||
- name: 📜 Restore cache
|
||||
uses: actions/cache@v2
|
||||
- name: 📜 Restore ccache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.ccache
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
~/.cache/ccache
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build
|
||||
|
||||
|
||||
- name: 📜 Restore CMakeCache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
build/CMakeCache.txt
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
- name: ⬇️ Install dependencies
|
||||
run: |
|
||||
sudo apt update
|
||||
@@ -39,13 +47,14 @@ jobs:
|
||||
run: |
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=gcc-10 CXX=g++-10 cmake \
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCMAKE_INSTALL_PREFIX="$PWD/install" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
..
|
||||
make -j4 unit_tests install
|
||||
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# Updating the version here will update it throughout ImHex as well
|
||||
set(IMHEX_VERSION "1.18.1")
|
||||
file(READ "VERSION" IMHEX_VERSION)
|
||||
project(imhex VERSION ${IMHEX_VERSION})
|
||||
message("Project version ${IMHEX_VERSION}")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
set(IMHEX_BASE_FOLDER ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set(CMAKE_MODULE_PATH "${IMHEX_BASE_FOLDER}/cmake/modules")
|
||||
include("${IMHEX_BASE_FOLDER}/cmake/build_helpers.cmake")
|
||||
|
||||
option(IMHEX_OFFLINE_BUILD "Enable offline build" OFF)
|
||||
option(IMHEX_PATTERNS_PULL_MASTER "Download latest files from master branch of the ImHex-Patterns repo" OFF)
|
||||
|
||||
# Make sure project is configured correctly
|
||||
setDefaultBuiltTypeIfUnset()
|
||||
detectBadClone()
|
||||
@@ -36,6 +40,3 @@ add_subdirectory(tests EXCLUDE_FROM_ALL)
|
||||
|
||||
# Configure packaging
|
||||
createPackage()
|
||||
|
||||
# Download and install all current files from the ImHex-Patterns repo
|
||||
downloadImHexPatternsFiles()
|
||||
|
||||
96
README.md
96
README.md
@@ -122,108 +122,22 @@ To develop plugins for ImHex, use one of the following two templates projects to
|
||||
Nightlies are available via GitHub Actions [here](https://github.com/WerWolv/ImHex/actions?query=workflow%3ABuild).
|
||||
|
||||
- Windows • __x86_64__
|
||||
- [MSI](https://nightly.link/WerWolv/ImHex/workflows/build/master/Windows%20Installer.zip)
|
||||
- [EXE](https://nightly.link/WerWolv/ImHex/workflows/build/master/Windows%20Portable%20ZIP.zip)
|
||||
- [Installer](https://nightly.link/WerWolv/ImHex/workflows/build/master/Windows%20Installer.zip)
|
||||
- [Portable](https://nightly.link/WerWolv/ImHex/workflows/build/master/Windows%20Portable%20ZIP.zip)
|
||||
- MacOS • __x86_64__
|
||||
- [DMG](https://nightly.link/WerWolv/ImHex/workflows/build/master/macOS%20DMG.zip)
|
||||
- Linux • __x86_64__
|
||||
- [ELF](https://nightly.link/WerWolv/ImHex/workflows/build/master/Linux%20ELF.zip)
|
||||
- [DEB](https://nightly.link/WerWolv/ImHex/workflows/build/master/Linux%20DEB.zip)
|
||||
- [Flatpak](https://nightly.link/WerWolv/ImHex/workflows/build/master/Linux%20Flatpak.zip)
|
||||
- [AppImage](https://nightly.link/WerWolv/ImHex/workflows/build/master/Linux%20AppImage.zip)
|
||||
- [Arch Package](https://nightly.link/WerWolv/ImHex/workflows/build/master/ArchLinux%20.pkg.tar.zst.zip)
|
||||
|
||||
## Compiling
|
||||
|
||||
You need a C++20 compatible compiler such as GCC 10.2.0 to compile ImHex.
|
||||
To compile ImHex, a C++20 compiler is required. Releases are all mainly built using GCC, however on macOS, clang is also required to compile some ObjC code.
|
||||
|
||||
Many dependencies are bundled into the repository using submodules so make sure to clone it using the `--recurse-submodules` option.
|
||||
All dependencies that aren't bundled, can be installed using the dependency installer scripts found in the `/dist` folder.
|
||||
|
||||
For working examples
|
||||
|
||||
### Windows
|
||||
|
||||
On Windows, ImHex is built through msys2 / mingw. To install all dependencies, open a mys2 window and run the PKGCONFIG script in the [dist/msys2](dist/msys2) folder.
|
||||
After all the dependencies are installed, run the following commands to build ImHex:
|
||||
|
||||
```sh
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||
make -j
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
To create a standalone zipfile on Windows, get the Python standard library (e.g. from https://github.com/python/cpython/tree/master/Lib) and place the files and folders in `lib/python3.8` next to your built executable. Don't forget to also copy the `libpython3.8.dll` and `libwinpthread-1.dll` from your mingw setup next to the executable.
|
||||
|
||||
- Copy the files inside the `/resources/lib/python` folder into the `lib` folder next to your built executable.
|
||||
- Place your magic databases in the `magic` folder next to your built executable
|
||||
- Place your patterns in the `pattern` folder next to your built executable
|
||||
- Place your include pattern files in the `include` folder next to your built executable
|
||||
|
||||
### macOS
|
||||
|
||||
To build ImHex on macOS, run the following commands:
|
||||
|
||||
```sh
|
||||
brew bundle --no-lock --file dist/Brewfile
|
||||
mkdir build
|
||||
cd build
|
||||
CC=$(brew --prefix llvm)/bin/clang CXX=$(brew --prefix llvm)/bin/clang++ PKG_CONFIG_PATH="$(brew --prefix openssl)/lib/pkgconfig":"$(brew --prefix)/lib/pkgconfig" cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||
make -j
|
||||
```
|
||||
|
||||
Install the ImHex executable as well as libimhex.dylib to wherever ImHex should be installed.
|
||||
|
||||
All other files belong in `~/Library/Application Support/imhex`:
|
||||
```
|
||||
Patterns: ~/Library/Application Support/imhex/patterns
|
||||
Pattern Includes: ~/Library/Application Support/imhex/includes
|
||||
Magic files: ~/Library/Application Support/imhex/magic
|
||||
Python: ~/Library/Application Support/imhex/lib/pythonX.X
|
||||
Plugins: ~/Library/Application Support/imhex/plugins
|
||||
Configuration: ~/Library/Application Support/imhex/config
|
||||
Resources: ~/Library/Application Support/imhex/resources
|
||||
```
|
||||
|
||||
If the build fails while trying to find the macOS libraries, make sure you have
|
||||
XCode installed with `xcode-select --install`. Homebrew will also help get the
|
||||
most recent SDK installed and configured with `brew doctor`.
|
||||
|
||||
### Linux
|
||||
|
||||
Dependency installation scripts are available for many common Linux distributions in the [/dist](dist) folder.
|
||||
After all the dependencies are installed, run the following commands to build ImHex:
|
||||
|
||||
```sh
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||
make -j
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Put the ImHex executable into the `/usr/bin` folder.
|
||||
Put libimhex.so into the `/usr/lib` folder.
|
||||
Configuration files go to `/etc/xdg/imhex` or `~/.config/imhex`.
|
||||
All other files belong in `/usr/share/imhex` or `~/.local/share/imhex`:
|
||||
|
||||
```
|
||||
Patterns: /usr/share/imhex/patterns
|
||||
Pattern Includes: /usr/share/imhex/includes
|
||||
Magic files: /usr/share/imhex/magic
|
||||
Python: /usr/share/imhex/lib/pythonX.X
|
||||
Plugins: /usr/share/imhex/plugins
|
||||
Configuration: /etc/xdg/imhex/config
|
||||
Resources: /usr/share/imhex/resources
|
||||
```
|
||||
|
||||
All paths follow the XDG Base Directories standard, and can thus be modified
|
||||
with the environment variables `XDG_CONFIG_HOME`, `XDG_CONFIG_DIRS`,
|
||||
`XDG_DATA_HOME` and `XDG_DATA_DIRS`.
|
||||
|
||||
## Credits
|
||||
|
||||
### Contributors
|
||||
@@ -231,6 +145,8 @@ with the environment variables `XDG_CONFIG_HOME`, `XDG_CONFIG_DIRS`,
|
||||
- [Mary](https://github.com/Thog) for her immense help porting ImHex to MacOS and help during development
|
||||
- [Roblabla](https://github.com/Roblabla) for adding MSI Installer support to ImHex
|
||||
- [jam1garner](https://github.com/jam1garner) and [raytwo](https://github.com/raytwo) for their help with adding Rust support to plugins
|
||||
- [Mailaender](https://github.com/Mailaender) for getting ImHex onto Flathub
|
||||
- [iTrooz](https://github.com/iTrooz) for many improvements related to release packaging and the GitHub Action runners.
|
||||
- Everybody else who has reported issues on Discord or GitHub that I had great conversations with :)
|
||||
|
||||
### Libraries
|
||||
|
||||
@@ -70,19 +70,18 @@ macro(detectOS)
|
||||
set(CMAKE_INSTALL_BINDIR ".")
|
||||
set(CMAKE_INSTALL_LIBDIR ".")
|
||||
set(PLUGINS_INSTALL_LOCATION "plugins")
|
||||
set(MAGIC_INSTALL_LOCATION "magic")
|
||||
elseif (APPLE)
|
||||
add_compile_definitions(OS_MACOS)
|
||||
set(CMAKE_INSTALL_BINDIR ".")
|
||||
set(CMAKE_INSTALL_LIBDIR ".")
|
||||
set(PLUGINS_INSTALL_LOCATION "plugins")
|
||||
set(MAGIC_INSTALL_LOCATION "magic")
|
||||
enable_language(OBJC)
|
||||
enable_language(OBJCXX)
|
||||
elseif (UNIX AND NOT APPLE)
|
||||
add_compile_definitions(OS_LINUX)
|
||||
set(CMAKE_INSTALL_BINDIR "bin")
|
||||
set(CMAKE_INSTALL_LIBDIR "lib")
|
||||
set(PLUGINS_INSTALL_LOCATION "share/imhex/plugins")
|
||||
set(MAGIC_INSTALL_LOCATION "share/imhex/magic")
|
||||
else ()
|
||||
message(FATAL_ERROR "Unknown / unsupported system!")
|
||||
endif()
|
||||
@@ -133,14 +132,14 @@ macro(configurePackingResources)
|
||||
set(MACOSX_BUNDLE_INFO_STRING "WerWolv")
|
||||
set(MACOSX_BUNDLE_BUNDLE_NAME "ImHex")
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER "WerWolv.ImHex")
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER "net.WerWolv.ImHex")
|
||||
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_VERSION}-${GIT_COMMIT_HASH}")
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}")
|
||||
set(MACOSX_BUNDLE_COPYRIGHT "Copyright © 2020 WerWolv and Thog. All rights reserved." )
|
||||
if ("${CMAKE_GENERATOR}" STREQUAL "Xcode")
|
||||
set ( bundle_path "${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/imhex.app" )
|
||||
set ( bundle_path "${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/ImHex.app" )
|
||||
else ()
|
||||
set ( bundle_path "${CMAKE_BINARY_DIR}/imhex.app" )
|
||||
set ( bundle_path "${CMAKE_BINARY_DIR}/ImHex.app" )
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
@@ -151,11 +150,11 @@ macro(createPackage)
|
||||
foreach (plugin IN LISTS PLUGINS)
|
||||
add_subdirectory("plugins/${plugin}")
|
||||
if (TARGET ${plugin})
|
||||
set_target_properties(${plugin} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins)
|
||||
set_target_properties(${plugin} PROPERTIES CARGO_BUILD_TARGET_DIR ${CMAKE_BINARY_DIR}/plugins)
|
||||
|
||||
get_target_property(IS_RUST_PROJECT ${plugin} RUST_PROJECT)
|
||||
|
||||
set_target_properties(${plugin} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins)
|
||||
set_target_properties(${plugin} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins)
|
||||
|
||||
if (IS_RUST_PROJECT)
|
||||
set_target_properties(${plugin} PROPERTIES CARGO_BUILD_TARGET_DIR ${CMAKE_BINARY_DIR}/plugins)
|
||||
|
||||
@@ -163,7 +162,6 @@ macro(createPackage)
|
||||
|
||||
install(FILES "${PLUGIN_LOCATION}/../${plugin}.hexplug" DESTINATION "${PLUGINS_INSTALL_LOCATION}")
|
||||
else ()
|
||||
set_target_properties(${plugin} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins)
|
||||
if (WIN32)
|
||||
install(TARGETS ${plugin} RUNTIME DESTINATION ${PLUGINS_INSTALL_LOCATION})
|
||||
elseif (APPLE)
|
||||
@@ -181,7 +179,6 @@ macro(createPackage)
|
||||
endif ()
|
||||
endforeach()
|
||||
|
||||
install(FILES "$<TARGET_FILE:libimhex>" DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
||||
set_target_properties(libimhex PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
if (WIN32)
|
||||
@@ -218,12 +215,20 @@ macro(createPackage)
|
||||
)
|
||||
endforeach()
|
||||
]])
|
||||
|
||||
install(FILES "$<TARGET_FILE:libimhex>" DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
||||
downloadImHexPatternsFiles("./")
|
||||
elseif(UNIX AND NOT APPLE)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/dist/DEBIAN/control.in ${CMAKE_BINARY_DIR}/DEBIAN/control)
|
||||
|
||||
configure_file(${CMAKE_SOURCE_DIR}/dist/DEBIAN/control.in ${CMAKE_BINARY_DIR}/DEBIAN/control)
|
||||
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION ${CMAKE_INSTALL_PREFIX}/share/licenses/imhex)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/dist/imhex.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/resources/icon.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/pixmaps RENAME imhex.png)
|
||||
install(FILES "$<TARGET_FILE:libimhex>" DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
||||
downloadImHexPatternsFiles("./share/imhex")
|
||||
endif()
|
||||
|
||||
|
||||
if (CREATE_BUNDLE)
|
||||
include(PostprocessBundle)
|
||||
|
||||
@@ -234,20 +239,21 @@ macro(createPackage)
|
||||
add_custom_target(build-time-make-plugins-directory ALL COMMAND ${CMAKE_COMMAND} -E make_directory "${bundle_path}/Contents/MacOS/plugins")
|
||||
add_custom_target(build-time-make-resources-directory ALL COMMAND ${CMAKE_COMMAND} -E make_directory "${bundle_path}/Contents/Resources")
|
||||
|
||||
downloadImHexPatternsFiles("${bundle_path}/Contents/MacOS")
|
||||
|
||||
install(FILES ${IMHEX_ICON} DESTINATION "${bundle_path}/Contents/Resources")
|
||||
install(TARGETS main BUNDLE DESTINATION ".")
|
||||
install(FILES $<TARGET_FILE:main> DESTINATION "${bundle_path}")
|
||||
|
||||
# Update library references to make the bundle portable
|
||||
postprocess_bundle(imhex_all main)
|
||||
|
||||
# Enforce DragNDrop packaging.
|
||||
set(CPACK_GENERATOR "DragNDrop")
|
||||
|
||||
install(TARGETS main BUNDLE DESTINATION .)
|
||||
else()
|
||||
install(TARGETS main RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
endif()
|
||||
|
||||
|
||||
if (CREATE_PACKAGE)
|
||||
include(apple)
|
||||
include(CPack)
|
||||
@@ -283,18 +289,26 @@ macro(detectBadClone)
|
||||
endmacro()
|
||||
|
||||
|
||||
function(downloadImHexPatternsFiles)
|
||||
FetchContent_Declare(
|
||||
imhex_patterns
|
||||
GIT_REPOSITORY https://github.com/WerWolv/ImHex-Patterns.git
|
||||
GIT_TAG master
|
||||
)
|
||||
function(downloadImHexPatternsFiles dest)
|
||||
if (NOT IMHEX_OFFLINE_BUILD)
|
||||
if (IMHEX_PATTERNS_PULL_MASTER)
|
||||
set(PATTERNS_BRANCH master)
|
||||
else ()
|
||||
set(PATTERNS_BRANCH ImHex-v${IMHEX_VERSION})
|
||||
endif ()
|
||||
|
||||
FetchContent_Populate(imhex_patterns)
|
||||
FetchContent_Declare(
|
||||
imhex_patterns
|
||||
GIT_REPOSITORY https://github.com/WerWolv/ImHex-Patterns.git
|
||||
GIT_TAG master
|
||||
)
|
||||
|
||||
set(PATTERNS_FOLDERS_TO_INSTALL constants encodings includes patterns magic)
|
||||
foreach (FOLDER ${PATTERNS_FOLDERS_TO_INSTALL})
|
||||
install(DIRECTORY "${imhex_patterns_SOURCE_DIR}/${FOLDER}" DESTINATION "./")
|
||||
endforeach()
|
||||
FetchContent_Populate(imhex_patterns)
|
||||
|
||||
set(PATTERNS_FOLDERS_TO_INSTALL constants encodings includes patterns magic)
|
||||
foreach (FOLDER ${PATTERNS_FOLDERS_TO_INSTALL})
|
||||
install(DIRECTORY "${imhex_patterns_SOURCE_DIR}/${FOLDER}" DESTINATION ${dest})
|
||||
endforeach ()
|
||||
endif ()
|
||||
|
||||
endfunction()
|
||||
65
dist/AppImageBuilder.yml
vendored
65
dist/AppImageBuilder.yml
vendored
@@ -1,21 +1,7 @@
|
||||
# appimage-builder recipe see https://appimage-builder.readthedocs.io for details
|
||||
version: 1
|
||||
script:
|
||||
- rm -rf AppDir | true
|
||||
- CC=gcc-11 CXX=g++11 cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
|
||||
- make -j3 install DESTDIR=AppDir
|
||||
- mv AppDir/usr/share/imhex/plugins AppDir/usr/bin/plugins
|
||||
- mv AppDir/usr/constants AppDir/usr/bin/constants
|
||||
- mv AppDir/usr/encodings AppDir/usr/bin/encodings
|
||||
- mv AppDir/usr/includes AppDir/usr/bin/includes
|
||||
- mv AppDir/usr/magic AppDir/usr/bin/magic
|
||||
- mv AppDir/usr/patterns AppDir/usr/bin/patterns
|
||||
- mkdir -p AppDir/usr/share/icons/hicolor/512x512
|
||||
- cp AppDir/usr/share/pixmaps/imhex.png AppDir/usr/share/icons/hicolor/512x512/imhex.png
|
||||
|
||||
|
||||
AppDir:
|
||||
path: ./AppDir
|
||||
path: .AppDir
|
||||
app_info:
|
||||
id: imhex
|
||||
name: ImHex
|
||||
@@ -28,18 +14,19 @@ AppDir:
|
||||
- amd64
|
||||
allow_unauthenticated: true
|
||||
sources:
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ impish main restricted
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ impish-updates main restricted
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ impish universe
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ impish-updates universe
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ impish multiverse
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ impish-updates multiverse
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ impish-backports main restricted
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ jammy main restricted
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ jammy-updates main restricted
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ jammy universe
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ jammy-updates universe
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ jammy multiverse
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ jammy-updates multiverse
|
||||
- sourceline: deb http://.archive.ubuntu.com/ubuntu/ jammy-backports main restricted
|
||||
universe multiverse
|
||||
- sourceline: deb http://security.ubuntu.com/ubuntu impish-security main restricted
|
||||
- sourceline: deb http://security.ubuntu.com/ubuntu impish-security universe
|
||||
- sourceline: deb http://security.ubuntu.com/ubuntu impish-security multiverse
|
||||
- sourceline: deb http://security.ubuntu.com/ubuntu jammy-security main restricted
|
||||
- sourceline: deb http://security.ubuntu.com/ubuntu jammy-security universe
|
||||
- sourceline: deb http://security.ubuntu.com/ubuntu jammy-security multiverse
|
||||
include:
|
||||
- librsvg2-common
|
||||
- libbz2-1.0:amd64
|
||||
- libcap2:amd64
|
||||
- libdbus-1-3:amd64
|
||||
@@ -53,7 +40,7 @@ AppDir:
|
||||
include:
|
||||
- /lib/x86_64-linux-gnu/libGLX.so.0
|
||||
- /lib/x86_64-linux-gnu/libGLdispatch.so.0
|
||||
- /lib/x86_64-linux-gnu/libLLVM-12.so.1
|
||||
- /lib/x86_64-linux-gnu/libLLVM-13.so.1
|
||||
- /lib/x86_64-linux-gnu/libOpenGL.so.0
|
||||
- /lib/x86_64-linux-gnu/libX11.so.6
|
||||
- /lib/x86_64-linux-gnu/libXau.so.6
|
||||
@@ -81,7 +68,7 @@ AppDir:
|
||||
- /lib/x86_64-linux-gnu/libedit.so.2
|
||||
- /lib/x86_64-linux-gnu/libelf.so.1
|
||||
- /lib/x86_64-linux-gnu/libepoxy.so.0
|
||||
- /lib/x86_64-linux-gnu/libffi.so.7
|
||||
- /lib/x86_64-linux-gnu/libffi.so.8
|
||||
- /lib/x86_64-linux-gnu/libfontconfig.so.1
|
||||
- /lib/x86_64-linux-gnu/libfreetype.so.6
|
||||
- /lib/x86_64-linux-gnu/libfribidi.so.0
|
||||
@@ -93,31 +80,41 @@ AppDir:
|
||||
- /lib/x86_64-linux-gnu/libglfw.so.3
|
||||
- /lib/x86_64-linux-gnu/libglib-2.0.so.0
|
||||
- /lib/x86_64-linux-gnu/libgmodule-2.0.so.0
|
||||
- /lib/x86_64-linux-gnu/libgmp.so.10
|
||||
- /lib/x86_64-linux-gnu/libgnutls.so.30
|
||||
- /lib/x86_64-linux-gnu/libgobject-2.0.so.0
|
||||
- /lib/x86_64-linux-gnu/libgraphite2.so.3
|
||||
- /lib/x86_64-linux-gnu/libgtk-3.so.0
|
||||
- /lib/x86_64-linux-gnu/libharfbuzz.so.0
|
||||
- /lib/x86_64-linux-gnu/libicudata.so.66
|
||||
- /lib/x86_64-linux-gnu/libicuuc.so.66
|
||||
- /lib/x86_64-linux-gnu/libhogweed.so.6
|
||||
- /lib/x86_64-linux-gnu/libicudata.so.70
|
||||
- /lib/x86_64-linux-gnu/libicuuc.so.70
|
||||
- /lib/x86_64-linux-gnu/libidn2.so.0
|
||||
- /lib/x86_64-linux-gnu/libjpeg.so.8
|
||||
- /lib/x86_64-linux-gnu/liblber-2.5.so.0
|
||||
- /lib/x86_64-linux-gnu/libldap-2.5.so.0
|
||||
- /lib/x86_64-linux-gnu/liblz4.so.1
|
||||
- /lib/x86_64-linux-gnu/libmagic.so.1
|
||||
- /lib/x86_64-linux-gnu/libmbedcrypto.so.3
|
||||
- /lib/x86_64-linux-gnu/libmbedtls.so.12
|
||||
- /lib/x86_64-linux-gnu/libmbedx509.so.0
|
||||
- /lib/x86_64-linux-gnu/libmbedcrypto.so.7
|
||||
- /lib/x86_64-linux-gnu/libmbedtls.so.14
|
||||
- /lib/x86_64-linux-gnu/libmbedx509.so.1
|
||||
- /lib/x86_64-linux-gnu/libmd.so.0
|
||||
- /lib/x86_64-linux-gnu/libmount.so.1
|
||||
- /lib/x86_64-linux-gnu/libnettle.so.8
|
||||
- /lib/x86_64-linux-gnu/libp11-kit.so.0
|
||||
- /lib/x86_64-linux-gnu/libpango-1.0.so.0
|
||||
- /lib/x86_64-linux-gnu/libpangocairo-1.0.so.0
|
||||
- /lib/x86_64-linux-gnu/libpangoft2-1.0.so.0
|
||||
- /lib/x86_64-linux-gnu/libpcre2-8.so.0
|
||||
- /lib/x86_64-linux-gnu/libpixman-1.so.0
|
||||
- /lib/x86_64-linux-gnu/libpng16.so.16
|
||||
- /lib/x86_64-linux-gnu/libpython3.8.so.1.0
|
||||
- /lib/x86_64-linux-gnu/libpython3.10.so.1.0
|
||||
- /lib/x86_64-linux-gnu/libsasl2.so.2
|
||||
- /lib/x86_64-linux-gnu/libsensors.so.5
|
||||
- /lib/x86_64-linux-gnu/libstdc++.so.6
|
||||
- /lib/x86_64-linux-gnu/libsystemd.so.0
|
||||
- /lib/x86_64-linux-gnu/libtasn1.so.6
|
||||
- /lib/x86_64-linux-gnu/libthai.so.0
|
||||
- /lib/x86_64-linux-gnu/libunistring.so.2
|
||||
- /lib/x86_64-linux-gnu/libuuid.so.1
|
||||
- /lib/x86_64-linux-gnu/libvulkan.so.1
|
||||
- /lib/x86_64-linux-gnu/libwayland-client.so.0
|
||||
|
||||
39
dist/Arch/PKGBUILD
vendored
Normal file
39
dist/Arch/PKGBUILD
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
# Maintainer: iTrooz_ <itrooz at protonmail dot com>
|
||||
pkgname=imhex-bin
|
||||
pkgver=%version%
|
||||
pkgrel=1
|
||||
pkgdesc="A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM. "
|
||||
arch=("x86_64")
|
||||
url="https://github.com/WerWolv/ImHex"
|
||||
repo=$url
|
||||
license=('GPL 2.0')
|
||||
groups=()
|
||||
depends=(glfw mbedtls python freetype2 libglvnd dbus xdg-desktop-portal)
|
||||
makedepends=(git)
|
||||
checkdepends=()
|
||||
optdepends=()
|
||||
provides=(imhex)
|
||||
conflicts=(imhex)
|
||||
replaces=()
|
||||
backup=()
|
||||
options=()
|
||||
source=($repo"/releases/download/v$pkgver/imhex-$pkgver-ArchLinux.pkg.tar.zst")
|
||||
noextract=()
|
||||
md5sums=(SKIP)
|
||||
validpgpkeys=()
|
||||
|
||||
package() {
|
||||
tar -xf imhex-$pkgver-ArchLinux.pkg.tar.zst
|
||||
|
||||
install -DT $srcdir/usr/bin/imhex $pkgdir/usr/bin/imhex
|
||||
install -DT $srcdir/usr/lib/libimhex.so $pkgdir/usr/lib/libimhex.so
|
||||
|
||||
for plugin in $srcdir/usr/share/imhex/plugins/*.hexplug;
|
||||
do
|
||||
install -DT $plugin $pkgdir/usr/share/imhex/plugins/`basename $plugin`
|
||||
done
|
||||
|
||||
cp -r $srcdir/usr/share/imhex/{constants,encodings,includes,magic,patterns} $pkgdir/usr/share/imhex
|
||||
cp -r $srcdir/usr/share/{applications,licenses} $pkgdir/usr/share
|
||||
install -d $pkgdir/usr/share
|
||||
}
|
||||
4
dist/Brewfile
vendored
4
dist/Brewfile
vendored
@@ -7,6 +7,4 @@ brew "python3"
|
||||
brew "freetype2"
|
||||
brew "libmagic"
|
||||
brew "pkg-config"
|
||||
|
||||
# TODO: Remove this when XCode version of clang will support the same level as LLVM 10
|
||||
brew "llvm"
|
||||
brew "gcc@12"
|
||||
|
||||
2
dist/DEBIAN/control.in
vendored
2
dist/DEBIAN/control.in
vendored
@@ -4,7 +4,7 @@ Section: editors
|
||||
Priority: optional
|
||||
Architecture: amd64
|
||||
License: GNU GPL-2
|
||||
Depends: libglfw3-dev, libmagic-dev, libmbedtls-dev, libcapstone-dev, python3-dev, libfreetype-dev, libgtk-3-dev, libldap2-dev
|
||||
Depends: libglfw3, libmagic1, libmbedtls14, libpython3.10, libfreetype6, libopengl0, libdbus-1-3, xdg-desktop-portal
|
||||
Maintainer: WerWolv <hey@werwolv.net>
|
||||
Description: ImHex Hex Editor
|
||||
A Hex Editor for Reverse Engineers, Programmers and
|
||||
|
||||
11
dist/DEBIAN/imhex.desktop
vendored
11
dist/DEBIAN/imhex.desktop
vendored
@@ -1,11 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Name=ImHex
|
||||
Comment=ImHex Hex Editor
|
||||
GenericName=Hex Editor
|
||||
Exec=/usr/bin/imhex %U
|
||||
Icon=/usr/share/pixmaps/imhex.png
|
||||
Type=Application
|
||||
StartupNotify=true
|
||||
Categories=GNOME;GTK;Development;
|
||||
StartupWMClass=imhex
|
||||
|
||||
3
dist/Dockerfile
vendored
3
dist/Dockerfile
vendored
@@ -15,7 +15,8 @@ RUN pacman -S --needed --noconfirm \
|
||||
mbedtls \
|
||||
python3 \
|
||||
freetype2 \
|
||||
gtk3
|
||||
dbus \
|
||||
xdg-desktop-portal
|
||||
|
||||
# Clone ImHex
|
||||
RUN git clone https://github.com/WerWolv/ImHex --recurse-submodules /root/ImHex
|
||||
|
||||
3
dist/ImHex-9999.ebuild
vendored
3
dist/ImHex-9999.ebuild
vendored
@@ -27,6 +27,7 @@ RDEPEND="${DEPEND}
|
||||
sys-apps/file
|
||||
dev-libs/mbedtls
|
||||
dev-cpp/nlohmann_json
|
||||
x11-libs/gtk+
|
||||
dbus
|
||||
xdg-desktop-portal
|
||||
"
|
||||
BDEPEND="${DEPEND}"
|
||||
|
||||
41
dist/compiling/linux.md
vendored
Normal file
41
dist/compiling/linux.md
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
### Compiling ImHex on Linux
|
||||
|
||||
Dependency installation scripts are available for many common Linux distributions in the [/dist](dist) folder.
|
||||
After all the dependencies are installed, run the following commands to build ImHex:
|
||||
|
||||
```sh
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
|
||||
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||
-DRUST_PATH="$HOME/.cargo/bin/" \
|
||||
..
|
||||
make -j 4 install
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Put the ImHex executable into the `/usr/bin` folder.
|
||||
Put libimhex.so into the `/usr/lib` folder.
|
||||
Configuration files go to `/usr/etc/imhex` or `~/.config/imhex`.
|
||||
All other files belong in `/usr/share/imhex` or `~/.local/share/imhex`:
|
||||
|
||||
```
|
||||
Patterns: /usr/share/imhex/patterns
|
||||
Pattern Includes: /usr/share/imhex/includes
|
||||
Magic files: /usr/share/imhex/magic
|
||||
Python: /usr/share/imhex/lib/pythonX.X
|
||||
Plugins: /usr/share/imhex/plugins
|
||||
Configuration: /etc/xdg/imhex/config
|
||||
```
|
||||
|
||||
All paths follow the XDG Base Directories standard, and can thus be modified
|
||||
with the environment variables `XDG_CONFIG_HOME`, `XDG_CONFIG_DIRS`,
|
||||
`XDG_DATA_HOME` and `XDG_DATA_DIRS`.
|
||||
41
dist/compiling/macOS.md
vendored
Normal file
41
dist/compiling/macOS.md
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
### Compiling ImHex on macOS
|
||||
|
||||
To build ImHex on macOS, run the following commands:
|
||||
|
||||
```sh
|
||||
brew bundle --no-lock --file dist/Brewfile
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=$(brew --prefix gcc@12)/bin/gcc-12 \
|
||||
CXX=$(brew --prefix gcc@12)/bin/g++-12 \
|
||||
OBJC=$(brew --prefix llvm)/bin/clang \
|
||||
OBJCXX=$(brew --prefix llvm)/bin/clang++ \
|
||||
PKG_CONFIG_PATH="$(brew --prefix openssl)/lib/pkgconfig":"$(brew --prefix)/lib/pkgconfig" \
|
||||
MACOSX_DEPLOYMENT_TARGET="10.15" \
|
||||
cmake \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCREATE_BUNDLE=ON \
|
||||
-DCREATE_PACKAGE=ON \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||
..
|
||||
make -j4 package
|
||||
```
|
||||
|
||||
Open the generated .dmg file and drag-n-drop the ImHex executable to the Applications folder
|
||||
|
||||
All other files belong in `~/Library/Application Support/imhex`:
|
||||
```
|
||||
Patterns: ~/Library/Application Support/imhex/patterns
|
||||
Pattern Includes: ~/Library/Application Support/imhex/includes
|
||||
Magic files: ~/Library/Application Support/imhex/magic
|
||||
Python: ~/Library/Application Support/imhex/lib/pythonX.X
|
||||
Plugins: ~/Library/Application Support/imhex/plugins
|
||||
Configuration: ~/Library/Application Support/imhex/config
|
||||
```
|
||||
|
||||
If the build fails while trying to find the macOS libraries, make sure you have
|
||||
XCode installed with `xcode-select --install`. Homebrew will also help get the
|
||||
most recent SDK installed and configured with `brew doctor`.
|
||||
23
dist/compiling/windows.md
vendored
Normal file
23
dist/compiling/windows.md
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
### Compiling ImHex on Windows
|
||||
|
||||
On Windows, ImHex is built through msys2 / mingw. To install all dependencies, open a msys2 window and run the PKGCONFIG script in the [dist/msys2](dist/msys2) folder.
|
||||
After all the dependencies are installed, run the following commands to build ImHex:
|
||||
|
||||
```sh
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G "MinGW Makefiles" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX="$PWD/install" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
|
||||
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||
-DRUST_PATH="$USERPROFILE/.cargo/bin/" \
|
||||
..
|
||||
mingw32-make -j install
|
||||
```
|
||||
|
||||
ImHex will look for any extra resources either in various folders directly next to the executable or in `%localappdata%/imhex`
|
||||
5
dist/get_deps_archlinux.sh
vendored
5
dist/get_deps_archlinux.sh
vendored
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
pacman -S --needed \
|
||||
pacman -S $@ --needed \
|
||||
cmake \
|
||||
gcc \
|
||||
lld \
|
||||
@@ -9,4 +9,5 @@ pacman -S --needed \
|
||||
mbedtls \
|
||||
python3 \
|
||||
freetype2 \
|
||||
gtk3
|
||||
dbus \
|
||||
xdg-desktop-portal
|
||||
|
||||
14
dist/get_deps_debian.sh
vendored
14
dist/get_deps_debian.sh
vendored
@@ -1,9 +1,5 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
echo "As of 2020-12, Debian stable does not include g++-10, needs debian testing or unstable."
|
||||
|
||||
# Tested on 2020-12-09 with Docker image bitnami/minideb:unstable
|
||||
|
||||
# Install pkgconf (adds minimum dependencies) only if the equivalent pkf-config is not already installed.
|
||||
if ! which pkg-config
|
||||
then
|
||||
@@ -12,8 +8,8 @@ fi
|
||||
|
||||
apt install -y \
|
||||
build-essential \
|
||||
gcc-11 \
|
||||
g++-11 \
|
||||
gcc-12 \
|
||||
g++-12 \
|
||||
lld \
|
||||
${PKGCONF:-} \
|
||||
cmake \
|
||||
@@ -25,7 +21,5 @@ apt install -y \
|
||||
libmbedtls-dev \
|
||||
python3-dev \
|
||||
libfreetype-dev \
|
||||
libgtk-3-dev \
|
||||
|
||||
echo "Please consider this before running cmake (useful on e.g. Ubuntu 20.04):"
|
||||
echo "export CXX=g++-11"
|
||||
libdbus-1-dev \
|
||||
xdg-desktop-portal
|
||||
|
||||
3
dist/get_deps_fedora.sh
vendored
3
dist/get_deps_fedora.sh
vendored
@@ -10,4 +10,5 @@ dnf install \
|
||||
mbedtls-devel \
|
||||
python-devel \
|
||||
freetype-devel \
|
||||
gtk3-devel
|
||||
dbus \
|
||||
xdg-desktop-portal
|
||||
|
||||
2
lib/external/curl
vendored
2
lib/external/curl
vendored
Submodule lib/external/curl updated: 64db5c575d...45ac4d0194
2
lib/external/fmt
vendored
2
lib/external/fmt
vendored
Submodule lib/external/fmt updated: bc654faf82...c4ee726532
8
lib/external/imgui/CMakeLists.txt
vendored
8
lib/external/imgui/CMakeLists.txt
vendored
@@ -32,14 +32,14 @@ add_library(imgui OBJECT
|
||||
source/implot_items.cpp
|
||||
source/implot_demo.cpp
|
||||
|
||||
fonts/fontawesome_font.c
|
||||
fonts/codicons_font.c
|
||||
fonts/unifont_font.c
|
||||
source/fonts/fontawesome_font.c
|
||||
source/fonts/codicons_font.c
|
||||
source/fonts/unifont_font.c
|
||||
)
|
||||
|
||||
add_compile_definitions(IMGUI_IMPL_OPENGL_LOADER_GLAD)
|
||||
|
||||
target_include_directories(imgui PUBLIC include fonts ${CMAKE_CURRENT_SOURCE_DIR} ${FREETYPE_INCLUDE_DIRS} ${GLFW_INCLUDE_DIRS})
|
||||
target_include_directories(imgui PUBLIC include ${FREETYPE_INCLUDE_DIRS} ${GLFW_INCLUDE_DIRS})
|
||||
|
||||
target_link_directories(imgui PUBLIC ${GLFW_LIBRARY_DIRS})
|
||||
|
||||
|
||||
2
lib/external/imgui/source/TextEditor.cpp
vendored
2
lib/external/imgui/source/TextEditor.cpp
vendored
@@ -821,7 +821,7 @@ void TextEditor::Render() {
|
||||
ImGui::Text("Error at line %d:", errorIt->first);
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::Separator();
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 0.2f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 0.5f, 0.2f, 1.0f));
|
||||
ImGui::Text("%s", errorIt->second.c_str());
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::EndTooltip();
|
||||
|
||||
58
lib/external/imgui/source/imgui_impl_glfw.cpp
vendored
58
lib/external/imgui/source/imgui_impl_glfw.cpp
vendored
@@ -47,6 +47,7 @@
|
||||
// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers.
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_internal.h"
|
||||
#include "imgui_impl_glfw.h"
|
||||
|
||||
// GLFW
|
||||
@@ -136,6 +137,51 @@ static void ImGui_ImplGlfw_SetClipboardText(void* user_data, const char* text)
|
||||
glfwSetClipboardString((GLFWwindow*)user_data, text);
|
||||
}
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
static const char* ImGui_ImplWin_GetClipboardText(void*)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.ClipboardHandlerData.clear();
|
||||
if (!::OpenClipboard(NULL))
|
||||
return NULL;
|
||||
HANDLE wbuf_handle = ::GetClipboardData(CF_UNICODETEXT);
|
||||
if (wbuf_handle == NULL)
|
||||
{
|
||||
::CloseClipboard();
|
||||
return NULL;
|
||||
}
|
||||
if (const WCHAR* wbuf_global = (const WCHAR*)::GlobalLock(wbuf_handle))
|
||||
{
|
||||
int buf_len = ::WideCharToMultiByte(CP_UTF8, 0, wbuf_global, -1, NULL, 0, NULL, NULL);
|
||||
g.ClipboardHandlerData.resize(buf_len);
|
||||
::WideCharToMultiByte(CP_UTF8, 0, wbuf_global, -1, g.ClipboardHandlerData.Data, buf_len, NULL, NULL);
|
||||
}
|
||||
::GlobalUnlock(wbuf_handle);
|
||||
::CloseClipboard();
|
||||
return g.ClipboardHandlerData.Data;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin_SetClipboardText(void*, const char* text)
|
||||
{
|
||||
if (!::OpenClipboard(NULL))
|
||||
return;
|
||||
const int wbuf_length = ::MultiByteToWideChar(CP_UTF8, 0, text, -1, NULL, 0);
|
||||
HGLOBAL wbuf_handle = ::GlobalAlloc(GMEM_MOVEABLE, (SIZE_T)wbuf_length * sizeof(WCHAR));
|
||||
if (wbuf_handle == NULL)
|
||||
{
|
||||
::CloseClipboard();
|
||||
return;
|
||||
}
|
||||
WCHAR* wbuf_global = (WCHAR*)::GlobalLock(wbuf_handle);
|
||||
::MultiByteToWideChar(CP_UTF8, 0, text, -1, wbuf_global, wbuf_length);
|
||||
::GlobalUnlock(wbuf_handle);
|
||||
::EmptyClipboard();
|
||||
if (::SetClipboardData(CF_UNICODETEXT, wbuf_handle) == NULL)
|
||||
::GlobalFree(wbuf_handle);
|
||||
::CloseClipboard();
|
||||
}
|
||||
#endif
|
||||
|
||||
void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
@@ -271,9 +317,15 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
||||
io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y;
|
||||
io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z;
|
||||
|
||||
io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText;
|
||||
io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText;
|
||||
io.ClipboardUserData = bd->Window;
|
||||
#if defined(OS_WINDOWS)
|
||||
io.SetClipboardTextFn = ImGui_ImplWin_SetClipboardText;
|
||||
io.GetClipboardTextFn = ImGui_ImplWin_GetClipboardText;
|
||||
io.ClipboardUserData = bd->Window;
|
||||
#else
|
||||
io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText;
|
||||
io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText;
|
||||
io.ClipboardUserData = bd->Window;
|
||||
#endif
|
||||
|
||||
// Create mouse cursors
|
||||
// (By design, on X11 cursors are user configurable and some cursors may be missing. When a cursor doesn't exist,
|
||||
|
||||
2
lib/external/libromfs
vendored
2
lib/external/libromfs
vendored
Submodule lib/external/libromfs updated: f14e88a727...58757f6cad
2
lib/external/nativefiledialog
vendored
2
lib/external/nativefiledialog
vendored
Submodule lib/external/nativefiledialog updated: 28ade5a5cc...3311592818
2
lib/external/pattern_language
vendored
2
lib/external/pattern_language
vendored
Submodule lib/external/pattern_language updated: 23ec4e4ef1...1b0de5e85b
2
lib/external/yara/yara
vendored
2
lib/external/yara/yara
vendored
Submodule lib/external/yara/yara updated: 136794355c...d5a7565a8b
8
lib/libimhex-rs/Cargo.lock
generated
8
lib/libimhex-rs/Cargo.lock
generated
@@ -568,9 +568,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.4"
|
||||
version = "1.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
|
||||
checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@@ -579,9 +579,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.25"
|
||||
version = "0.6.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
|
||||
@@ -10,6 +10,7 @@ set_target_properties(imgui PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../external/microtar ${CMAKE_CURRENT_BINARY_DIR}/external/microtar EXCLUDE_FROM_ALL)
|
||||
set_target_properties(microtar PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
set(NFD_PORTAL ON CACHE BOOL "Use Portals for Linux file dialogs" FORCE)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../external/nativefiledialog ${CMAKE_CURRENT_BINARY_DIR}/external/nativefiledialog EXCLUDE_FROM_ALL)
|
||||
set_target_properties(nfd PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
@@ -123,14 +124,14 @@ set(LIBIMHEX_SOURCES
|
||||
source/helpers/patches.cpp
|
||||
source/helpers/project_file_handler.cpp
|
||||
source/helpers/encoding_file.cpp
|
||||
source/helpers/loader_script_handler.cpp
|
||||
source/helpers/logger.cpp
|
||||
source/helpers/tar.cpp
|
||||
|
||||
source/providers/provider.cpp
|
||||
|
||||
source/ui/imgui_imhex_extensions.cpp
|
||||
source/ui/view.cpp
|
||||
)
|
||||
)
|
||||
|
||||
if (APPLE)
|
||||
set(OSX_11_0_SDK_PATH /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk)
|
||||
@@ -142,7 +143,9 @@ if (APPLE)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
set(LIBIMHEX_SOURCES ${LIBIMHEX_SOURCES} source/helpers/fs_macos.mm)
|
||||
set(LIBIMHEX_SOURCES ${LIBIMHEX_SOURCES}
|
||||
source/helpers/fs_macos.m
|
||||
source/helpers/utils_macos.m)
|
||||
endif ()
|
||||
|
||||
add_compile_definitions(IMHEX_PROJECT_NAME="${PROJECT_NAME}")
|
||||
|
||||
@@ -3,46 +3,8 @@
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
#include <hex/helpers/types.hpp>
|
||||
#include <hex/helpers/intrinsics.hpp>
|
||||
|
||||
constexpr static const auto ImHexApiURL = "https://api.werwolv.net/imhex";
|
||||
constexpr static const auto GitHubApiURL = "https://api.github.com/repos/WerWolv/ImHex";
|
||||
|
||||
using u8 = std::uint8_t;
|
||||
using u16 = std::uint16_t;
|
||||
using u32 = std::uint32_t;
|
||||
using u64 = std::uint64_t;
|
||||
using u128 = __uint128_t;
|
||||
|
||||
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 color_t = u32;
|
||||
|
||||
namespace hex {
|
||||
|
||||
struct Region {
|
||||
u64 address;
|
||||
size_t size;
|
||||
|
||||
[[nodiscard]] constexpr bool isWithin(const Region &other) const {
|
||||
return (this->address >= other.address) && ((this->address + this->size) <= (other.address + other.size));
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr bool overlaps(const Region &other) const {
|
||||
return ((this->address + this->size) >= other.address) && (this->address < (other.address + other.size));
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr u64 getStartAddress() const {
|
||||
return this->address;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr u64 getEndAddress() const {
|
||||
return this->address + this->size - 1;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ namespace hex {
|
||||
|
||||
}
|
||||
|
||||
template<hex::derived_from<View> T, typename... Args>
|
||||
template<std::derived_from<View> T, typename... Args>
|
||||
void add(Args &&...args) {
|
||||
return impl::add(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
@@ -234,7 +234,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
|
||||
template<hex::derived_from<dp::Node> T, typename... Args>
|
||||
template<std::derived_from<dp::Node> T, typename... Args>
|
||||
void add(const std::string &unlocalizedCategory, const std::string &unlocalizedName, Args &&...args) {
|
||||
add(impl::Entry { unlocalizedCategory.c_str(), unlocalizedName.c_str(), [=] {
|
||||
auto node = new T(std::forward<Args>(args)...);
|
||||
@@ -326,7 +326,7 @@ namespace hex {
|
||||
|
||||
}
|
||||
|
||||
template<hex::derived_from<hex::prv::Provider> T>
|
||||
template<std::derived_from<hex::prv::Provider> T>
|
||||
void add(const std::string &unlocalizedName, bool addToList = true) {
|
||||
(void)EventManager::subscribe<RequestCreateProvider>([expectedName = unlocalizedName](const std::string &name, hex::prv::Provider **provider) {
|
||||
if (name != expectedName) return;
|
||||
@@ -415,12 +415,80 @@ namespace hex {
|
||||
|
||||
}
|
||||
|
||||
template<hex::derived_from<DataVisualizer> T, typename... Args>
|
||||
template<std::derived_from<DataVisualizer> T, typename... Args>
|
||||
void addDataVisualizer(const std::string &unlocalizedName, Args &&...args) {
|
||||
return impl::addDataVisualizer(unlocalizedName, new T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace Hashes {
|
||||
|
||||
class Hash {
|
||||
public:
|
||||
Hash(std::string unlocalizedName) : m_unlocalizedName(std::move(unlocalizedName)) {}
|
||||
|
||||
class Function {
|
||||
public:
|
||||
using Callback = std::function<std::vector<u8>(const Region&, prv::Provider *)>;
|
||||
|
||||
Function(const Hash *type, std::string name, Callback callback)
|
||||
: m_type(type), m_name(std::move(name)), m_callback(std::move(callback)) {
|
||||
|
||||
}
|
||||
|
||||
[[nodiscard]] const Hash *getType() const { return this->m_type; }
|
||||
[[nodiscard]] const std::string &getName() const { return this->m_name; }
|
||||
|
||||
const std::vector<u8>& get(const Region& region, prv::Provider *provider) {
|
||||
if (this->m_cache.empty()) {
|
||||
this->m_cache = this->m_callback(region, provider);
|
||||
}
|
||||
|
||||
return this->m_cache;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
this->m_cache.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
const Hash *m_type;
|
||||
std::string m_name;
|
||||
Callback m_callback;
|
||||
|
||||
std::vector<u8> m_cache;
|
||||
};
|
||||
|
||||
virtual void draw() { }
|
||||
[[nodiscard]] virtual Function create(std::string name) = 0;
|
||||
|
||||
[[nodiscard]] const std::string &getUnlocalizedName() const {
|
||||
return this->m_unlocalizedName;
|
||||
}
|
||||
|
||||
protected:
|
||||
[[nodiscard]] Function create(const std::string &name, const Function::Callback &callback) const {
|
||||
return { this, name, callback };
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_unlocalizedName;
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::vector<Hash*> &getHashes();
|
||||
|
||||
void add(Hash* hash);
|
||||
}
|
||||
|
||||
template<typename T, typename ... Args>
|
||||
void add(Args && ... args) {
|
||||
impl::add(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -129,6 +129,12 @@ namespace hex {
|
||||
EVENT_DEF(RequestOpenPopup, std::string);
|
||||
EVENT_DEF(RequestCreateProvider, std::string, hex::prv::Provider **);
|
||||
|
||||
EVENT_DEF(RequestShowInfoPopup, std::string);
|
||||
EVENT_DEF(RequestShowErrorPopup, std::string);
|
||||
EVENT_DEF(RequestShowFatalErrorPopup, std::string);
|
||||
EVENT_DEF(RequestShowYesNoQuestionPopup, std::string, std::function<void()>, std::function<void()>);
|
||||
EVENT_DEF(RequestShowFileChooserPopup, std::vector<std::fs::path>, std::vector<nfdfilteritem_t>, std::function<void(std::fs::path)>);
|
||||
|
||||
EVENT_DEF(QuerySelection, std::optional<Region> &);
|
||||
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <hex/helpers/concepts.hpp>
|
||||
#include <hex/api/task.hpp>
|
||||
#include <hex/api/keybinding.hpp>
|
||||
#include <hex/helpers/fs.hpp>
|
||||
|
||||
using ImGuiID = unsigned int;
|
||||
struct ImVec2;
|
||||
@@ -127,7 +128,7 @@ namespace hex {
|
||||
|
||||
void add(prv::Provider *provider);
|
||||
|
||||
template<hex::derived_from<prv::Provider> T>
|
||||
template<std::derived_from<prv::Provider> T>
|
||||
void add(auto &&...args) {
|
||||
add(new T(std::forward<decltype(args)>(args)...));
|
||||
}
|
||||
@@ -158,6 +159,11 @@ namespace hex {
|
||||
void setProgramArguments(int argc, char **argv, char **envp);
|
||||
|
||||
void setBorderlessWindowMode(bool enabled);
|
||||
|
||||
void setCustomFontPath(const std::fs::path &path);
|
||||
void setFontSize(float size);
|
||||
|
||||
void setGPUVendor(const std::string &vendor);
|
||||
}
|
||||
|
||||
struct ProgramArguments {
|
||||
@@ -166,6 +172,12 @@ namespace hex {
|
||||
char **envp;
|
||||
};
|
||||
|
||||
enum class Theme {
|
||||
Dark = 1,
|
||||
Light = 2,
|
||||
Classic = 3
|
||||
};
|
||||
|
||||
const ProgramArguments &getProgramArguments();
|
||||
|
||||
float getTargetFPS();
|
||||
@@ -181,6 +193,19 @@ namespace hex {
|
||||
|
||||
std::map<std::string, std::string> &getInitArguments();
|
||||
|
||||
const std::fs::path &getCustomFontPath();
|
||||
float getFontSize();
|
||||
|
||||
void setTheme(Theme theme);
|
||||
Theme getTheme();
|
||||
|
||||
void enableSystemThemeDetection(bool enabled);
|
||||
bool usesSystemThemeDetection();
|
||||
|
||||
const std::vector<std::fs::path> &getAdditionalFolderPaths();
|
||||
void setAdditionalFolderPaths(const std::vector<std::fs::path> &paths);
|
||||
|
||||
const std::string &getGPUVendor();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
struct ImGuiContext;
|
||||
|
||||
namespace hex {
|
||||
@@ -39,7 +45,11 @@ namespace hex {
|
||||
using SetImGuiContextFunc = void (*)(ImGuiContext *);
|
||||
using IsBuiltinPluginFunc = bool (*)();
|
||||
|
||||
void *m_handle = nullptr;
|
||||
#if defined(OS_WINDOWS)
|
||||
HMODULE m_handle = nullptr;
|
||||
#else
|
||||
void *m_handle = nullptr;
|
||||
#endif
|
||||
std::fs::path m_path;
|
||||
|
||||
mutable bool m_initialized = false;
|
||||
|
||||
@@ -5,151 +5,7 @@
|
||||
#include <type_traits>
|
||||
#include <memory>
|
||||
|
||||
namespace hex {
|
||||
|
||||
template<typename>
|
||||
struct is_integral_helper : public std::false_type { };
|
||||
|
||||
template<>
|
||||
struct is_integral_helper<u8> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_integral_helper<i8> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_integral_helper<u16> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_integral_helper<i16> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_integral_helper<u32> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_integral_helper<i32> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_integral_helper<u64> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_integral_helper<i64> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_integral_helper<u128> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_integral_helper<i128> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_integral_helper<bool> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_integral_helper<char> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_integral_helper<char8_t> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_integral_helper<char16_t> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_integral_helper<char32_t> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_integral_helper<wchar_t> : public std::true_type { };
|
||||
|
||||
template<typename T>
|
||||
struct is_integral : public is_integral_helper<std::remove_cvref_t<T>>::type { };
|
||||
|
||||
|
||||
template<typename>
|
||||
struct is_signed_helper : public std::false_type { };
|
||||
|
||||
template<>
|
||||
struct is_signed_helper<i8> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_signed_helper<i16> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_signed_helper<i32> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_signed_helper<i64> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_signed_helper<i128> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_signed_helper<char> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_signed_helper<float> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_signed_helper<double> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_signed_helper<long double> : public std::true_type { };
|
||||
|
||||
template<typename T>
|
||||
struct is_signed : public is_signed_helper<std::remove_cvref_t<T>>::type { };
|
||||
|
||||
|
||||
template<typename>
|
||||
struct is_floating_point_helper : public std::false_type { };
|
||||
|
||||
template<>
|
||||
struct is_floating_point_helper<float> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_floating_point_helper<double> : public std::true_type { };
|
||||
|
||||
template<>
|
||||
struct is_floating_point_helper<long double> : public std::true_type { };
|
||||
|
||||
template<typename T>
|
||||
struct is_floating_point : public is_floating_point_helper<std::remove_cvref_t<T>>::type { };
|
||||
|
||||
}
|
||||
|
||||
#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION <= 12000
|
||||
#if __has_include(<concepts>)
|
||||
// Make sure we break when derived_from is implemented in libc++. Then we can fix a compatibility version above
|
||||
#include <concepts>
|
||||
#endif
|
||||
// libcxx 12 still doesn't have many default concepts implemented, as a result we need to define it ourself using clang built-ins.
|
||||
// [concept.derived] (patch from https://reviews.llvm.org/D74292)
|
||||
namespace hex {
|
||||
template<class _Dp, class _Bp>
|
||||
concept derived_from =
|
||||
__is_base_of(_Bp, _Dp) && __is_convertible_to(const volatile _Dp *, const volatile _Bp *);
|
||||
}
|
||||
|
||||
#else
|
||||
// Assume supported
|
||||
#include <concepts>
|
||||
namespace hex {
|
||||
using std::derived_from;
|
||||
}
|
||||
#endif
|
||||
|
||||
// [concepts.arithmetic]
|
||||
namespace hex {
|
||||
|
||||
template<class T>
|
||||
concept integral = hex::is_integral<T>::value;
|
||||
|
||||
template<class T>
|
||||
concept signed_integral = integral<T> && hex::is_signed<T>::value;
|
||||
|
||||
template<class T>
|
||||
concept unsigned_integral = integral<T> && !signed_integral<T>;
|
||||
|
||||
template<class T>
|
||||
concept floating_point = std::is_floating_point<T>::value;
|
||||
|
||||
}
|
||||
#include <concepts>
|
||||
|
||||
namespace hex {
|
||||
|
||||
@@ -159,11 +15,6 @@ namespace hex {
|
||||
template<typename T, size_t Size>
|
||||
concept has_size = sizeof(T) == Size;
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace hex {
|
||||
|
||||
template<typename T>
|
||||
class Cloneable {
|
||||
public:
|
||||
|
||||
@@ -47,10 +47,12 @@ namespace hex::fs {
|
||||
size_t readBuffer(u8 *buffer, size_t size);
|
||||
std::vector<u8> readBytes(size_t numBytes = 0);
|
||||
std::string readString(size_t numBytes = 0);
|
||||
std::u8string readU8String(size_t numBytes = 0);
|
||||
|
||||
void write(const u8 *buffer, size_t size);
|
||||
void write(const std::vector<u8> &bytes);
|
||||
void write(const std::string &string);
|
||||
void write(const std::u8string &string);
|
||||
|
||||
[[nodiscard]] size_t getSize() const;
|
||||
void setSize(u64 size);
|
||||
|
||||
@@ -50,6 +50,12 @@ namespace hex::fs {
|
||||
return std::filesystem::remove(path, error) && !error;
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
static inline bool removeAll(const std::fs::path &path) {
|
||||
std::error_code error;
|
||||
return std::filesystem::remove_all(path, error) && !error;
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
static inline uintmax_t getFileSize(const std::fs::path &path) {
|
||||
std::error_code error;
|
||||
@@ -61,6 +67,8 @@ namespace hex::fs {
|
||||
|
||||
bool isPathWritable(const std::fs::path &path);
|
||||
|
||||
std::fs::path toShortPath(const std::fs::path &path);
|
||||
|
||||
enum class DialogMode
|
||||
{
|
||||
Open,
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(OS_MACOS)
|
||||
#include <hex/helpers/fs.hpp>
|
||||
|
||||
namespace hex {
|
||||
std::string getMacExecutableDirectoryPath();
|
||||
std::string getMacApplicationSupportDirectoryPath();
|
||||
}
|
||||
#endif
|
||||
12
lib/libimhex/include/hex/helpers/fs_macos.hpp
Normal file
12
lib/libimhex/include/hex/helpers/fs_macos.hpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(OS_MACOS)
|
||||
|
||||
#include <hex/helpers/fs.hpp>
|
||||
|
||||
extern "C" char * getMacExecutableDirectoryPath();
|
||||
extern "C" char * getMacApplicationSupportDirectoryPath();
|
||||
|
||||
extern "C" void macFree(void *ptr);
|
||||
|
||||
#endif
|
||||
@@ -1,38 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <hex/helpers/fs.hpp>
|
||||
|
||||
struct _object;
|
||||
typedef struct _object PyObject;
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace prv {
|
||||
class Provider;
|
||||
}
|
||||
|
||||
class LoaderScript {
|
||||
public:
|
||||
LoaderScript() = delete;
|
||||
|
||||
static bool processFile(const std::fs::path &scriptPath);
|
||||
|
||||
static void setFilePath(const std::fs::path &filePath) { LoaderScript::s_filePath = filePath; }
|
||||
static void setDataProvider(prv::Provider *provider) { LoaderScript::s_dataProvider = provider; }
|
||||
|
||||
private:
|
||||
static inline std::fs::path s_filePath;
|
||||
static inline prv::Provider *s_dataProvider;
|
||||
|
||||
static PyObject *Py_getFilePath(PyObject *self, PyObject *args);
|
||||
static PyObject *Py_addPatch(PyObject *self, PyObject *args);
|
||||
static PyObject *Py_addBookmark(PyObject *self, PyObject *args);
|
||||
|
||||
static PyObject *Py_addStruct(PyObject *self, PyObject *args);
|
||||
static PyObject *Py_addUnion(PyObject *self, PyObject *args);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -44,11 +44,14 @@ namespace hex {
|
||||
std::future<Response<void>> downloadFile(const std::string &url, const std::fs::path &filePath, u32 timeout = DefaultTimeout);
|
||||
|
||||
[[nodiscard]] std::string encode(const std::string &input);
|
||||
[[nodiscard]] std::string decode(const std::string &input);
|
||||
|
||||
[[nodiscard]] float getProgress() const { return this->m_progress; }
|
||||
|
||||
void cancel() { this->m_shouldCancel = true; }
|
||||
|
||||
static void setProxy(const std::string &url);
|
||||
|
||||
private:
|
||||
void setCommonSettings(std::string &response, const std::string &url, u32 timeout = 2000, const std::map<std::string, std::string> &extraHeaders = {}, const std::string &body = {});
|
||||
std::optional<i32> execute();
|
||||
@@ -62,6 +65,8 @@ namespace hex {
|
||||
std::mutex m_transmissionActive;
|
||||
float m_progress = 0.0F;
|
||||
bool m_shouldCancel = false;
|
||||
|
||||
static std::string s_proxyUrl;
|
||||
};
|
||||
|
||||
}
|
||||
35
lib/libimhex/include/hex/helpers/tar.hpp
Normal file
35
lib/libimhex/include/hex/helpers/tar.hpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <hex/helpers/fs.hpp>
|
||||
|
||||
#include <microtar.h>
|
||||
|
||||
namespace hex {
|
||||
|
||||
class Tar {
|
||||
public:
|
||||
enum class Mode {
|
||||
Read,
|
||||
Write,
|
||||
Create
|
||||
};
|
||||
|
||||
Tar() = default;
|
||||
Tar(const std::fs::path &path, Mode mode);
|
||||
~Tar();
|
||||
|
||||
std::vector<u8> read(const std::fs::path &path);
|
||||
void write(const std::fs::path &path, const std::vector<u8> &data);
|
||||
|
||||
std::vector<std::fs::path> listEntries();
|
||||
|
||||
void extract(const std::fs::path &path, const std::fs::path &outputPath);
|
||||
void extractAll(const std::fs::path &outputPath);
|
||||
|
||||
private:
|
||||
mtar_t m_ctx = { };
|
||||
};
|
||||
|
||||
}
|
||||
44
lib/libimhex/include/hex/helpers/types.hpp
Normal file
44
lib/libimhex/include/hex/helpers/types.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
using u8 = std::uint8_t;
|
||||
using u16 = std::uint16_t;
|
||||
using u32 = std::uint32_t;
|
||||
using u64 = std::uint64_t;
|
||||
using u128 = __uint128_t;
|
||||
|
||||
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 color_t = u32;
|
||||
|
||||
namespace hex {
|
||||
|
||||
struct Region {
|
||||
u64 address;
|
||||
size_t size;
|
||||
|
||||
[[nodiscard]] constexpr bool isWithin(const Region &other) const {
|
||||
return (this->getStartAddress() >= other.getStartAddress()) && (this->getEndAddress() <= other.getEndAddress());
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr bool overlaps(const Region &other) const {
|
||||
return (this->getEndAddress() >= other.getStartAddress()) && (this->getStartAddress() < other.getEndAddress());
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr u64 getStartAddress() const {
|
||||
return this->address;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr u64 getEndAddress() const {
|
||||
return this->address + this->size - 1;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr size_t getSize() const {
|
||||
return this->size;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -43,7 +43,7 @@ namespace hex {
|
||||
std::string encodeByteString(const std::vector<u8> &bytes);
|
||||
std::vector<u8> decodeByteString(const std::string &string);
|
||||
|
||||
[[nodiscard]] constexpr inline u64 extract(u8 from, u8 to, const hex::unsigned_integral auto &value) {
|
||||
[[nodiscard]] constexpr inline u64 extract(u8 from, u8 to, const std::unsigned_integral auto &value) {
|
||||
if (from < to) std::swap(from, to);
|
||||
|
||||
using ValueType = std::remove_cvref_t<decltype(value)>;
|
||||
@@ -72,6 +72,18 @@ namespace hex {
|
||||
return (value ^ mask) - mask;
|
||||
}
|
||||
|
||||
template<std::integral T>
|
||||
constexpr inline T swapBitOrder(size_t numBits, T value) {
|
||||
T result = 0x00;
|
||||
|
||||
for (size_t bit = 0; bit < numBits; bit++) {
|
||||
result <<= 1;
|
||||
result |= (value & (1 << bit)) != 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class... Ts>
|
||||
struct overloaded : Ts... { using Ts::operator()...; };
|
||||
template<class... Ts>
|
||||
@@ -188,7 +200,7 @@ namespace hex {
|
||||
return T(1) << bit_width(T(x - 1));
|
||||
}
|
||||
|
||||
template<hex::integral T, hex::integral U>
|
||||
template<std::integral T, std::integral U>
|
||||
auto powi(T base, U exp) {
|
||||
using ResultType = decltype(T{} * U{});
|
||||
|
||||
@@ -252,7 +264,7 @@ namespace hex {
|
||||
return result;
|
||||
}
|
||||
|
||||
inline std::string toBinaryString(hex::unsigned_integral auto number) {
|
||||
inline std::string toBinaryString(std::unsigned_integral auto number) {
|
||||
if (number == 0) return "0";
|
||||
|
||||
std::string result;
|
||||
@@ -305,7 +317,7 @@ namespace hex {
|
||||
return *value;
|
||||
}
|
||||
|
||||
template<hex::integral T>
|
||||
template<std::integral T>
|
||||
T alignTo(T value, T alignment) {
|
||||
T remainder = value % alignment;
|
||||
|
||||
|
||||
10
lib/libimhex/include/hex/helpers/utils_macos.hpp
Normal file
10
lib/libimhex/include/hex/helpers/utils_macos.hpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(OS_MACOS)
|
||||
|
||||
#include <string>
|
||||
|
||||
extern "C" void openWebpageMacos(const char *url);
|
||||
extern "C" bool isMacosSystemDarkModeEnabled();
|
||||
|
||||
#endif
|
||||
@@ -110,6 +110,11 @@ namespace hex::prv {
|
||||
|
||||
friend bool operator== (const Iterator& left, const Iterator& right) { return left.m_address == right.m_address; };
|
||||
friend bool operator!= (const Iterator& left, const Iterator& right) { return left.m_address != right.m_address; };
|
||||
friend bool operator> (const Iterator& left, const Iterator& right) { return left.m_address > right.m_address; };
|
||||
friend bool operator< (const Iterator& left, const Iterator& right) { return left.m_address < right.m_address; };
|
||||
friend bool operator>= (const Iterator& left, const Iterator& right) { return left.m_address >= right.m_address; };
|
||||
friend bool operator<= (const Iterator& left, const Iterator& right) { return left.m_address <= right.m_address; };
|
||||
|
||||
private:
|
||||
BufferedReader *m_reader;
|
||||
u64 m_address;
|
||||
@@ -176,10 +181,14 @@ namespace hex::prv {
|
||||
|
||||
friend bool operator== (const ReverseIterator& left, const ReverseIterator& right) { return left.m_address == right.m_address; };
|
||||
friend bool operator!= (const ReverseIterator& left, const ReverseIterator& right) { return left.m_address != right.m_address; };
|
||||
friend bool operator> (const ReverseIterator& left, const ReverseIterator& right) { return left.m_address > right.m_address; };
|
||||
friend bool operator< (const ReverseIterator& left, const ReverseIterator& right) { return left.m_address < right.m_address; };
|
||||
friend bool operator>= (const ReverseIterator& left, const ReverseIterator& right) { return left.m_address >= right.m_address; };
|
||||
friend bool operator<= (const ReverseIterator& left, const ReverseIterator& right) { return left.m_address <= right.m_address; };
|
||||
|
||||
private:
|
||||
BufferedReader *m_reader;
|
||||
u64 m_address;
|
||||
u64 m_address = 0x00;
|
||||
};
|
||||
|
||||
Iterator begin() {
|
||||
@@ -187,7 +196,7 @@ namespace hex::prv {
|
||||
}
|
||||
|
||||
Iterator end() {
|
||||
return { this, this->m_baseAddress + this->m_provider->getActualSize() };
|
||||
return { this, this->m_provider->getActualSize() };
|
||||
}
|
||||
|
||||
ReverseIterator rbegin() {
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace hex::prv {
|
||||
|
||||
virtual void resize(size_t newSize);
|
||||
virtual void insert(u64 offset, size_t size);
|
||||
virtual void remove(u64 offset, size_t size);
|
||||
|
||||
virtual void save();
|
||||
virtual void saveAs(const std::fs::path &path);
|
||||
|
||||
@@ -74,7 +74,8 @@ namespace ImGui {
|
||||
bool ToolBarButton(const char *symbol, ImVec4 color);
|
||||
bool IconButton(const char *symbol, ImVec4 color, ImVec2 size_arg = ImVec2(0, 0));
|
||||
|
||||
bool InputIntegerPrefix(const char* label, const char *prefix, u64 *value, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
|
||||
bool InputIntegerPrefix(const char* label, const char *prefix, void *value, ImGuiDataType type, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
|
||||
bool InputHexadecimal(const char* label, u32 *value, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
|
||||
bool InputHexadecimal(const char* label, u64 *value, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
|
||||
|
||||
inline bool HasSecondPassed() {
|
||||
@@ -129,9 +130,13 @@ namespace ImGui {
|
||||
}
|
||||
|
||||
bool InputText(const char* label, std::string &buffer, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
|
||||
bool InputText(const char *label, std::u8string &buffer, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
|
||||
bool InputTextMultiline(const char* label, std::string &buffer, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
|
||||
bool InputTextWithHint(const char *label, const char *hint, std::string &buffer, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
|
||||
|
||||
bool InputScalarCallback(const char* label, ImGuiDataType data_type, void* p_data, const char* format, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data);
|
||||
|
||||
void HideTooltip();
|
||||
|
||||
bool BitCheckbox(const char* label, bool* v);
|
||||
}
|
||||
@@ -7,8 +7,8 @@
|
||||
#include <imgui_internal.h>
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
|
||||
#include <fontawesome_font.h>
|
||||
#include <codicons_font.h>
|
||||
#include <fonts/fontawesome_font.h>
|
||||
#include <fonts/codicons_font.h>
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/api/event.hpp>
|
||||
@@ -34,11 +34,9 @@ namespace hex {
|
||||
[[nodiscard]] virtual bool isAvailable() const;
|
||||
[[nodiscard]] virtual bool shouldProcess() const { return this->isAvailable() && this->getWindowOpenState(); }
|
||||
|
||||
static void drawCommonInterfaces();
|
||||
|
||||
static void showMessagePopup(const std::string &message);
|
||||
static void showErrorPopup(const std::string &errorMessage);
|
||||
static void showFatalPopup(const std::string &errorMessage);
|
||||
static void showInfoPopup(const std::string &message);
|
||||
static void showErrorPopup(const std::string &message);
|
||||
static void showFatalPopup(const std::string &message);
|
||||
static void showYesNoQuestionPopup(const std::string &message, const std::function<void()> &yesCallback, const std::function<void()> &noCallback);
|
||||
|
||||
static void showFileChooserPopup(const std::vector<std::fs::path> &paths, const std::vector<nfdfilteritem_t> &validExtensions, const std::function<void(std::fs::path)> &callback);
|
||||
@@ -71,15 +69,6 @@ namespace hex {
|
||||
bool m_windowOpen = false;
|
||||
std::map<Shortcut, std::function<void()>> m_shortcuts;
|
||||
|
||||
static std::string s_popupMessage;
|
||||
|
||||
static std::function<void()> s_yesCallback, s_noCallback;
|
||||
|
||||
static u32 s_selectableFileIndex;
|
||||
static std::vector<std::fs::path> s_selectableFiles;
|
||||
static std::function<void(std::fs::path)> s_selectableFileOpenCallback;
|
||||
static std::vector<nfdfilteritem_t> s_selectableFilesValidExtensions;
|
||||
|
||||
static ImFontAtlas *s_fontAtlas;
|
||||
static ImFontConfig s_fontConfig;
|
||||
|
||||
|
||||
@@ -538,7 +538,7 @@ namespace hex {
|
||||
|
||||
namespace ContentRegistry::HexEditor {
|
||||
|
||||
const int DataVisualizer::TextInputFlags = ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_NoHorizontalScroll | ImGuiInputTextFlags_EnterReturnsTrue;
|
||||
const int DataVisualizer::TextInputFlags = ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_NoHorizontalScroll;
|
||||
|
||||
bool DataVisualizer::drawDefaultEditingTextBox(u64 address, const char *format, ImGuiDataType dataType, u8 *data, ImGuiInputTextFlags flags) const {
|
||||
struct UserData {
|
||||
@@ -582,4 +582,18 @@ namespace hex {
|
||||
|
||||
}
|
||||
|
||||
namespace ContentRegistry::Hashes {
|
||||
|
||||
std::vector<Hash *> &impl::getHashes() {
|
||||
static std::vector<Hash *> hashes;
|
||||
|
||||
return hashes;
|
||||
}
|
||||
|
||||
void impl::add(Hash *hash) {
|
||||
getHashes().push_back(hash);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/api/content_registry.hpp>
|
||||
|
||||
#include <hex/api/event.hpp>
|
||||
#include <hex/providers/provider.hpp>
|
||||
#include <utility>
|
||||
|
||||
#include <utility>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace ImHexApi::Common {
|
||||
@@ -231,7 +234,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
bool isValid() {
|
||||
return !s_providers.empty();
|
||||
return !s_providers.empty() && s_currentProvider < s_providers.size();
|
||||
}
|
||||
|
||||
void add(prv::Provider *provider) {
|
||||
@@ -246,7 +249,7 @@ namespace hex {
|
||||
|
||||
s_providers.erase(it);
|
||||
|
||||
if (it - s_providers.begin() == s_currentProvider)
|
||||
if (it - s_providers.begin() == s_currentProvider && !s_providers.empty())
|
||||
setCurrentProvider(0);
|
||||
|
||||
delete provider;
|
||||
@@ -315,6 +318,21 @@ namespace hex {
|
||||
s_borderlessWindowMode = enabled;
|
||||
}
|
||||
|
||||
static std::fs::path s_customFontPath;
|
||||
void setCustomFontPath(const std::fs::path &path) {
|
||||
s_customFontPath = path;
|
||||
}
|
||||
|
||||
static float s_fontSize;
|
||||
void setFontSize(float size) {
|
||||
s_fontSize = size;
|
||||
}
|
||||
|
||||
static std::string s_gpuVendor;
|
||||
void setGPUVendor(const std::string &vendor) {
|
||||
s_gpuVendor = vendor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -360,6 +378,54 @@ namespace hex {
|
||||
|
||||
return initArgs;
|
||||
}
|
||||
|
||||
const std::fs::path &getCustomFontPath() {
|
||||
return impl::s_customFontPath;
|
||||
}
|
||||
|
||||
float getFontSize() {
|
||||
return impl::s_fontSize;
|
||||
}
|
||||
|
||||
|
||||
static Theme s_theme;
|
||||
static bool s_systemThemeDetection;
|
||||
|
||||
void setTheme(Theme theme) {
|
||||
s_theme = theme;
|
||||
|
||||
EventManager::post<EventSettingsChanged>();
|
||||
}
|
||||
|
||||
Theme getTheme() {
|
||||
return s_theme;
|
||||
}
|
||||
|
||||
|
||||
void enableSystemThemeDetection(bool enabled) {
|
||||
s_systemThemeDetection = enabled;
|
||||
|
||||
EventManager::post<EventSettingsChanged>();
|
||||
}
|
||||
|
||||
bool usesSystemThemeDetection() {
|
||||
return s_systemThemeDetection;
|
||||
}
|
||||
|
||||
|
||||
static std::vector<std::fs::path> s_additionalFolderPaths;
|
||||
const std::vector<std::fs::path> &getAdditionalFolderPaths() {
|
||||
return s_additionalFolderPaths;
|
||||
}
|
||||
|
||||
void setAdditionalFolderPaths(const std::vector<std::fs::path> &paths) {
|
||||
s_additionalFolderPaths = paths;
|
||||
}
|
||||
|
||||
|
||||
const std::string &getGPUVendor() {
|
||||
return impl::s_gpuVendor;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,19 +3,26 @@
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
#include <filesystem>
|
||||
#include <dlfcn.h>
|
||||
#include <system_error>
|
||||
|
||||
namespace hex {
|
||||
|
||||
Plugin::Plugin(const std::fs::path &path) : m_path(path) {
|
||||
this->m_handle = dlopen(path.string().c_str(), RTLD_LAZY);
|
||||
#if defined(OS_WINDOWS)
|
||||
this->m_handle = LoadLibraryW(path.c_str());
|
||||
|
||||
if (this->m_handle == nullptr) {
|
||||
log::error("dlopen failed: {}", dlerror());
|
||||
return;
|
||||
}
|
||||
if (this->m_handle == nullptr) {
|
||||
log::error("LoadLibraryW failed: {}!", std::system_category().message(::GetLastError()));
|
||||
return;
|
||||
}
|
||||
#else
|
||||
this->m_handle = dlopen(path.string().c_str(), RTLD_LAZY);
|
||||
|
||||
auto pluginName = std::fs::path(path).stem().string();
|
||||
if (this->m_handle == nullptr) {
|
||||
log::error("dlopen failed: {}!", dlerror());
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
this->m_initializePluginFunction = getPluginFunction<InitializePluginFunc>("initializePlugin");
|
||||
this->m_getPluginNameFunction = getPluginFunction<GetPluginNameFunc>("getPluginName");
|
||||
@@ -49,8 +56,13 @@ namespace hex {
|
||||
}
|
||||
|
||||
Plugin::~Plugin() {
|
||||
if (this->m_handle != nullptr)
|
||||
dlclose(this->m_handle);
|
||||
#if defined(OS_WINDOWS)
|
||||
if (this->m_handle != nullptr)
|
||||
FreeLibrary(this->m_handle);
|
||||
#else
|
||||
if (this->m_handle != nullptr)
|
||||
dlclose(this->m_handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Plugin::initializePlugin() const {
|
||||
@@ -120,7 +132,11 @@ namespace hex {
|
||||
|
||||
|
||||
void *Plugin::getPluginFunction(const std::string &symbol) {
|
||||
return dlsym(this->m_handle, symbol.c_str());
|
||||
#if defined(OS_WINDOWS)
|
||||
return reinterpret_cast<void *>(GetProcAddress(this->m_handle, symbol.c_str()));
|
||||
#else
|
||||
return dlsym(this->m_handle, symbol.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -135,7 +151,7 @@ namespace hex {
|
||||
|
||||
for (auto &pluginPath : std::fs::directory_iterator(pluginFolder)) {
|
||||
if (pluginPath.is_regular_file() && pluginPath.path().extension() == ".hexplug")
|
||||
PluginManager::s_plugins.emplace_back(pluginPath.path().string());
|
||||
PluginManager::s_plugins.emplace_back(pluginPath.path());
|
||||
}
|
||||
|
||||
if (PluginManager::s_plugins.empty())
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/concepts.hpp>
|
||||
|
||||
#include <mbedtls/version.h>
|
||||
#include <mbedtls/base64.h>
|
||||
@@ -15,7 +16,6 @@
|
||||
|
||||
#include <array>
|
||||
#include <span>
|
||||
#include <concepts>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
|
||||
@@ -38,8 +38,6 @@ namespace hex {
|
||||
{
|
||||
auto delimiterPos = line.find('=');
|
||||
|
||||
if (delimiterPos == std::string::npos)
|
||||
continue;
|
||||
if (delimiterPos >= line.length())
|
||||
continue;
|
||||
|
||||
@@ -47,12 +45,16 @@ namespace hex {
|
||||
to = line.substr(delimiterPos + 1);
|
||||
|
||||
if (from.empty()) continue;
|
||||
if (to.empty()) to = " ";
|
||||
}
|
||||
|
||||
auto fromBytes = hex::parseByteString(from);
|
||||
if (fromBytes.empty()) continue;
|
||||
|
||||
if (to.length() > 1)
|
||||
hex::trim(to);
|
||||
if (to.empty())
|
||||
to = " ";
|
||||
|
||||
if (!this->m_mapping.contains(fromBytes.size()))
|
||||
this->m_mapping.insert({ fromBytes.size(), {} });
|
||||
this->m_mapping[fromBytes.size()].insert({ fromBytes, to });
|
||||
|
||||
@@ -1,16 +1,28 @@
|
||||
#include <hex/helpers/file.hpp>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
|
||||
namespace hex::fs {
|
||||
|
||||
File::File(const std::fs::path &path, Mode mode) noexcept : m_path(path) {
|
||||
if (mode == File::Mode::Read)
|
||||
this->m_file = fopen64(path.string().c_str(), "rb");
|
||||
else if (mode == File::Mode::Write)
|
||||
this->m_file = fopen64(path.string().c_str(), "r+b");
|
||||
#if defined(OS_WINDOWS)
|
||||
if (mode == File::Mode::Read)
|
||||
this->m_file = _wfopen(path.c_str(), L"rb");
|
||||
else if (mode == File::Mode::Write)
|
||||
this->m_file = _wfopen(path.c_str(), L"r+b");
|
||||
|
||||
if (mode == File::Mode::Create || (mode == File::Mode::Write && this->m_file == nullptr))
|
||||
this->m_file = fopen64(path.string().c_str(), "w+b");
|
||||
if (mode == File::Mode::Create || (mode == File::Mode::Write && this->m_file == nullptr))
|
||||
this->m_file = _wfopen(path.c_str(), L"w+b");
|
||||
#else
|
||||
if (mode == File::Mode::Read)
|
||||
this->m_file = fopen64(path.string().c_str(), "rb");
|
||||
else if (mode == File::Mode::Write)
|
||||
this->m_file = fopen64(path.string().c_str(), "r+b");
|
||||
|
||||
if (mode == File::Mode::Create || (mode == File::Mode::Write && this->m_file == nullptr))
|
||||
this->m_file = fopen64(path.string().c_str(), "w+b");
|
||||
#endif
|
||||
}
|
||||
|
||||
File::File() noexcept {
|
||||
@@ -77,7 +89,22 @@ namespace hex::fs {
|
||||
if (bytes.empty())
|
||||
return "";
|
||||
|
||||
return { reinterpret_cast<char *>(bytes.data()), bytes.size() };
|
||||
auto cString = reinterpret_cast<const char *>(bytes.data());
|
||||
return { cString, std::min(bytes.size(), std::strlen(cString)) };
|
||||
}
|
||||
|
||||
std::u8string File::readU8String(size_t numBytes) {
|
||||
if (!isValid()) return {};
|
||||
|
||||
if (getSize() == 0) return {};
|
||||
|
||||
auto bytes = readBytes(numBytes);
|
||||
|
||||
if (bytes.empty())
|
||||
return u8"";
|
||||
|
||||
auto cString = reinterpret_cast<const char8_t *>(bytes.data());
|
||||
return { cString, std::min(bytes.size(), std::strlen(reinterpret_cast<const char*>(bytes.data()))) };
|
||||
}
|
||||
|
||||
void File::write(const u8 *buffer, size_t size) {
|
||||
@@ -98,6 +125,12 @@ namespace hex::fs {
|
||||
std::fwrite(string.data(), string.size(), 1, this->m_file);
|
||||
}
|
||||
|
||||
void File::write(const std::u8string &string) {
|
||||
if (!isValid()) return;
|
||||
|
||||
std::fwrite(string.data(), string.size(), 1, this->m_file);
|
||||
}
|
||||
|
||||
size_t File::getSize() const {
|
||||
if (!isValid()) return 0;
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#include <hex/helpers/fs.hpp>
|
||||
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/helpers/fs_macos.h>
|
||||
#include <hex/helpers/fs_macos.hpp>
|
||||
#include <hex/helpers/file.hpp>
|
||||
#include <hex/helpers/intrinsics.hpp>
|
||||
#include <hex/helpers/net.hpp>
|
||||
|
||||
#include <xdg.hpp>
|
||||
|
||||
@@ -22,8 +23,8 @@ namespace hex::fs {
|
||||
|
||||
std::optional<std::fs::path> getExecutablePath() {
|
||||
#if defined(OS_WINDOWS)
|
||||
std::string exePath(MAX_PATH, '\0');
|
||||
if (GetModuleFileName(nullptr, exePath.data(), exePath.length()) == 0)
|
||||
std::wstring exePath(MAX_PATH, '\0');
|
||||
if (GetModuleFileNameW(nullptr, exePath.data(), exePath.length()) == 0)
|
||||
return std::nullopt;
|
||||
|
||||
return exePath;
|
||||
@@ -34,7 +35,15 @@ namespace hex::fs {
|
||||
|
||||
return exePath;
|
||||
#elif defined(OS_MACOS)
|
||||
return getMacExecutableDirectoryPath();
|
||||
std::string result;
|
||||
|
||||
{
|
||||
auto string = getMacExecutableDirectoryPath();
|
||||
result = string;
|
||||
macFree(string);
|
||||
}
|
||||
|
||||
return result;
|
||||
#else
|
||||
return std::nullopt;
|
||||
#endif
|
||||
@@ -62,7 +71,7 @@ namespace hex::fs {
|
||||
bool openFileBrowser(DialogMode mode, const std::vector<nfdfilteritem_t> &validExtensions, const std::function<void(std::fs::path)> &callback, const std::string &defaultPath) {
|
||||
NFD::Init();
|
||||
|
||||
nfdchar_t *outPath;
|
||||
nfdchar_t *outPath = nullptr;
|
||||
nfdresult_t result;
|
||||
switch (mode) {
|
||||
case DialogMode::Open:
|
||||
@@ -78,8 +87,8 @@ namespace hex::fs {
|
||||
hex::unreachable();
|
||||
}
|
||||
|
||||
if (result == NFD_OKAY) {
|
||||
callback(reinterpret_cast<const char8_t *>(outPath));
|
||||
if (result == NFD_OKAY && outPath != nullptr) {
|
||||
callback(reinterpret_cast<char8_t*>(outPath));
|
||||
NFD::FreePath(outPath);
|
||||
}
|
||||
|
||||
@@ -92,8 +101,7 @@ namespace hex::fs {
|
||||
std::vector<std::fs::path> getDefaultPaths(ImHexPath path, bool listNonExisting) {
|
||||
std::vector<std::fs::path> result;
|
||||
const auto exePath = getExecutablePath();
|
||||
const std::string settingName { "hex.builtin.setting.folders" };
|
||||
auto userDirs = ContentRegistry::Settings::read(settingName, settingName, std::vector<std::string> {});
|
||||
auto userDirs = ImHexApi::System::getAdditionalFolderPaths();
|
||||
|
||||
[[maybe_unused]]
|
||||
auto addUserDirs = [&userDirs](auto &paths) {
|
||||
@@ -105,11 +113,11 @@ namespace hex::fs {
|
||||
#if defined(OS_WINDOWS)
|
||||
std::fs::path appDataDir;
|
||||
{
|
||||
LPWSTR wAppDataPath = nullptr;
|
||||
PWSTR wAppDataPath = nullptr;
|
||||
if (!SUCCEEDED(SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_CREATE, nullptr, &wAppDataPath)))
|
||||
throw std::runtime_error("Failed to get APPDATA folder path");
|
||||
|
||||
appDataDir = wAppDataPath;
|
||||
appDataDir = std::wstring(wAppDataPath);
|
||||
CoTaskMemFree(wAppDataPath);
|
||||
}
|
||||
|
||||
@@ -122,60 +130,60 @@ namespace hex::fs {
|
||||
case ImHexPath::Patterns:
|
||||
addUserDirs(paths);
|
||||
std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) {
|
||||
return (path / "patterns").string();
|
||||
return path / "patterns";
|
||||
});
|
||||
break;
|
||||
case ImHexPath::PatternsInclude:
|
||||
addUserDirs(paths);
|
||||
std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) {
|
||||
return (path / "includes").string();
|
||||
return path / "includes";
|
||||
});
|
||||
break;
|
||||
case ImHexPath::Magic:
|
||||
addUserDirs(paths);
|
||||
std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) {
|
||||
return (path / "magic").string();
|
||||
return path / "magic";
|
||||
});
|
||||
break;
|
||||
case ImHexPath::Python:
|
||||
addUserDirs(paths);
|
||||
std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) {
|
||||
return (path / "python").string();
|
||||
return path / "python";
|
||||
});
|
||||
break;
|
||||
case ImHexPath::Plugins:
|
||||
std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) {
|
||||
return (path / "plugins").string();
|
||||
return path / "plugins";
|
||||
});
|
||||
break;
|
||||
case ImHexPath::Yara:
|
||||
addUserDirs(paths);
|
||||
std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) {
|
||||
return (path / "yara").string();
|
||||
return path / "yara";
|
||||
});
|
||||
break;
|
||||
case ImHexPath::Config:
|
||||
return { (appDataDir / "imhex" / "config").string() };
|
||||
return { appDataDir / "imhex" / "config" };
|
||||
case ImHexPath::Resources:
|
||||
std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) {
|
||||
return (path / "resources").string();
|
||||
return path / "resources";
|
||||
});
|
||||
break;
|
||||
case ImHexPath::Constants:
|
||||
addUserDirs(paths);
|
||||
std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) {
|
||||
return (path / "constants").string();
|
||||
return path / "constants";
|
||||
});
|
||||
break;
|
||||
case ImHexPath::Encodings:
|
||||
addUserDirs(paths);
|
||||
std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) {
|
||||
return (path / "encodings").string();
|
||||
return path / "encodings";
|
||||
});
|
||||
break;
|
||||
case ImHexPath::Logs:
|
||||
std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) {
|
||||
return (path / "logs").string();
|
||||
return path / "logs";
|
||||
});
|
||||
break;
|
||||
default:
|
||||
@@ -183,48 +191,54 @@ namespace hex::fs {
|
||||
}
|
||||
#elif defined(OS_MACOS)
|
||||
// Get path to special directories
|
||||
const std::fs::path applicationSupportDir(getMacApplicationSupportDirectoryPath());
|
||||
std::string applicationSupportDir;
|
||||
{
|
||||
auto string = getMacApplicationSupportDirectoryPath();
|
||||
applicationSupportDir = string;
|
||||
macFree(string);
|
||||
}
|
||||
const std::fs::path applicationSupportDirPath(applicationSupportDir);
|
||||
|
||||
std::vector<std::fs::path> paths = { applicationSupportDir };
|
||||
std::vector<std::fs::path> paths = { applicationSupportDirPath };
|
||||
|
||||
if (exePath)
|
||||
paths.push_back(exePath->parent_path());
|
||||
if (exePath.has_value())
|
||||
paths.push_back(exePath.value());
|
||||
|
||||
switch (path) {
|
||||
case ImHexPath::Patterns:
|
||||
result.push_back((applicationSupportDir / "patterns").string());
|
||||
result.push_back(applicationSupportDirPath / "patterns");
|
||||
break;
|
||||
case ImHexPath::PatternsInclude:
|
||||
result.push_back((applicationSupportDir / "includes").string());
|
||||
result.push_back(applicationSupportDirPath / "includes");
|
||||
break;
|
||||
case ImHexPath::Magic:
|
||||
result.push_back((applicationSupportDir / "magic").string());
|
||||
result.push_back(applicationSupportDirPath / "magic");
|
||||
break;
|
||||
case ImHexPath::Python:
|
||||
result.push_back((applicationSupportDir / "python").string());
|
||||
result.push_back(applicationSupportDirPath / "python");
|
||||
break;
|
||||
case ImHexPath::Plugins:
|
||||
std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) {
|
||||
return (path / "plugins").string();
|
||||
return path / "plugins";
|
||||
});
|
||||
break;
|
||||
case ImHexPath::Yara:
|
||||
result.push_back((applicationSupportDir / "yara").string());
|
||||
result.push_back(applicationSupportDirPath / "yara");
|
||||
break;
|
||||
case ImHexPath::Config:
|
||||
result.push_back((applicationSupportDir / "config").string());
|
||||
result.push_back(applicationSupportDirPath / "config");
|
||||
break;
|
||||
case ImHexPath::Resources:
|
||||
result.push_back((applicationSupportDir / "resources").string());
|
||||
result.push_back(applicationSupportDirPath / "resources");
|
||||
break;
|
||||
case ImHexPath::Constants:
|
||||
result.push_back((applicationSupportDir / "constants").string());
|
||||
result.push_back(applicationSupportDirPath / "constants");
|
||||
break;
|
||||
case ImHexPath::Encodings:
|
||||
result.push_back((applicationSupportDir / "encodings").string());
|
||||
result.push_back(applicationSupportDirPath / "encodings");
|
||||
break;
|
||||
case ImHexPath::Logs:
|
||||
result.push_back((applicationSupportDir / "logs").string());
|
||||
result.push_back(applicationSupportDirPath / "logs");
|
||||
break;
|
||||
default:
|
||||
hex::unreachable();
|
||||
@@ -233,8 +247,8 @@ namespace hex::fs {
|
||||
std::vector<std::fs::path> configDirs = xdg::ConfigDirs();
|
||||
std::vector<std::fs::path> dataDirs = xdg::DataDirs();
|
||||
|
||||
configDirs.push_back(xdg::ConfigHomeDir());
|
||||
dataDirs.push_back(xdg::DataHomeDir());
|
||||
configDirs.insert(configDirs.begin(), xdg::ConfigHomeDir());
|
||||
dataDirs.insert(dataDirs.begin(), xdg::DataHomeDir());
|
||||
|
||||
for (auto &dir : dataDirs)
|
||||
dir = dir / "imhex";
|
||||
@@ -245,43 +259,43 @@ namespace hex::fs {
|
||||
switch (path) {
|
||||
case ImHexPath::Patterns:
|
||||
addUserDirs(dataDirs);
|
||||
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return (p / "patterns").string(); });
|
||||
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "patterns"; });
|
||||
break;
|
||||
case ImHexPath::PatternsInclude:
|
||||
addUserDirs(dataDirs);
|
||||
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return (p / "includes").string(); });
|
||||
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "includes"; });
|
||||
break;
|
||||
case ImHexPath::Magic:
|
||||
addUserDirs(dataDirs);
|
||||
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return (p / "magic").string(); });
|
||||
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "magic"; });
|
||||
break;
|
||||
case ImHexPath::Python:
|
||||
addUserDirs(dataDirs);
|
||||
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return (p).string(); });
|
||||
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p; });
|
||||
break;
|
||||
case ImHexPath::Plugins:
|
||||
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return (p / "plugins").string(); });
|
||||
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "plugins"; });
|
||||
break;
|
||||
case ImHexPath::Yara:
|
||||
addUserDirs(dataDirs);
|
||||
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return (p / "yara").string(); });
|
||||
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "yara"; });
|
||||
break;
|
||||
case ImHexPath::Config:
|
||||
std::transform(configDirs.begin(), configDirs.end(), std::back_inserter(result), [](auto p) { return (p / "imhex").string(); });
|
||||
std::transform(configDirs.begin(), configDirs.end(), std::back_inserter(result), [](auto p) { return p / "imhex"; });
|
||||
break;
|
||||
case ImHexPath::Resources:
|
||||
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return (p / "resources").string(); });
|
||||
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "resources"; });
|
||||
break;
|
||||
case ImHexPath::Constants:
|
||||
addUserDirs(dataDirs);
|
||||
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return (p / "constants").string(); });
|
||||
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "constants"; });
|
||||
break;
|
||||
case ImHexPath::Encodings:
|
||||
addUserDirs(dataDirs);
|
||||
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return (p / "encodings").string(); });
|
||||
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "encodings"; });
|
||||
break;
|
||||
case ImHexPath::Logs:
|
||||
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return (p / "logs").string(); });
|
||||
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "logs"; });
|
||||
break;
|
||||
default:
|
||||
hex::unreachable();
|
||||
@@ -299,4 +313,20 @@ namespace hex::fs {
|
||||
return result;
|
||||
}
|
||||
|
||||
std::fs::path toShortPath(const std::fs::path &path) {
|
||||
#if defined(OS_WINDOWS)
|
||||
size_t size = GetShortPathNameW(path.c_str(), nullptr, 0) * sizeof(TCHAR);
|
||||
if (size == 0)
|
||||
return path;
|
||||
|
||||
std::wstring newPath(size, 0x00);
|
||||
GetShortPathNameW(path.c_str(), newPath.data(), newPath.size());
|
||||
|
||||
return newPath;
|
||||
#else
|
||||
return path;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
44
lib/libimhex/source/helpers/fs_macos.m
Normal file
44
lib/libimhex/source/helpers/fs_macos.m
Normal file
@@ -0,0 +1,44 @@
|
||||
#if defined(OS_MACOS)
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
char* getMacExecutableDirectoryPath() {
|
||||
@autoreleasepool {
|
||||
const char *pathString = [[[[[NSBundle mainBundle] executableURL] URLByDeletingLastPathComponent] path] UTF8String];
|
||||
|
||||
char *result = malloc(strlen(pathString) + 1);
|
||||
strcpy(result, pathString);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
char* getMacApplicationSupportDirectoryPath() {
|
||||
@autoreleasepool {
|
||||
NSError* error = nil;
|
||||
NSURL* dirUrl = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory
|
||||
inDomain:NSUserDomainMask
|
||||
appropriateForURL:nil
|
||||
create:YES
|
||||
error:&error];
|
||||
|
||||
if (error != nil) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *pathString = [[[dirUrl URLByAppendingPathComponent:(@"imhex")] path] UTF8String];
|
||||
|
||||
char *result = malloc(strlen(pathString) + 1);
|
||||
strcpy(result, pathString);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
void macFree(void *ptr) {
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,30 +0,0 @@
|
||||
#if defined(OS_MACOS)
|
||||
#include <hex/helpers/fs_macos.h>
|
||||
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
namespace hex {
|
||||
std::string getMacExecutableDirectoryPath() {
|
||||
@autoreleasepool {
|
||||
return {[[[[[NSBundle mainBundle] executableURL] URLByDeletingLastPathComponent] path] UTF8String]};
|
||||
}
|
||||
}
|
||||
|
||||
std::string getMacApplicationSupportDirectoryPath() {
|
||||
@autoreleasepool {
|
||||
NSError* error = nil;
|
||||
NSURL* dirUrl = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory
|
||||
inDomain:NSUserDomainMask
|
||||
appropriateForURL:nil
|
||||
create:YES
|
||||
error:&error];
|
||||
|
||||
if (error != nil) {
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
return {[[[dirUrl URLByAppendingPathComponent:(@"imhex")] path] UTF8String]};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,248 +0,0 @@
|
||||
#include <hex/helpers/loader_script_handler.hpp>
|
||||
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/fs.hpp>
|
||||
#include <hex/helpers/file.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
#include <hex/providers/provider.hpp>
|
||||
#include <hex/helpers/intrinsics.hpp>
|
||||
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include <Python.h>
|
||||
#include <structmember.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
|
||||
using namespace std::literals::string_literals;
|
||||
|
||||
namespace hex {
|
||||
|
||||
PyObject *LoaderScript::Py_getFilePath(PyObject *self, PyObject *args) {
|
||||
hex::unused(self, args);
|
||||
|
||||
return PyUnicode_FromString(LoaderScript::s_filePath.string().c_str());
|
||||
}
|
||||
|
||||
PyObject *LoaderScript::Py_addPatch(PyObject *self, PyObject *args) {
|
||||
hex::unused(self);
|
||||
|
||||
u64 address;
|
||||
u8 *patches;
|
||||
Py_ssize_t count;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "K|y#", &address, &patches, &count)) {
|
||||
PyErr_BadArgument();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (patches == nullptr || count == 0) {
|
||||
PyErr_SetString(PyExc_TypeError, "Invalid patch provided");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (address >= LoaderScript::s_dataProvider->getActualSize()) {
|
||||
PyErr_SetString(PyExc_IndexError, "address out of range");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LoaderScript::s_dataProvider->write(address, patches, count);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject *LoaderScript::Py_addBookmark(PyObject *self, PyObject *args) {
|
||||
hex::unused(self);
|
||||
|
||||
u64 address;
|
||||
size_t size;
|
||||
|
||||
char *name = nullptr;
|
||||
char *comment = nullptr;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "K|n|s|s", &address, &size, &name, &comment)) {
|
||||
PyErr_BadArgument();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (name == nullptr || comment == nullptr) {
|
||||
PyErr_SetString(PyExc_IndexError, "address out of range");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ImHexApi::Bookmarks::add(address, size, name, comment);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *createStructureType(const std::string &keyword, PyObject *args) {
|
||||
if (args == nullptr) {
|
||||
PyErr_BadArgument();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto type = PyTuple_GetItem(args, 0);
|
||||
if (type == nullptr) {
|
||||
PyErr_BadArgument();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto instance = PyObject_CallObject(type, nullptr);
|
||||
if (instance == nullptr) {
|
||||
PyErr_BadArgument();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ON_SCOPE_EXIT { Py_DECREF(instance); };
|
||||
|
||||
if (instance->ob_type->tp_base == nullptr || instance->ob_type->tp_base->tp_name != "ImHexType"s) {
|
||||
PyErr_SetString(PyExc_TypeError, "class type must extend from ImHexType");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto dict = instance->ob_type->tp_dict;
|
||||
if (dict == nullptr) {
|
||||
PyErr_BadArgument();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto annotations = PyDict_GetItemString(dict, "__annotations__");
|
||||
if (annotations == nullptr) {
|
||||
PyErr_BadArgument();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto list = PyDict_Items(annotations);
|
||||
if (list == nullptr) {
|
||||
PyErr_BadArgument();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ON_SCOPE_EXIT { Py_DECREF(list); };
|
||||
|
||||
std::string code = keyword + " " + instance->ob_type->tp_name + " {\n";
|
||||
|
||||
for (Py_ssize_t i = 0; i < PyList_Size(list); i++) {
|
||||
auto item = PyList_GetItem(list, i);
|
||||
if (item == nullptr) {
|
||||
PyErr_SetString(PyExc_TypeError, "failed to get item from list");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto memberName = PyUnicode_AsUTF8(PyTuple_GetItem(item, 0));
|
||||
if (memberName == nullptr) {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid member name");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto memberType = PyTuple_GetItem(item, 1);
|
||||
if (!PyTuple_Check(memberType) || memberType == nullptr) {
|
||||
PyErr_SetString(PyExc_TypeError, "member needs to have a annotation extending from ImHexType");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Array already is an object
|
||||
if (memberType->ob_type->tp_name == "array"s) {
|
||||
|
||||
auto arrayType = PyObject_GetAttrString(memberType, "array_type");
|
||||
if (arrayType == nullptr) {
|
||||
PyErr_BadArgument();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
code += " "s + arrayType->ob_type->tp_name + " " + memberName;
|
||||
|
||||
auto arraySize = PyObject_GetAttrString(memberType, "size");
|
||||
if (arraySize == nullptr) {
|
||||
PyErr_BadArgument();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (PyUnicode_Check(arraySize))
|
||||
code += "["s + PyUnicode_AsUTF8(arraySize) + "];\n";
|
||||
else if (PyLong_Check(arraySize))
|
||||
code += "["s + std::to_string(PyLong_AsLong(arraySize)) + "];\n";
|
||||
} else {
|
||||
auto memberTypeInstance = PyObject_CallObject(memberType, nullptr);
|
||||
if (memberTypeInstance == nullptr || memberTypeInstance->ob_type->tp_base == nullptr || memberTypeInstance->ob_type->tp_base->tp_name != "ImHexType"s) {
|
||||
PyErr_SetString(PyExc_TypeError, "member needs to have a annotation extending from ImHexType");
|
||||
if (memberTypeInstance != nullptr)
|
||||
Py_DECREF(memberTypeInstance);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
code += " "s + memberTypeInstance->ob_type->tp_name + " "s + memberName + ";\n";
|
||||
|
||||
Py_DECREF(memberTypeInstance);
|
||||
}
|
||||
}
|
||||
|
||||
code += "};\n";
|
||||
|
||||
EventManager::post<RequestSetPatternLanguageCode>(code);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject *LoaderScript::Py_addStruct(PyObject *self, PyObject *args) {
|
||||
hex::unused(self);
|
||||
|
||||
return createStructureType("struct", args);
|
||||
}
|
||||
|
||||
PyObject *LoaderScript::Py_addUnion(PyObject *self, PyObject *args) {
|
||||
hex::unused(self);
|
||||
|
||||
return createStructureType("union", args);
|
||||
}
|
||||
|
||||
bool LoaderScript::processFile(const std::fs::path &scriptPath) {
|
||||
Py_SetProgramName(Py_DecodeLocale("ImHex", nullptr));
|
||||
|
||||
for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Python)) {
|
||||
if (fs::exists(std::fs::path(dir / "lib" / "python" PYTHON_VERSION_MAJOR_MINOR))) {
|
||||
Py_SetPythonHome(Py_DecodeLocale(dir.string().c_str(), nullptr));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PyImport_AppendInittab("_imhex", []() -> PyObject * {
|
||||
static PyMethodDef ImHexMethods[] = {
|
||||
{"get_file_path", &LoaderScript::Py_getFilePath, METH_NOARGS, "Returns the path of the file being loaded."},
|
||||
{ "patch", &LoaderScript::Py_addPatch, METH_VARARGS, "Patches a region of memory" },
|
||||
{ "add_bookmark", &LoaderScript::Py_addBookmark, METH_VARARGS, "Adds a bookmark" },
|
||||
{ "add_struct", &LoaderScript::Py_addStruct, METH_VARARGS, "Adds a struct" },
|
||||
{ "add_union", &LoaderScript::Py_addUnion, METH_VARARGS, "Adds a union" },
|
||||
{ nullptr, nullptr, 0, nullptr }
|
||||
};
|
||||
|
||||
static PyModuleDef ImHexModule = {
|
||||
PyModuleDef_HEAD_INIT, "imhex", nullptr, -1, ImHexMethods, nullptr, nullptr, nullptr, nullptr
|
||||
};
|
||||
|
||||
auto module = PyModule_Create(&ImHexModule);
|
||||
if (module == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return module;
|
||||
});
|
||||
|
||||
Py_Initialize();
|
||||
|
||||
{
|
||||
auto sysPath = PySys_GetObject("path");
|
||||
auto path = PyUnicode_FromString("lib");
|
||||
|
||||
PyList_Insert(sysPath, 0, path);
|
||||
}
|
||||
|
||||
fs::File scriptFile(scriptPath, fs::File::Mode::Read);
|
||||
PyRun_SimpleFile(scriptFile.getHandle(), scriptFile.getPath().string().c_str());
|
||||
|
||||
Py_Finalize();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,8 +26,9 @@ namespace hex::magic {
|
||||
std::error_code error;
|
||||
for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Magic)) {
|
||||
for (const auto &entry : std::fs::directory_iterator(dir, error)) {
|
||||
if (entry.is_regular_file() && ((sourceFiles && entry.path().extension().empty()) || (!sourceFiles && entry.path().extension() == ".mgc")))
|
||||
magicFiles += entry.path().string() + MAGIC_PATH_SEPARATOR;
|
||||
if (entry.is_regular_file() && ((sourceFiles && entry.path().extension().empty()) || (!sourceFiles && entry.path().extension() == ".mgc"))) {
|
||||
magicFiles += fs::toShortPath(entry.path()).string() + MAGIC_PATH_SEPARATOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <hex/helpers/file.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
#include <hex/api/content_registry.hpp>
|
||||
|
||||
#include <filesystem>
|
||||
#include <cstdio>
|
||||
|
||||
@@ -113,12 +115,14 @@ namespace hex {
|
||||
curl_easy_setopt(this->m_ctx, CURLOPT_SSLCERTTYPE, "PEM");
|
||||
curl_easy_setopt(this->m_ctx, CURLOPT_SSL_CTX_FUNCTION, sslCtxFunction);
|
||||
#endif
|
||||
|
||||
curl_easy_setopt(this->m_ctx, CURLOPT_PROXY, Net::s_proxyUrl.c_str());
|
||||
}
|
||||
|
||||
std::optional<i32> Net::execute() {
|
||||
CURLcode result = curl_easy_perform(this->m_ctx);
|
||||
if (result != CURLE_OK)
|
||||
log::error("Net request failed with error {0}: '{1}'", result, curl_easy_strerror(result));
|
||||
log::error("Net request failed with error {0}: '{1}'", u32(result), curl_easy_strerror(result));
|
||||
|
||||
i32 responseCode = 0;
|
||||
curl_easy_getinfo(this->m_ctx, CURLINFO_RESPONSE_CODE, &responseCode);
|
||||
@@ -176,7 +180,7 @@ namespace hex {
|
||||
|
||||
ON_SCOPE_EXIT { this->m_transmissionActive.unlock(); };
|
||||
|
||||
fs::File file(filePath.string(), fs::File::Mode::Read);
|
||||
fs::File file(filePath, fs::File::Mode::Read);
|
||||
if (!file.isValid())
|
||||
return Response<std::string> { 400, {} };
|
||||
|
||||
@@ -214,7 +218,7 @@ namespace hex {
|
||||
|
||||
ON_SCOPE_EXIT { this->m_transmissionActive.unlock(); };
|
||||
|
||||
fs::File file(filePath.string(), fs::File::Mode::Create);
|
||||
fs::File file(filePath, fs::File::Mode::Create);
|
||||
if (!file.isValid())
|
||||
return Response<void> { 400 };
|
||||
|
||||
@@ -241,4 +245,23 @@ namespace hex {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string Net::decode(const std::string &input) {
|
||||
auto unescapedString = curl_easy_unescape(this->m_ctx, input.c_str(), std::strlen(input.c_str()), nullptr);
|
||||
|
||||
if (unescapedString != nullptr) {
|
||||
std::string output = unescapedString;
|
||||
curl_free(unescapedString);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string Net::s_proxyUrl;
|
||||
|
||||
void Net::setProxy(const std::string &url) {
|
||||
Net::s_proxyUrl = url;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -52,10 +52,10 @@ namespace hex {
|
||||
json projectFileData;
|
||||
|
||||
try {
|
||||
std::ifstream projectFile(filePath.c_str());
|
||||
std::ifstream projectFile(filePath);
|
||||
projectFile >> projectFileData;
|
||||
|
||||
ProjectFile::s_filePath = std::fs::path(projectFileData["filePath"].get<std::string>());
|
||||
ProjectFile::s_filePath = std::fs::path(projectFileData["filePath"].get<std::u8string>());
|
||||
ProjectFile::s_pattern = projectFileData["pattern"];
|
||||
ProjectFile::s_patches = projectFileData["patches"].get<Patches>();
|
||||
ProjectFile::s_dataProcessorContent = projectFileData["dataProcessor"];
|
||||
@@ -89,7 +89,7 @@ namespace hex {
|
||||
filePath = ProjectFile::s_currProjectFilePath;
|
||||
|
||||
try {
|
||||
projectFileData["filePath"] = ProjectFile::s_filePath.string();
|
||||
projectFileData["filePath"] = ProjectFile::s_filePath.u8string();
|
||||
projectFileData["pattern"] = ProjectFile::s_pattern;
|
||||
projectFileData["patches"] = ProjectFile::s_patches;
|
||||
projectFileData["dataProcessor"] = ProjectFile::s_dataProcessorContent;
|
||||
|
||||
99
lib/libimhex/source/helpers/tar.cpp
Normal file
99
lib/libimhex/source/helpers/tar.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
#include <hex/helpers/tar.hpp>
|
||||
#include <hex/helpers/literals.hpp>
|
||||
#include <hex/helpers/file.hpp>
|
||||
|
||||
namespace hex {
|
||||
|
||||
using namespace hex::literals;
|
||||
|
||||
Tar::Tar(const std::fs::path &path, Mode mode) {
|
||||
if (mode == Tar::Mode::Read)
|
||||
mtar_open(&this->m_ctx, path.string().c_str(), "r");
|
||||
else if (mode == Tar::Mode::Write)
|
||||
mtar_open(&this->m_ctx, path.string().c_str(), "a");
|
||||
else if (mode == Tar::Mode::Create)
|
||||
mtar_open(&this->m_ctx, path.string().c_str(), "w");
|
||||
}
|
||||
|
||||
Tar::~Tar() {
|
||||
mtar_finalize(&this->m_ctx);
|
||||
mtar_close(&this->m_ctx);
|
||||
}
|
||||
|
||||
std::vector<std::fs::path> Tar::listEntries() {
|
||||
std::vector<std::fs::path> result;
|
||||
|
||||
const std::string PaxHeaderName = "@PaxHeader";
|
||||
mtar_header_t header;
|
||||
while (mtar_read_header(&this->m_ctx, &header) != MTAR_ENULLRECORD) {
|
||||
if (header.name != PaxHeaderName) {
|
||||
result.emplace_back(header.name);
|
||||
}
|
||||
|
||||
mtar_next(&this->m_ctx);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<u8> Tar::read(const std::fs::path &path) {
|
||||
mtar_header_t header;
|
||||
mtar_find(&this->m_ctx, path.string().c_str(), &header);
|
||||
|
||||
std::vector<u8> result(header.size, 0x00);
|
||||
mtar_read_data(&this->m_ctx, result.data(), result.size());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Tar::write(const std::fs::path &path, const std::vector<u8> &data) {
|
||||
if (path.has_parent_path()) {
|
||||
std::fs::path pathPart;
|
||||
for (const auto &part : path.parent_path()) {
|
||||
pathPart /= part;
|
||||
mtar_write_dir_header(&this->m_ctx, pathPart.string().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
mtar_write_file_header(&this->m_ctx, path.string().c_str(), data.size());
|
||||
mtar_write_data(&this->m_ctx, data.data(), data.size());
|
||||
}
|
||||
|
||||
static void writeFile(mtar_t *ctx, mtar_header_t *header, const std::fs::path &path) {
|
||||
constexpr static u64 BufferSize = 1_MiB;
|
||||
|
||||
fs::File outputFile(path, fs::File::Mode::Create);
|
||||
|
||||
std::vector<u8> buffer;
|
||||
for (u64 offset = 0; offset < header->size; offset += BufferSize) {
|
||||
buffer.resize(std::min<u64>(BufferSize, header->size - offset));
|
||||
|
||||
mtar_read_data(ctx, buffer.data(), buffer.size());
|
||||
outputFile.write(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void Tar::extract(const std::fs::path &path, const std::fs::path &outputPath) {
|
||||
mtar_header_t header;
|
||||
mtar_find(&this->m_ctx, path.string().c_str(), &header);
|
||||
|
||||
writeFile(&this->m_ctx, &header, outputPath);
|
||||
}
|
||||
|
||||
void Tar::extractAll(const std::fs::path &outputPath) {
|
||||
mtar_header_t header;
|
||||
while (mtar_read_header(&this->m_ctx, &header) != MTAR_ENULLRECORD) {
|
||||
const auto filePath = std::fs::absolute(outputPath / std::fs::path(header.name));
|
||||
|
||||
if (filePath.filename() != "@PaxHeader") {
|
||||
|
||||
std::fs::create_directories(filePath.parent_path());
|
||||
|
||||
writeFile(&this->m_ctx, &header, filePath);
|
||||
}
|
||||
|
||||
mtar_next(&this->m_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
#include <cstdio>
|
||||
#include <codecvt>
|
||||
#include <locale>
|
||||
#include <filesystem>
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
|
||||
@@ -18,13 +16,10 @@
|
||||
#elif defined(OS_LINUX)
|
||||
#include <unistd.h>
|
||||
#elif defined(OS_MACOS)
|
||||
#include <CoreFoundation/CFBundle.h>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#include <hex/helpers/utils_macos.hpp>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <hex/helpers/logger.hpp>
|
||||
#include <hex/helpers/file.hpp>
|
||||
|
||||
namespace hex {
|
||||
|
||||
long double operator""_scaled(long double value) {
|
||||
@@ -83,29 +78,34 @@ namespace hex {
|
||||
break;
|
||||
}
|
||||
|
||||
std::string result = hex::format("{0:.2f}", value);
|
||||
std::string result;
|
||||
|
||||
if (unitIndex == 0)
|
||||
result = hex::format("{0:}", value);
|
||||
else
|
||||
result = hex::format("{0:.2f}", value);
|
||||
|
||||
switch (unitIndex) {
|
||||
case 0:
|
||||
result += " Bytes";
|
||||
result += ((value == 1) ? " Byte" : " Bytes");
|
||||
break;
|
||||
case 1:
|
||||
result += " kB";
|
||||
result += " kiB";
|
||||
break;
|
||||
case 2:
|
||||
result += " MB";
|
||||
result += " MiB";
|
||||
break;
|
||||
case 3:
|
||||
result += " GB";
|
||||
result += " GiB";
|
||||
break;
|
||||
case 4:
|
||||
result += " TB";
|
||||
result += " TiB";
|
||||
break;
|
||||
case 5:
|
||||
result += " PB";
|
||||
result += " PiB";
|
||||
break;
|
||||
case 6:
|
||||
result += " EB";
|
||||
result += " EiB";
|
||||
break;
|
||||
default:
|
||||
result = "A lot!";
|
||||
@@ -252,13 +252,14 @@ namespace hex {
|
||||
|
||||
void runCommand(const std::string &command) {
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
auto result = system(hex::format("start {0}", command).c_str());
|
||||
#elif defined(OS_MACOS)
|
||||
auto result = system(hex::format("open {0}", command).c_str());
|
||||
#elif defined(OS_LINUX)
|
||||
auto result = system(hex::format("xdg-open {0}", command).c_str());
|
||||
#endif
|
||||
#if defined(OS_WINDOWS)
|
||||
auto result = system(hex::format("start {0}", command).c_str());
|
||||
#elif defined(OS_MACOS)
|
||||
auto result = system(hex::format("open {0}", command).c_str());
|
||||
#elif defined(OS_LINUX)
|
||||
auto result = system(hex::format("xdg-open {0}", command).c_str());
|
||||
#endif
|
||||
|
||||
hex::unused(result);
|
||||
}
|
||||
|
||||
@@ -267,18 +268,16 @@ namespace hex {
|
||||
if (url.find("://") == std::string::npos)
|
||||
url = "https://" + url;
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
ShellExecute(nullptr, "open", url.c_str(), nullptr, nullptr, SW_SHOWNORMAL);
|
||||
#elif defined(OS_MACOS)
|
||||
CFURLRef urlRef = CFURLCreateWithBytes(nullptr, reinterpret_cast<u8 *>(url.data()), url.length(), kCFStringEncodingASCII, nullptr);
|
||||
LSOpenCFURLRef(urlRef, nullptr);
|
||||
CFRelease(urlRef);
|
||||
#elif defined(OS_LINUX)
|
||||
auto result = system(hex::format("xdg-open {0}", url).c_str());
|
||||
hex::unused(result);
|
||||
#else
|
||||
#warning "Unknown OS, can't open webpages"
|
||||
#endif
|
||||
#if defined(OS_WINDOWS)
|
||||
ShellExecute(nullptr, "open", url.c_str(), nullptr, nullptr, SW_SHOWNORMAL);
|
||||
#elif defined(OS_MACOS)
|
||||
openWebpageMacos(url.c_str());
|
||||
#elif defined(OS_LINUX)
|
||||
auto result = system(hex::format("xdg-open {0}", url).c_str());
|
||||
hex::unused(result);
|
||||
#else
|
||||
#warning "Unknown OS, can't open webpages"
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string encodeByteString(const std::vector<u8> &bytes) {
|
||||
|
||||
28
lib/libimhex/source/helpers/utils_macos.m
Normal file
28
lib/libimhex/source/helpers/utils_macos.m
Normal file
@@ -0,0 +1,28 @@
|
||||
#if defined(OS_MACOS)
|
||||
|
||||
#include <CoreFoundation/CFBundle.h>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#include <Foundation/NSUserDefaults.h>
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void openWebpageMacos(const char *url) {
|
||||
CFURLRef urlRef = CFURLCreateWithBytes(NULL, (uint8_t*)(url), strlen(url), kCFStringEncodingASCII, NULL);
|
||||
LSOpenCFURLRef(urlRef, NULL);
|
||||
CFRelease(urlRef);
|
||||
}
|
||||
|
||||
bool isMacosSystemDarkModeEnabled() {
|
||||
NSString * appleInterfaceStyle = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
|
||||
|
||||
if (appleInterfaceStyle && [appleInterfaceStyle length] > 0) {
|
||||
return [[appleInterfaceStyle lowercaseString] containsString:@"dark"];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -2,25 +2,17 @@
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/api/event.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include <pl/pattern_language.hpp>
|
||||
|
||||
namespace hex::prv {
|
||||
|
||||
Provider::Provider() {
|
||||
this->m_patches.emplace_back();
|
||||
this->m_patternLanguageRuntime = ContentRegistry::PatternLanguage::createDefaultRuntime(this);
|
||||
|
||||
if (this->hasLoadInterface())
|
||||
EventManager::post<RequestOpenPopup>(View::toWindowName("hex.builtin.view.provider_settings.load_popup"));
|
||||
}
|
||||
|
||||
Provider::~Provider() {
|
||||
@@ -63,6 +55,22 @@ namespace hex::prv {
|
||||
patches.insert({ address + size, value });
|
||||
}
|
||||
|
||||
void Provider::remove(u64 offset, size_t size) {
|
||||
auto &patches = getPatches();
|
||||
|
||||
std::vector<std::pair<u64, u8>> patchesToMove;
|
||||
|
||||
for (auto &[address, value] : patches) {
|
||||
if (address > offset)
|
||||
patchesToMove.emplace_back(address, value);
|
||||
}
|
||||
|
||||
for (const auto &[address, value] : patchesToMove)
|
||||
patches.erase(address);
|
||||
for (const auto &[address, value] : patchesToMove)
|
||||
patches.insert({ address - size, value });
|
||||
}
|
||||
|
||||
void Provider::applyOverlays(u64 offset, void *buffer, size_t size) {
|
||||
for (auto &overlay : this->m_overlays) {
|
||||
auto overlayOffset = overlay->getAddress();
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace ImGui {
|
||||
if (data->EventFlag == ImGuiInputTextFlags_CallbackResize) {
|
||||
auto &string = *static_cast<std::string *>(data->UserData);
|
||||
|
||||
string.resize(data->BufSize);
|
||||
string.resize(data->BufTextLen);
|
||||
data->Buf = string.data();
|
||||
}
|
||||
|
||||
@@ -334,8 +334,8 @@ namespace ImGui {
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
#if defined(GL_UNPACK_ROW_LENGTH)
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
@@ -487,7 +487,7 @@ namespace ImGui {
|
||||
return pressed;
|
||||
}
|
||||
|
||||
bool InputIntegerPrefix(const char *label, const char *prefix, u64 *value, ImGuiInputTextFlags flags) {
|
||||
bool InputIntegerPrefix(const char *label, const char *prefix, void *value, ImGuiDataType type, ImGuiInputTextFlags flags) {
|
||||
auto window = ImGui::GetCurrentWindow();
|
||||
const ImGuiID id = window->GetID(label);
|
||||
const ImGuiStyle &style = GImGui->Style;
|
||||
@@ -500,7 +500,7 @@ namespace ImGui {
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + frame_size.x);
|
||||
|
||||
char buf[64];
|
||||
DataTypeFormatString(buf, IM_ARRAYSIZE(buf), ImGuiDataType_U64, value, "%llX");
|
||||
DataTypeFormatString(buf, IM_ARRAYSIZE(buf), type, value, "%llX");
|
||||
|
||||
bool value_changed = false;
|
||||
if (InputTextEx(label, nullptr, buf, IM_ARRAYSIZE(buf), ImVec2(CalcItemWidth() - frame_size.x, label_size.y + style.FramePadding.y * 2.0f), flags))
|
||||
@@ -519,8 +519,12 @@ namespace ImGui {
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
bool InputHexadecimal(const char *label, u32 *value, ImGuiInputTextFlags flags) {
|
||||
return InputIntegerPrefix(label, "0x", value, ImGuiDataType_U32, flags | ImGuiInputTextFlags_CharsHexadecimal);
|
||||
}
|
||||
|
||||
bool InputHexadecimal(const char *label, u64 *value, ImGuiInputTextFlags flags) {
|
||||
return InputIntegerPrefix(label, "0x", value, flags | ImGuiInputTextFlags_CharsHexadecimal);
|
||||
return InputIntegerPrefix(label, "0x", value, ImGuiDataType_U64, flags | ImGuiInputTextFlags_CharsHexadecimal);
|
||||
}
|
||||
|
||||
void SmallProgressBar(float fraction, float yOffset) {
|
||||
@@ -549,6 +553,14 @@ namespace ImGui {
|
||||
return ImGui::InputText(label, buffer.data(), buffer.size() + 1, ImGuiInputTextFlags_CallbackResize | flags, ImGui::UpdateStringSizeCallback, &buffer);
|
||||
}
|
||||
|
||||
bool InputTextWithHint(const char *label, const char *hint, std::string &buffer, ImGuiInputTextFlags flags) {
|
||||
return ImGui::InputTextWithHint(label, hint, buffer.data(), buffer.size() + 1, ImGuiInputTextFlags_CallbackResize | flags, ImGui::UpdateStringSizeCallback, &buffer);
|
||||
}
|
||||
|
||||
bool InputText(const char *label, std::u8string &buffer, ImGuiInputTextFlags flags) {
|
||||
return ImGui::InputText(label, reinterpret_cast<char *>(buffer.data()), buffer.size() + 1, ImGuiInputTextFlags_CallbackResize | flags, ImGui::UpdateStringSizeCallback, &buffer);
|
||||
}
|
||||
|
||||
bool InputTextMultiline(const char *label, std::string &buffer, const ImVec2 &size, ImGuiInputTextFlags flags) {
|
||||
return ImGui::InputTextMultiline(label, buffer.data(), buffer.size() + 1, size, ImGuiInputTextFlags_CallbackResize | flags, ImGui::UpdateStringSizeCallback, &buffer);
|
||||
}
|
||||
@@ -590,4 +602,47 @@ namespace ImGui {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool BitCheckbox(const char* label, bool* v) {
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label);
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
|
||||
const ImVec2 size = ImVec2(CalcTextSize("0").x + style.FramePadding.x * 2, GetFrameHeight());
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
const ImRect total_bb(pos, pos + size);
|
||||
ItemSize(total_bb, style.FramePadding.y);
|
||||
if (!ItemAdd(total_bb, id))
|
||||
{
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hovered, held;
|
||||
bool pressed = ButtonBehavior(total_bb, id, &hovered, &held);
|
||||
if (pressed)
|
||||
{
|
||||
*v = !(*v);
|
||||
MarkItemEdited(id);
|
||||
}
|
||||
|
||||
const ImRect check_bb(pos, pos + size);
|
||||
RenderNavHighlight(total_bb, id);
|
||||
RenderFrame(check_bb.Min, check_bb.Max, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding);
|
||||
|
||||
RenderText(check_bb.Min + style.FramePadding, *v ? "1" : "0");
|
||||
|
||||
ImVec2 label_pos = ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y);
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(label_pos, label);
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0));
|
||||
return pressed;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,15 +8,6 @@
|
||||
|
||||
namespace hex {
|
||||
|
||||
std::string View::s_popupMessage;
|
||||
|
||||
std::function<void()> View::s_yesCallback, View::s_noCallback;
|
||||
|
||||
u32 View::s_selectableFileIndex;
|
||||
std::vector<std::fs::path> View::s_selectableFiles;
|
||||
std::function<void(std::fs::path)> View::s_selectableFileOpenCallback;
|
||||
std::vector<nfdfilteritem_t> View::s_selectableFilesValidExtensions;
|
||||
|
||||
ImFontAtlas *View::s_fontAtlas;
|
||||
ImFontConfig View::s_fontConfig;
|
||||
|
||||
@@ -26,123 +17,21 @@ namespace hex {
|
||||
return ImHexApi::Provider::isValid() && ImHexApi::Provider::get()->isAvailable();
|
||||
}
|
||||
|
||||
void View::drawCommonInterfaces() {
|
||||
auto windowSize = ImHexApi::System::getMainWindowSize();
|
||||
|
||||
ImGui::SetNextWindowSizeConstraints(scaled(ImVec2(400, 100)), scaled(ImVec2(600, 300)));
|
||||
if (ImGui::BeginPopupModal("hex.builtin.common.info"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
ImGui::TextFormattedWrapped("{}", s_popupMessage.c_str());
|
||||
ImGui::NewLine();
|
||||
ImGui::Separator();
|
||||
if (ImGui::Button("hex.builtin.common.okay"_lang) || ImGui::IsKeyDown(ImGuiKey_Escape))
|
||||
ImGui::CloseCurrentPopup();
|
||||
|
||||
ImGui::SetWindowPos((windowSize - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::SetNextWindowSizeConstraints(scaled(ImVec2(400, 100)), scaled(ImVec2(600, 300)));
|
||||
if (ImGui::BeginPopupModal("hex.builtin.common.error"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
ImGui::TextFormattedWrapped("{}", s_popupMessage.c_str());
|
||||
ImGui::NewLine();
|
||||
ImGui::Separator();
|
||||
if (ImGui::Button("hex.builtin.common.okay"_lang) || ImGui::IsKeyDown(ImGuiKey_Escape))
|
||||
ImGui::CloseCurrentPopup();
|
||||
|
||||
ImGui::SetWindowPos((windowSize - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::SetNextWindowSizeConstraints(scaled(ImVec2(400, 100)), scaled(ImVec2(600, 300)));
|
||||
if (ImGui::BeginPopupModal("hex.builtin.common.fatal"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
ImGui::TextFormattedWrapped("{}", s_popupMessage.c_str());
|
||||
ImGui::NewLine();
|
||||
ImGui::Separator();
|
||||
if (ImGui::Button("hex.builtin.common.okay"_lang) || ImGui::IsKeyDown(ImGuiKey_Escape)) {
|
||||
ImHexApi::Common::closeImHex();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui::SetWindowPos((windowSize - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::SetNextWindowSizeConstraints(scaled(ImVec2(400, 100)), scaled(ImVec2(600, 300)));
|
||||
if (ImGui::BeginPopupModal("hex.builtin.common.question"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
ImGui::TextFormattedWrapped("{}", s_popupMessage.c_str());
|
||||
ImGui::NewLine();
|
||||
ImGui::Separator();
|
||||
|
||||
View::confirmButtons(
|
||||
"hex.builtin.common.yes"_lang, "hex.builtin.common.no"_lang, [] {
|
||||
s_yesCallback();
|
||||
ImGui::CloseCurrentPopup(); }, [] {
|
||||
s_noCallback();
|
||||
ImGui::CloseCurrentPopup(); });
|
||||
|
||||
ImGui::SetWindowPos((windowSize - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
bool opened = true;
|
||||
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5F, 0.5F));
|
||||
if (ImGui::BeginPopupModal("hex.builtin.common.choose_file"_lang, &opened, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
|
||||
if (ImGui::BeginListBox("##files", ImVec2(300_scaled, 0))) {
|
||||
|
||||
u32 index = 0;
|
||||
for (auto &path : View::s_selectableFiles) {
|
||||
if (ImGui::Selectable(path.filename().string().c_str(), index == View::s_selectableFileIndex))
|
||||
View::s_selectableFileIndex = index;
|
||||
index++;
|
||||
}
|
||||
|
||||
ImGui::EndListBox();
|
||||
}
|
||||
|
||||
if (ImGui::Button("hex.builtin.common.open"_lang)) {
|
||||
View::s_selectableFileOpenCallback(View::s_selectableFiles[View::s_selectableFileIndex]);
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("hex.builtin.common.browse"_lang)) {
|
||||
fs::openFileBrowser(fs::DialogMode::Open, View::s_selectableFilesValidExtensions, [](const auto &path) {
|
||||
View::s_selectableFileOpenCallback(path);
|
||||
ImGui::CloseCurrentPopup();
|
||||
});
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
void View::showInfoPopup(const std::string &message) {
|
||||
EventManager::post<RequestShowInfoPopup>(message);
|
||||
}
|
||||
|
||||
void View::showMessagePopup(const std::string &message) {
|
||||
s_popupMessage = message;
|
||||
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.common.info"_lang); });
|
||||
void View::showErrorPopup(const std::string &message) {
|
||||
EventManager::post<RequestShowErrorPopup>(message);
|
||||
}
|
||||
|
||||
void View::showErrorPopup(const std::string &errorMessage) {
|
||||
s_popupMessage = errorMessage;
|
||||
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.common.error"_lang); });
|
||||
}
|
||||
|
||||
void View::showFatalPopup(const std::string &errorMessage) {
|
||||
s_popupMessage = errorMessage;
|
||||
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.common.fatal"_lang); });
|
||||
void View::showFatalPopup(const std::string &message) {
|
||||
EventManager::post<RequestShowFatalErrorPopup>(message);
|
||||
}
|
||||
|
||||
void View::showYesNoQuestionPopup(const std::string &message, const std::function<void()> &yesCallback, const std::function<void()> &noCallback) {
|
||||
s_popupMessage = message;
|
||||
EventManager::post<RequestShowYesNoQuestionPopup>(message, yesCallback, noCallback);
|
||||
|
||||
s_yesCallback = yesCallback;
|
||||
s_noCallback = noCallback;
|
||||
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.common.question"_lang); });
|
||||
}
|
||||
|
||||
void View::showFileChooserPopup(const std::vector<std::fs::path> &paths, const std::vector<nfdfilteritem_t> &validExtensions, const std::function<void(std::fs::path)> &callback) {
|
||||
@@ -151,12 +40,7 @@ namespace hex {
|
||||
callback(path);
|
||||
});
|
||||
} else {
|
||||
View::s_selectableFileIndex = 0;
|
||||
View::s_selectableFiles = paths;
|
||||
View::s_selectableFilesValidExtensions = validExtensions;
|
||||
View::s_selectableFileOpenCallback = callback;
|
||||
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.common.choose_file"_lang); });
|
||||
EventManager::post<RequestShowFileChooserPopup>(paths, validExtensions, callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ set_target_properties(main PROPERTIES
|
||||
add_compile_definitions(IMHEX_PROJECT_NAME="${PROJECT_NAME}")
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(main PUBLIC libimhex wsock32 ws2_32 Dwmapi.lib)
|
||||
target_link_libraries(main PUBLIC usp10 libimhex wsock32 ws2_32 Dwmapi.lib)
|
||||
else ()
|
||||
target_link_libraries(main PUBLIC libimhex pthread)
|
||||
endif ()
|
||||
|
||||
@@ -23,8 +23,6 @@ namespace hex::init {
|
||||
this->m_tasks.emplace_back(taskName, task);
|
||||
}
|
||||
|
||||
[[nodiscard]] const std::string &getGPUVendor() const { return this->m_gpuVendor; }
|
||||
|
||||
private:
|
||||
GLFWwindow *m_window;
|
||||
std::mutex m_progressMutex;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
#include <imgui_impl_glfw.h>
|
||||
#include <imgui_impl_opengl3.h>
|
||||
#include <fontawesome_font.h>
|
||||
#include <fonts/fontawesome_font.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <unistd.h>
|
||||
@@ -30,7 +30,7 @@ namespace hex::init {
|
||||
this->initGLFW();
|
||||
this->initImGui();
|
||||
|
||||
this->m_gpuVendor = reinterpret_cast<const char *>(glGetString(GL_VENDOR));
|
||||
ImHexApi::System::impl::setGPUVendor(reinterpret_cast<const char *>(glGetString(GL_VENDOR)));
|
||||
}
|
||||
|
||||
WindowSplash::~WindowSplash() {
|
||||
@@ -173,18 +173,20 @@ namespace hex::init {
|
||||
|
||||
auto meanScale = std::midpoint(xScale, yScale);
|
||||
|
||||
// On Macs with a retina display (basically all modern ones we care about), the OS reports twice
|
||||
// the actual monitor scale for some obscure reason. Get rid of this here so ImHex doesn't look
|
||||
// extremely huge with native scaling on macOS.
|
||||
#if defined(OS_MACOS)
|
||||
meanScale /= 2;
|
||||
#endif
|
||||
// On Macs with a retina display (basically all modern ones we care about), the OS reports twice
|
||||
// the actual monitor scale for some obscure reason. Get rid of this here so ImHex doesn't look
|
||||
// extremely huge with native scaling on macOS.
|
||||
#if defined(OS_MACOS)
|
||||
meanScale /= 2;
|
||||
#endif
|
||||
|
||||
if (meanScale <= 0.0) {
|
||||
meanScale = 1.0;
|
||||
}
|
||||
|
||||
ImHexApi::System::impl::setGlobalScale(meanScale);
|
||||
} else {
|
||||
ImHexApi::System::impl::setGlobalScale(1.0);
|
||||
}
|
||||
|
||||
this->m_window = glfwCreateWindow(640_scaled, 400_scaled, "Starting ImHex...", nullptr, nullptr);
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
#include <hex/helpers/fs.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
#include <fontawesome_font.h>
|
||||
#include <codicons_font.h>
|
||||
#include <unifont_font.h>
|
||||
#include <fonts/fontawesome_font.h>
|
||||
#include <fonts/codicons_font.h>
|
||||
#include <fonts/unifont_font.h>
|
||||
|
||||
#include <hex/api/plugin_manager.hpp>
|
||||
|
||||
@@ -93,23 +93,6 @@ namespace hex::init {
|
||||
auto fonts = IM_NEW(ImFontAtlas)();
|
||||
ImFontConfig cfg = {};
|
||||
|
||||
std::fs::path fontFile = ContentRegistry::Settings::read("hex.builtin.setting.font", "hex.builtin.setting.font.font_path", "");
|
||||
if (!fs::exists(fontFile))
|
||||
fontFile.clear();
|
||||
|
||||
// If no custom font has been specified, search for a file called "font.ttf" in one of the resource folders
|
||||
if (fontFile.empty()) {
|
||||
for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Resources)) {
|
||||
auto path = dir / "font.ttf";
|
||||
if (fs::exists(path)) {
|
||||
log::info("Loading custom front from {}", path.string());
|
||||
|
||||
fontFile = path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImVector<ImWchar> ranges;
|
||||
{
|
||||
ImFontGlyphRangesBuilder glyphRangesBuilder;
|
||||
@@ -135,7 +118,8 @@ namespace hex::init {
|
||||
0x0100, 0xFFF0, 0
|
||||
};
|
||||
|
||||
float fontSize = 13.0F * ImHexApi::System::getGlobalScale();
|
||||
auto fontFile = ImHexApi::System::getCustomFontPath();
|
||||
float fontSize = ImHexApi::System::getFontSize();
|
||||
if (fontFile.empty()) {
|
||||
// Load default font if no custom one has been specified
|
||||
|
||||
@@ -147,8 +131,6 @@ namespace hex::init {
|
||||
} else {
|
||||
// Load custom font
|
||||
|
||||
fontSize = ContentRegistry::Settings::read("hex.builtin.setting.font", "hex.builtin.setting.font.font_size", 13) * ImHexApi::System::getGlobalScale();
|
||||
|
||||
cfg.OversampleH = cfg.OversampleV = 1, cfg.PixelSnapH = true;
|
||||
cfg.SizePixels = fontSize;
|
||||
|
||||
@@ -170,6 +152,10 @@ namespace hex::init {
|
||||
}
|
||||
|
||||
bool deleteSharedData() {
|
||||
while (ImHexApi::Provider::isValid())
|
||||
ImHexApi::Provider::remove(ImHexApi::Provider::get());
|
||||
ContentRegistry::Provider::getEntries().clear();
|
||||
|
||||
ImHexApi::System::getInitArguments().clear();
|
||||
ImHexApi::Tasks::getDeferredCalls().clear();
|
||||
ImHexApi::HexEditor::impl::getBackgroundHighlights().clear();
|
||||
@@ -177,16 +163,23 @@ namespace hex::init {
|
||||
ImHexApi::HexEditor::impl::getBackgroundHighlightingFunctions().clear();
|
||||
ImHexApi::HexEditor::impl::getForegroundHighlightingFunctions().clear();
|
||||
ImHexApi::HexEditor::impl::getTooltips().clear();
|
||||
ImHexApi::HexEditor::impl::getTooltipFunctions().clear();
|
||||
|
||||
ContentRegistry::Settings::getEntries().clear();
|
||||
ContentRegistry::Settings::getSettingsData().clear();
|
||||
|
||||
ContentRegistry::CommandPaletteCommands::getEntries().clear();
|
||||
ContentRegistry::PatternLanguage::getFunctions().clear();
|
||||
|
||||
for (auto &[name, view] : ContentRegistry::Views::getEntries())
|
||||
delete view;
|
||||
ContentRegistry::Views::getEntries().clear();
|
||||
ContentRegistry::PatternLanguage::getFunctions().clear();
|
||||
ContentRegistry::PatternLanguage::getPragmas().clear();
|
||||
|
||||
{
|
||||
auto &views = ContentRegistry::Views::getEntries();
|
||||
for (auto &[name, view] : views)
|
||||
delete view;
|
||||
views.clear();
|
||||
}
|
||||
|
||||
|
||||
ContentRegistry::Tools::getEntries().clear();
|
||||
ContentRegistry::DataInspector::getEntries().clear();
|
||||
@@ -213,9 +206,12 @@ namespace hex::init {
|
||||
ContentRegistry::DataFormatter::getEntries().clear();
|
||||
ContentRegistry::FileHandler::getEntries().clear();
|
||||
|
||||
while (ImHexApi::Provider::isValid())
|
||||
ImHexApi::Provider::remove(ImHexApi::Provider::get());
|
||||
ContentRegistry::Provider::getEntries().clear();
|
||||
{
|
||||
auto &visualizers = ContentRegistry::HexEditor::impl::getVisualizers();
|
||||
for (auto &[name, visualizer] : visualizers)
|
||||
delete visualizer;
|
||||
visualizers.clear();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -289,28 +285,6 @@ namespace hex::init {
|
||||
return false;
|
||||
}
|
||||
|
||||
float interfaceScaling = 1.0F;
|
||||
switch (ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.scaling", 0)) {
|
||||
default:
|
||||
case 0:
|
||||
// Native scaling
|
||||
break;
|
||||
case 1:
|
||||
interfaceScaling = 0.5F;
|
||||
break;
|
||||
case 2:
|
||||
interfaceScaling = 1.0F;
|
||||
break;
|
||||
case 3:
|
||||
interfaceScaling = 1.5F;
|
||||
break;
|
||||
case 4:
|
||||
interfaceScaling = 2.0F;
|
||||
break;
|
||||
}
|
||||
|
||||
ImHexApi::System::impl::setGlobalScale(interfaceScaling);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,17 +25,6 @@ int main(int argc, char **argv, char **envp) {
|
||||
|
||||
init::WindowSplash splashWindow;
|
||||
|
||||
// Intel's OpenGL driver has weird bugs that cause the drawn window to be offset to the bottom right.
|
||||
// This can be fixed by either using Mesa3D's OpenGL Software renderer or by simply disabling it.
|
||||
// If you want to try if it works anyways on your GPU, set the hex.builtin.setting.interface.force_borderless_window_mode setting to 1
|
||||
if (ImHexApi::System::isBorderlessWindowModeEnabled()) {
|
||||
bool isIntelGPU = hex::containsIgnoreCase(splashWindow.getGPUVendor(), "Intel");
|
||||
ImHexApi::System::impl::setBorderlessWindowMode(!isIntelGPU);
|
||||
|
||||
if (isIntelGPU)
|
||||
log::warn("Intel GPU detected! Intel's OpenGL driver has bugs that can cause issues when using ImHex. If you experience any rendering bugs, please try the Mesa3D Software Renderer");
|
||||
}
|
||||
|
||||
for (const auto &[name, task] : init::getInitTasks())
|
||||
splashWindow.addStartupTask(name, task);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/api/event.hpp>
|
||||
|
||||
@@ -21,7 +22,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
void Window::setupNativeWindow() {
|
||||
bool themeFollowSystem = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.color") == 0;
|
||||
bool themeFollowSystem = ImHexApi::System::usesSystemThemeDetection();
|
||||
EventManager::subscribe<EventOSThemeChanged>(this, [themeFollowSystem] {
|
||||
if (!themeFollowSystem) return;
|
||||
|
||||
@@ -38,7 +39,7 @@ namespace hex {
|
||||
auto exitCode = WEXITSTATUS(pclose(pipe));
|
||||
if (exitCode != 0) return;
|
||||
|
||||
EventManager::post<RequestChangeTheme>(hex::containsIgnoreCase(result, "dark") ? 1 : 2);
|
||||
EventManager::post<RequestChangeTheme>(hex::containsIgnoreCase(result, "light") ? 2 : 1);
|
||||
});
|
||||
|
||||
if (themeFollowSystem)
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
#if defined(OS_MACOS)
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/api/event.hpp>
|
||||
|
||||
#include <hex/helpers/utils_macos.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
@@ -19,12 +21,14 @@ namespace hex {
|
||||
}
|
||||
|
||||
void Window::setupNativeWindow() {
|
||||
bool themeFollowSystem = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.color") == 0;
|
||||
bool themeFollowSystem = ImHexApi::System::usesSystemThemeDetection();
|
||||
EventManager::subscribe<EventOSThemeChanged>(this, [themeFollowSystem] {
|
||||
if (!themeFollowSystem) return;
|
||||
|
||||
// TODO: Implement this when MacOS build is working again
|
||||
EventManager::post<RequestChangeTheme>(1);
|
||||
if (!isMacosSystemDarkModeEnabled())
|
||||
EventManager::post<RequestChangeTheme>(2);
|
||||
else
|
||||
EventManager::post<RequestChangeTheme>(1);
|
||||
});
|
||||
|
||||
if (themeFollowSystem)
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
#include <codicons_font.h>
|
||||
#include <fonts/codicons_font.h>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <imnodes.h>
|
||||
#include <imnodes_internal.h>
|
||||
|
||||
#include <codicons_font.h>
|
||||
#include <fonts/codicons_font.h>
|
||||
|
||||
#include <hex/helpers/project_file_handler.hpp>
|
||||
|
||||
@@ -118,7 +118,7 @@ namespace hex {
|
||||
return;
|
||||
|
||||
for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Config)) {
|
||||
if (ProjectFile::store((std::fs::path(path) / CrashBackupFileName).string()))
|
||||
if (ProjectFile::store(std::fs::path(path) / CrashBackupFileName))
|
||||
break;
|
||||
}
|
||||
});
|
||||
@@ -198,7 +198,7 @@ namespace hex {
|
||||
|
||||
ImGuiViewport *viewport = ImGui::GetMainViewport();
|
||||
ImGui::SetNextWindowPos(viewport->WorkPos);
|
||||
ImGui::SetNextWindowSize(viewport->WorkSize);
|
||||
ImGui::SetNextWindowSize(ImHexApi::System::getMainWindowSize() - ImVec2(0, ImGui::GetTextLineHeightWithSpacing()));
|
||||
ImGui::SetNextWindowViewport(viewport->ID);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||
@@ -348,11 +348,12 @@ namespace hex {
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Plugins, true)) {
|
||||
const auto filePath = path / "builtin.hexplug";
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted(path.string().c_str());
|
||||
ImGui::TextUnformatted(filePath.string().c_str());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted(fs::exists(path) ? ICON_VS_CHECK : ICON_VS_CLOSE);
|
||||
ImGui::TextUnformatted(fs::exists(filePath) ? ICON_VS_CHECK : ICON_VS_CLOSE);
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
@@ -420,8 +421,6 @@ namespace hex {
|
||||
calls.clear();
|
||||
}
|
||||
|
||||
View::drawCommonInterfaces();
|
||||
|
||||
for (auto &[name, view] : ContentRegistry::Views::getEntries()) {
|
||||
ImGui::GetCurrentContext()->NextWindowData.ClearFlags();
|
||||
|
||||
@@ -559,7 +558,8 @@ namespace hex {
|
||||
});
|
||||
|
||||
glfwSetWindowSizeCallback(this->m_window, [](GLFWwindow *window, int width, int height) {
|
||||
ImHexApi::System::impl::setMainWindowSize(width, height);
|
||||
if (!glfwGetWindowAttrib(window, GLFW_ICONIFIED))
|
||||
ImHexApi::System::impl::setMainWindowSize(width, height);
|
||||
|
||||
if (auto g = ImGui::GetCurrentContext(); g == nullptr || g->WithinFrameScope) return;
|
||||
|
||||
@@ -653,8 +653,9 @@ namespace hex {
|
||||
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable | ImGuiConfigFlags_NavEnableKeyboard;
|
||||
|
||||
{
|
||||
if (glfwGetPrimaryMonitor() != nullptr) {
|
||||
auto sessionType = hex::getEnvironmentVariable("XDG_SESSION_TYPE");
|
||||
|
||||
if (!sessionType || !hex::containsIgnoreCase(*sessionType, "wayland"))
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ add_library(${PROJECT_NAME} SHARED
|
||||
source/content/welcome_screen.cpp
|
||||
source/content/data_visualizers.cpp
|
||||
source/content/events.cpp
|
||||
source/content/hashes.cpp
|
||||
|
||||
source/content/providers/file_provider.cpp
|
||||
source/content/providers/gdb_provider.cpp
|
||||
@@ -57,6 +58,7 @@ add_library(${PROJECT_NAME} SHARED
|
||||
source/lang/it_IT.cpp
|
||||
source/lang/zh_CN.cpp
|
||||
source/lang/ja_JP.cpp
|
||||
source/lang/pt_BR.cpp
|
||||
)
|
||||
|
||||
# Add additional include directories here #
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace hex::plugin::builtin::prv {
|
||||
|
||||
void resize(size_t newSize) override;
|
||||
void insert(u64 offset, size_t size) override;
|
||||
void remove(u64 offset, size_t size) override;
|
||||
|
||||
void readRaw(u64 offset, void *buffer, size_t size) override;
|
||||
void writeRaw(u64 offset, const void *buffer, size_t size) override;
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
private:
|
||||
std::list<ImHexApi::Bookmarks::Entry> m_bookmarks;
|
||||
std::string m_currFilter;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/api/content_registry.hpp>
|
||||
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <array>
|
||||
@@ -16,35 +18,10 @@ namespace hex::plugin::builtin {
|
||||
void drawContent() override;
|
||||
|
||||
private:
|
||||
enum class HashFunctions
|
||||
{
|
||||
Crc8,
|
||||
Crc16,
|
||||
Crc32,
|
||||
Md5,
|
||||
Sha1,
|
||||
Sha224,
|
||||
Sha256,
|
||||
Sha384,
|
||||
Sha512
|
||||
};
|
||||
ContentRegistry::Hashes::Hash *m_selectedHash = nullptr;
|
||||
std::string m_newHashName;
|
||||
|
||||
bool m_shouldInvalidate = true;
|
||||
int m_currHashFunction = 0;
|
||||
u64 m_hashRegion[2] = { 0 };
|
||||
bool m_shouldMatchSelection = false;
|
||||
|
||||
static constexpr std::array hashFunctionNames {
|
||||
std::pair {HashFunctions::Crc8, "CRC8" },
|
||||
std::pair { HashFunctions::Crc16, "CRC16" },
|
||||
std::pair { HashFunctions::Crc32, "CRC32" },
|
||||
std::pair { HashFunctions::Md5, "MD5" },
|
||||
std::pair { HashFunctions::Sha1, "SHA-1" },
|
||||
std::pair { HashFunctions::Sha224, "SHA-224"},
|
||||
std::pair { HashFunctions::Sha256, "SHA-256"},
|
||||
std::pair { HashFunctions::Sha384, "SHA-384"},
|
||||
std::pair { HashFunctions::Sha512, "SHA-512"},
|
||||
};
|
||||
std::vector<ContentRegistry::Hashes::Hash::Function> m_hashFunctions;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ namespace hex::plugin::builtin {
|
||||
private:
|
||||
constexpr static auto InvalidSelection = std::numeric_limits<u64>::max();
|
||||
|
||||
void openFile(const std::fs::path &path);
|
||||
void registerShortcuts();
|
||||
void registerEvents();
|
||||
void registerMenuItems();
|
||||
@@ -31,15 +30,25 @@ namespace hex::plugin::builtin {
|
||||
|
||||
public:
|
||||
void setSelection(const Region ®ion) { this->setSelection(region.getStartAddress(), region.getEndAddress()); }
|
||||
void setSelection(i128 start, i128 end) {
|
||||
if (!ImHexApi::Provider::isValid()) return;
|
||||
void setSelection(u128 start, u128 end) {
|
||||
if (!ImHexApi::Provider::isValid())
|
||||
return;
|
||||
if (start == InvalidSelection && end == InvalidSelection)
|
||||
return;
|
||||
|
||||
const size_t maxAddress = ImHexApi::Provider::get()->getActualSize() - 1;
|
||||
if (start == InvalidSelection)
|
||||
start = end;
|
||||
if (end == InvalidSelection)
|
||||
end = start;
|
||||
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
|
||||
const size_t maxAddress = provider->getActualSize() + provider->getBaseAddress() - 1;
|
||||
|
||||
this->m_selectionChanged = this->m_selectionStart != start || this->m_selectionEnd != end;
|
||||
|
||||
this->m_selectionStart = std::clamp<decltype(start)>(start, 0, maxAddress);
|
||||
this->m_selectionEnd = std::clamp<decltype(end)>(end, 0, maxAddress);
|
||||
this->m_selectionStart = std::clamp<u128>(start, 0, maxAddress);
|
||||
this->m_selectionEnd = std::clamp<u128>(end, 0, maxAddress);
|
||||
|
||||
if (this->m_selectionChanged) {
|
||||
EventManager::post<EventRegionSelected>(this->getSelection());
|
||||
@@ -66,6 +75,10 @@ namespace hex::plugin::builtin {
|
||||
this->m_shouldScrollToSelection = true;
|
||||
}
|
||||
|
||||
void jumpIfOffScreen() {
|
||||
this->m_shouldJumpWhenOffScreen = true;
|
||||
}
|
||||
|
||||
public:
|
||||
class Popup {
|
||||
public:
|
||||
@@ -105,6 +118,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
bool m_shouldJumpToSelection = false;
|
||||
bool m_shouldScrollToSelection = false;
|
||||
bool m_shouldJumpWhenOffScreen = false;
|
||||
|
||||
bool m_selectionChanged = false;
|
||||
u64 m_selectionStart = InvalidSelection;
|
||||
@@ -115,6 +129,7 @@ namespace hex::plugin::builtin {
|
||||
std::optional<u64> m_editingAddress;
|
||||
bool m_shouldModifyValue = false;
|
||||
bool m_enteredEditingMode = false;
|
||||
bool m_shouldUpdateEditingValue = false;
|
||||
std::vector<u8> m_editingBytes;
|
||||
|
||||
color_t m_selectionColor = 0x00;
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace hex::plugin::builtin {
|
||||
void drawContent() override;
|
||||
|
||||
private:
|
||||
std::map<prv::Provider *, std::vector<std::shared_ptr<pl::Pattern>>> m_sortedPatterns;
|
||||
std::map<prv::Provider *, std::vector<pl::Pattern*>> m_sortedPatterns;
|
||||
hex::PatternDrawer m_patternDrawer;
|
||||
};
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace hex::plugin::builtin {
|
||||
void drawContent() override;
|
||||
|
||||
private:
|
||||
pl::PatternLanguage *m_parserRuntime;
|
||||
std::unique_ptr<pl::PatternLanguage> m_parserRuntime;
|
||||
|
||||
std::vector<std::fs::path> m_possiblePatternFiles;
|
||||
u32 m_selectedPatternFile = 0;
|
||||
@@ -56,7 +56,6 @@ namespace hex::plugin::builtin {
|
||||
};
|
||||
|
||||
std::map<std::string, PatternVariable> m_patternVariables;
|
||||
std::vector<std::string> m_patternTypes;
|
||||
|
||||
enum class EnvVarType
|
||||
{
|
||||
@@ -102,4 +101,4 @@ namespace hex::plugin::builtin {
|
||||
void evaluatePattern(const std::string &code);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace hex::plugin::builtin {
|
||||
u32 tooltipId;
|
||||
};
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> m_rules;
|
||||
std::vector<std::pair<std::fs::path, std::fs::path>> m_rules;
|
||||
std::vector<YaraMatch> m_matches;
|
||||
u32 m_selectedRule = 0;
|
||||
bool m_matching = false;
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
namespace hex {
|
||||
|
||||
template<typename T>
|
||||
concept ArrayPattern = requires(T pattern, std::function<void(int, pl::Pattern&)> fn) {
|
||||
{ pattern.forEachArrayEntry(fn) } -> std::same_as<void>;
|
||||
concept ArrayPattern = requires(u64 displayEnd, T pattern, std::function<void(int, pl::Pattern&)> fn) {
|
||||
{ pattern.forEachArrayEntry(displayEnd, fn) } -> std::same_as<void>;
|
||||
};
|
||||
|
||||
class PatternDrawer : public pl::PatternVisitor {
|
||||
@@ -48,7 +48,7 @@ namespace hex {
|
||||
|
||||
if (opened) {
|
||||
auto& displayEnd = this->getDisplayEnd(pattern);
|
||||
pattern.forEachArrayEntry([&] (u64 idx, auto &entry){
|
||||
pattern.forEachArrayEntry(displayEnd, [&] (u64 idx, auto &entry){
|
||||
this->drawArrayNode(idx, displayEnd, entry);
|
||||
});
|
||||
}
|
||||
@@ -57,7 +57,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
bool drawArrayRoot(pl::Pattern& pattern, size_t entryCount, bool isInlined);
|
||||
void drawArrayNode(u64 idx, u64 displayEnd, pl::Pattern& pattern);
|
||||
void drawArrayNode(u64 idx, u64& displayEnd, pl::Pattern& pattern);
|
||||
void drawArrayEnd(pl::Pattern& pattern, bool opened);
|
||||
|
||||
void drawCommentTooltip(const pl::Pattern &pattern) const;
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
template<std::floating_point T>
|
||||
static std::vector<u8> stringToFloat(const std::string &value, std::endian endian) requires(sizeof(T) <= sizeof(long double)) {
|
||||
auto result = std::strtold(value.c_str(), nullptr);
|
||||
T result = std::strtold(value.c_str(), nullptr);
|
||||
|
||||
std::vector<u8> bytes(sizeof(T), 0x00);
|
||||
std::memcpy(bytes.data(), &result, bytes.size());
|
||||
@@ -84,7 +84,7 @@ namespace hex::plugin::builtin {
|
||||
[](auto buffer, auto endian, auto style) {
|
||||
hex::unused(endian, style);
|
||||
|
||||
std::string binary = hex::format("0b{:b}", buffer[0]);
|
||||
std::string binary = hex::format("0b{:08b}", buffer[0]);
|
||||
|
||||
return [binary] {
|
||||
ImGui::TextUnformatted(binary.c_str());
|
||||
@@ -314,7 +314,7 @@ namespace hex::plugin::builtin {
|
||||
return [value] { ImGui::TextFormatted("'{0}'", value.c_str()); return value; };
|
||||
},
|
||||
[](const std::string &value, std::endian endian) -> std::vector<u8> {
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter("");
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter("Invalid");
|
||||
|
||||
std::vector<u8> bytes;
|
||||
auto wideString = converter.from_bytes(value.c_str());
|
||||
@@ -349,7 +349,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ContentRegistry::DataInspector::add("hex.builtin.inspector.string", 1,
|
||||
[](auto buffer, auto endian, auto style) {
|
||||
hex::unused(endian, style);
|
||||
hex::unused(buffer, endian, style);
|
||||
|
||||
auto currSelection = ImHexApi::HexEditor::getSelection();
|
||||
|
||||
@@ -358,14 +358,15 @@ namespace hex::plugin::builtin {
|
||||
std::string value, copyValue;
|
||||
|
||||
if (currSelection.has_value()) {
|
||||
std::vector<u8> stringBuffer(std::min<size_t>(MaxStringLength, currSelection->size), 0x00);
|
||||
std::vector<u8> stringBuffer(std::min<size_t>(currSelection->size, 0x1000), 0x00);
|
||||
ImHexApi::Provider::get()->read(currSelection->address, stringBuffer.data(), stringBuffer.size());
|
||||
|
||||
value = hex::encodeByteString(stringBuffer);
|
||||
copyValue = hex::encodeByteString(buffer);
|
||||
value = copyValue = hex::encodeByteString(stringBuffer);
|
||||
|
||||
if (currSelection->size > MaxStringLength)
|
||||
if (currSelection->size > MaxStringLength) {
|
||||
value.resize(MaxStringLength);
|
||||
value += "...";
|
||||
}
|
||||
} else {
|
||||
value = "";
|
||||
copyValue = "";
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
void load(nlohmann::json &j) override {
|
||||
this->m_value = j["data"];
|
||||
this->m_value = j["data"].get<std::string>();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -213,7 +213,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
void load(nlohmann::json &j) override {
|
||||
this->m_comment = j["comment"];
|
||||
this->m_comment = j["comment"].get<std::string>();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -777,7 +777,16 @@ namespace hex::plugin::builtin {
|
||||
NodeVisualizerDigram() : Node("hex.builtin.nodes.visualizer.digram.header", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.common.input") }) { }
|
||||
|
||||
void drawNode() override {
|
||||
const auto viewSize = scaled({ 200, 200 });
|
||||
drawDigram(scaled({ 200, 200 }));
|
||||
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
drawDigram(scaled({ 600, 600 }));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
void drawDigram(const ImVec2 &viewSize) {
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImU32(ImColor(0, 0, 0)));
|
||||
if (ImGui::BeginChild("##visualizer", viewSize, true)) {
|
||||
auto drawList = ImGui::GetWindowDrawList();
|
||||
@@ -860,7 +869,15 @@ namespace hex::plugin::builtin {
|
||||
NodeVisualizerLayeredDistribution() : Node("hex.builtin.nodes.visualizer.layered_dist.header", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.common.input") }) { }
|
||||
|
||||
void drawNode() override {
|
||||
const auto viewSize = scaled({ 200, 200 });
|
||||
drawLayeredDistribution(scaled({ 200, 200 }));
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
drawLayeredDistribution(scaled({ 600, 600 }));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
void drawLayeredDistribution(const ImVec2 &viewSize) {
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImU32(ImColor(0, 0, 0)));
|
||||
if (ImGui::BeginChild("##visualizer", viewSize, true)) {
|
||||
auto drawList = ImGui::GetWindowDrawList();
|
||||
@@ -944,6 +961,11 @@ namespace hex::plugin::builtin {
|
||||
|
||||
void drawNode() override {
|
||||
ImGui::Image(this->m_texture, scaled(ImVec2(this->m_texture.aspectRatio() * 200, 200)));
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Image(this->m_texture, scaled(ImVec2(this->m_texture.aspectRatio() * 600, 600)));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
void process() override {
|
||||
@@ -964,8 +986,18 @@ namespace hex::plugin::builtin {
|
||||
NodeVisualizerByteDistribution() : Node("hex.builtin.nodes.visualizer.byte_distribution.header", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.common.input") }) { }
|
||||
|
||||
void drawNode() override {
|
||||
drawPlot(scaled({ 400, 300 }));
|
||||
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
drawPlot(scaled({ 700, 550 }));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
void drawPlot(const ImVec2 &viewSize) {
|
||||
ImPlot::SetNextPlotLimits(0, 256, 0.5, float(*std::max_element(this->m_counts.begin(), this->m_counts.end())) * 1.1F, ImGuiCond_Always);
|
||||
if (ImPlot::BeginPlot("##distribution", "Address", "Count", scaled(ImVec2(400, 300)), ImPlotFlags_NoLegend | ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect, ImPlotAxisFlags_Lock, ImPlotAxisFlags_Lock | ImPlotAxisFlags_LogScale, ImPlotAxisFlags_NoLabel | ImPlotAxisFlags_NoTickLabels, ImPlotAxisFlags_NoLabel | ImPlotAxisFlags_NoTickLabels)) {
|
||||
if (ImPlot::BeginPlot("##distribution", "Address", "Count", viewSize, ImPlotFlags_NoLegend | ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect, ImPlotAxisFlags_Lock, ImPlotAxisFlags_Lock | ImPlotAxisFlags_LogScale, ImPlotAxisFlags_NoLabel | ImPlotAxisFlags_NoTickLabels, ImPlotAxisFlags_NoLabel | ImPlotAxisFlags_NoTickLabels)) {
|
||||
static auto x = [] {
|
||||
std::array<ImU64, 256> result { 0 };
|
||||
std::iota(result.begin(), result.end(), 0);
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace hex::plugin::builtin {
|
||||
else static_assert(hex::always_false<T>::value, "Invalid data type!");
|
||||
}
|
||||
|
||||
template<hex::integral T>
|
||||
template<std::integral T>
|
||||
class DataVisualizerHexadecimal : public hex::ContentRegistry::HexEditor::DataVisualizer {
|
||||
public:
|
||||
DataVisualizerHexadecimal() : DataVisualizer(ByteCount, CharCount) { }
|
||||
@@ -114,7 +114,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
};
|
||||
|
||||
template<hex::integral T>
|
||||
template<std::integral T>
|
||||
class DataVisualizerDecimal : public hex::ContentRegistry::HexEditor::DataVisualizer {
|
||||
public:
|
||||
DataVisualizerDecimal() : DataVisualizer(ByteCount, CharCount) { }
|
||||
@@ -123,7 +123,7 @@ namespace hex::plugin::builtin {
|
||||
hex::unused(address, upperCase);
|
||||
|
||||
if (size == ByteCount) {
|
||||
if (hex::is_signed<T>::value)
|
||||
if (std::is_signed<T>::value)
|
||||
ImGui::Text(getFormatString(), static_cast<i64>(*reinterpret_cast<const T*>(data)));
|
||||
else
|
||||
ImGui::Text(getFormatString(), static_cast<u64>(*reinterpret_cast<const T*>(data)));
|
||||
@@ -153,14 +153,14 @@ namespace hex::plugin::builtin {
|
||||
constexpr static inline auto ByteCount = sizeof(T);
|
||||
constexpr static inline auto CharCount = std::numeric_limits<T>::digits10 + 2;
|
||||
|
||||
const static inline auto FormatString = hex::format("%{}{}", CharCount, hex::is_signed<T>::value ? "lld" : "llu");
|
||||
const static inline auto FormatString = hex::format("%{}{}", CharCount, std::is_signed<T>::value ? "lld" : "llu");
|
||||
|
||||
const char *getFormatString() {
|
||||
return FormatString.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
template<hex::floating_point T>
|
||||
template<std::floating_point T>
|
||||
class DataVisualizerFloatingPoint : public hex::ContentRegistry::HexEditor::DataVisualizer {
|
||||
public:
|
||||
DataVisualizerFloatingPoint() : DataVisualizer(ByteCount, CharCount) { }
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
#include <hex/api/event.hpp>
|
||||
#include <hex/api/content_registry.hpp>
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
#include <hex/helpers/project_file_handler.hpp>
|
||||
#include <hex/api/localization.hpp>
|
||||
#include <hex/helpers/file.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
@@ -86,6 +89,11 @@ namespace hex::plugin::builtin {
|
||||
EventManager::subscribe<EventProviderChanged>([](auto, auto) {
|
||||
EventManager::post<EventHighlightingChanged>();
|
||||
});
|
||||
|
||||
EventManager::subscribe<EventProviderCreated>([](hex::prv::Provider *provider) {
|
||||
if (provider->hasLoadInterface())
|
||||
EventManager::post<RequestOpenPopup>(View::toWindowName("hex.builtin.view.provider_settings.load_popup"));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
140
plugins/builtin/source/content/hashes.cpp
Normal file
140
plugins/builtin/source/content/hashes.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/api/localization.hpp>
|
||||
#include <hex/helpers/crypto.hpp>
|
||||
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
class HashMD5 : public ContentRegistry::Hashes::Hash {
|
||||
public:
|
||||
HashMD5() : Hash("hex.builtin.hash.md5") {}
|
||||
|
||||
Function create(std::string name) override {
|
||||
return Hash::create(name, [](const Region& region, prv::Provider *provider) -> std::vector<u8> {
|
||||
auto array = crypt::md5(provider, region.address, region.size);
|
||||
|
||||
return { array.begin(), array.end() };
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
class HashSHA1 : public ContentRegistry::Hashes::Hash {
|
||||
public:
|
||||
HashSHA1() : Hash("hex.builtin.hash.sha1") {}
|
||||
|
||||
Function create(std::string name) override {
|
||||
return Hash::create(name, [](const Region& region, prv::Provider *provider) -> std::vector<u8> {
|
||||
auto array = crypt::sha1(provider, region.address, region.size);
|
||||
|
||||
return { array.begin(), array.end() };
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
class HashSHA224 : public ContentRegistry::Hashes::Hash {
|
||||
public:
|
||||
HashSHA224() : Hash("hex.builtin.hash.sha224") {}
|
||||
|
||||
Function create(std::string name) override {
|
||||
return Hash::create(name, [](const Region& region, prv::Provider *provider) -> std::vector<u8> {
|
||||
auto array = crypt::sha224(provider, region.address, region.size);
|
||||
|
||||
return { array.begin(), array.end() };
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
class HashSHA256 : public ContentRegistry::Hashes::Hash {
|
||||
public:
|
||||
HashSHA256() : Hash("hex.builtin.hash.sha256") {}
|
||||
|
||||
Function create(std::string name) override {
|
||||
return Hash::create(name, [](const Region& region, prv::Provider *provider) -> std::vector<u8> {
|
||||
auto array = crypt::sha256(provider, region.address, region.size);
|
||||
|
||||
return { array.begin(), array.end() };
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
class HashSHA384 : public ContentRegistry::Hashes::Hash {
|
||||
public:
|
||||
HashSHA384() : Hash("hex.builtin.hash.sha384") {}
|
||||
|
||||
Function create(std::string name) override {
|
||||
return Hash::create(name, [](const Region& region, prv::Provider *provider) -> std::vector<u8> {
|
||||
auto array = crypt::sha384(provider, region.address, region.size);
|
||||
|
||||
return { array.begin(), array.end() };
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
class HashSHA512 : public ContentRegistry::Hashes::Hash {
|
||||
public:
|
||||
HashSHA512() : Hash("hex.builtin.hash.sha512") {}
|
||||
|
||||
Function create(std::string name) override {
|
||||
return Hash::create(name, [](const Region& region, prv::Provider *provider) -> std::vector<u8> {
|
||||
auto array = crypt::sha512(provider, region.address, region.size);
|
||||
|
||||
return { array.begin(), array.end() };
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class HashCRC : public ContentRegistry::Hashes::Hash {
|
||||
public:
|
||||
using CRCFunction = T(*)(prv::Provider*&, u64, size_t, u32, u32, u32, bool, bool);
|
||||
HashCRC(const std::string &name, const CRCFunction &crcFunction, u32 polynomial, u32 initialValue, u32 xorOut)
|
||||
: Hash(name), m_crcFunction(crcFunction), m_polynomial(polynomial), m_initialValue(initialValue), m_xorOut(xorOut) {}
|
||||
|
||||
void draw() override {
|
||||
ImGui::InputHexadecimal("hex.builtin.hash.crc.poly"_lang, &this->m_polynomial);
|
||||
ImGui::InputHexadecimal("hex.builtin.hash.crc.iv"_lang, &this->m_initialValue);
|
||||
ImGui::InputHexadecimal("hex.builtin.hash.crc.xor_out"_lang, &this->m_xorOut);
|
||||
|
||||
ImGui::NewLine();
|
||||
|
||||
ImGui::Checkbox("hex.builtin.hash.crc.refl_in"_lang, &this->m_reflectIn);
|
||||
ImGui::Checkbox("hex.builtin.hash.crc.refl_out"_lang, &this->m_reflectOut);
|
||||
}
|
||||
|
||||
Function create(std::string name) override {
|
||||
return Hash::create(name, [hash = *this](const Region& region, prv::Provider *provider) -> std::vector<u8> {
|
||||
auto result = hash.m_crcFunction(provider, region.address, region.size, hash.m_polynomial, hash.m_initialValue, hash.m_xorOut, hash.m_reflectIn, hash.m_reflectOut);
|
||||
|
||||
std::vector<u8> bytes(sizeof(result), 0x00);
|
||||
std::memcpy(bytes.data(), &result, bytes.size());
|
||||
|
||||
return bytes;
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
CRCFunction m_crcFunction;
|
||||
|
||||
u32 m_polynomial;
|
||||
u32 m_initialValue;
|
||||
u32 m_xorOut;
|
||||
bool m_reflectIn = false, m_reflectOut = false;
|
||||
};
|
||||
|
||||
void registerHashes() {
|
||||
ContentRegistry::Hashes::add<HashMD5>();
|
||||
|
||||
ContentRegistry::Hashes::add<HashSHA1>();
|
||||
ContentRegistry::Hashes::add<HashSHA224>();
|
||||
ContentRegistry::Hashes::add<HashSHA256>();
|
||||
ContentRegistry::Hashes::add<HashSHA384>();
|
||||
ContentRegistry::Hashes::add<HashSHA512>();
|
||||
|
||||
ContentRegistry::Hashes::add<HashCRC<u16>>("hex.builtin.hash.crc8", crypt::crc8, 0x07, 0x0000, 0x0000);
|
||||
ContentRegistry::Hashes::add<HashCRC<u16>>("hex.builtin.hash.crc16", crypt::crc16, 0x8005, 0x0000, 0x0000);
|
||||
ContentRegistry::Hashes::add<HashCRC<u32>>("hex.builtin.hash.crc32", crypt::crc32, 0x04C1'1DB7, 0xFFFF'FFFF, 0xFFFF'FFFF);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user