FreeRDP JIS キーボードビルド(Apple Silicon M1〜M5向け)
Apple Silicon (arm64) 向けに、Mac日本語(JIS)キーボードでの \ および _ 入力を修正するパッチを適用してFreeRDPをソースからビルドします。FFmpeg、H.264ハードウェアアクセラレーション(VideoToolbox)、X11(xfreerdp)に対応しています。
結論
Ubuntu上のxrdpサーバーに対して利用可能なすべてのFreeRDPクライアントを広範囲にテストした結果、推奨クライアントはSDLクライアントではなく xfreerdp(X11クライアント)です。
クライアント比較
| クライアント | 速度 | JIS \ / _
|
状態 |
|---|---|---|---|
xfreerdp(本ビルド) |
高速 | 修正済み | 推奨 |
sdl3-freerdp(本ビルド) |
低速 | 修正済み | 非推奨 |
sdl2-freerdp |
低速 | N/A | 使わない |
Macネイティブ(MacFreeRDP) |
高速 | 不明 | 使わない |
Homebrew xfreerdp
|
高速 | 不具合あり(keycode 0x65/0x66 不明) | JIS非対応 |
SDL3がxrdpで低速な理由
SDL3クライアントはすべてのビットマップ更新をCPU→Metalテクスチャとしてアップロードします。xrdpはレガシーRDPビットマップコーデック(planar/interleaved)を使用しており、多数の小さいタイル更新が発生するため、SDLのテクスチャパイプラインに過大な負荷がかかります。xfreerdpはX11/XQuartzを使用し、より直接的なレンダリングパスでこのコーデックを効率的に処理します。
有効なパッチ
JISキーボードの修正には2つのレベルでのパッチが必要でした。
1. SDLクライアント — client/SDL/SDL2/sdl_kbd.cpp
(元のアプローチ: moriya9n/FreeRDP-SDL-JISKBD)
| SDL スキャンコード | 修正前 | 修正後 | キー |
|---|---|---|---|
SDL_SCANCODE_INTERNATIONAL1 |
RDP_SCANCODE_UNKNOWN |
RDP_SCANCODE_ABNT_C1 |
\ バックスラッシュ |
SDL_SCANCODE_INTERNATIONAL3 |
RDP_SCANCODE_UNKNOWN |
RDP_SCANCODE_BACKSLASH_JP |
_ アンダースコア |
2. X11クライアント — client/X11/xf_keyboard.c(本作業で発見した新規パッチ)
macOS + XQuartzでは、Apple JISキーコード 0x65(APPLE_VK_JIS_Yen)および 0x66(APPLE_VK_JIS_Underscore)がFreeRDPのApple VKテーブルに登録されておらず(0 にマップ)、Unknown key エラーが発生します。Apple keycodeテーブルの参照後に直接上書きすることで修正します。
// client/X11/xf_keyboard.c — load_map_from_xkbfile() 内の __APPLE__ フォールバックブロック
if (i == 0x65)
xfc->X11_KEYCODE_TO_VIRTUAL_SCANCODE[i] = RDP_SCANCODE_BACKSLASH_JP; /* ¥/\ */
else if (i == 0x66)
xfc->X11_KEYCODE_TO_VIRTUAL_SCANCODE[i] = RDP_SCANCODE_ABNT_C1; /* _/ろ */
注意: 0x65 → BACKSLASH_JP、0x66 → ABNT_C1(直感とは逆順 — テストで確認済み)。
3. SDL3マウスクラッシュ修正 — client/SDL/SDL3/sdl_context.cpp
eventToPixelCoordinates() は、未登録のウィンドウIDでマウスイベントが届いた場合(macOSのフォーカス切り替え時)に false を返し、未処理の例外へ伝播していました。最初のウィンドウへのフォールバックで修正します。
// sdl_context.cpp — eventToPixelCoordinates()
auto w = getWindowForId(id);
if (!w)
w = getFirstWindow(); // パッチ: macOSフォーカス問題時にフォールバック
ビルド手順
前提条件
brew install cmake ninja pkg-config openssl@3 pkcs11-helper cjson \
ffmpeg sdl3 sdl3_ttf sdl2_ttf libusb openh264
Macクライアントには Xcode(コマンドラインツールのみ不可)が必要です。
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
クローンと安定タグのチェックアウト
git clone https://github.com/freerdp/freerdp ~/docker-claude/FreeRDP
cd ~/docker-claude/FreeRDP
git fetch --tags
git checkout 3.24.2 # または最新の安定タグ
パッチの適用
cd ~/docker-claude/FreeRDP
# SDLクライアントパッチ(A/B/C)
SDL_KBD=$(find client -name "sdl_kbd.cpp" | grep SDL2 | head -1)
sed -i.bak 's/ENTRY(SDL_SCANCODE_INTERNATIONAL1, RDP_SCANCODE_UNKNOWN)/ENTRY(SDL_SCANCODE_INTERNATIONAL1, RDP_SCANCODE_ABNT_C1)/' "$SDL_KBD"
sed -i.bak 's/ENTRY(SDL_SCANCODE_INTERNATIONAL3, RDP_SCANCODE_UNKNOWN)/ENTRY(SDL_SCANCODE_INTERNATIONAL3, RDP_SCANCODE_BACKSLASH_JP)/' "$SDL_KBD"
sed -i.bak 's/ENTRY(SDL_SCANCODE_RGUI, RDP_SCANCODE_RWIN)/ENTRY(SDL_SCANCODE_RGUI, RDP_SCANCODE_OEM_3)/' "$SDL_KBD"
# X11クライアントパッチ — client/X11/xf_keyboard.c に手動で適用
# 変更箇所の詳細は上記「有効なパッチ」セクションを参照
CMake設定
HBREW=$(brew --prefix)
cmake -S . -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_OSX_ARCHITECTURES=arm64 \
-DWITH_CLIENT_SDL=ON \
-DWITH_CLIENT_MAC=ON \
-DWITH_X11=ON \
-DWITH_FFMPEG=ON -DWITH_DSP_FFMPEG=ON -DWITH_VIDEO_FFMPEG=ON \
-DWITH_OPENH264=ON \
-DWITH_VAAPI=OFF \
-DBUILD_TESTING=OFF -DCHANNEL_URBDRC=OFF \
-DCMAKE_PREFIX_PATH="$HBREW" \
-DOPENSSL_ROOT_DIR="$HBREW/opt/openssl@3" \
"-DCMAKE_C_FLAGS=-I$HBREW/include/SDL2 -I$HBREW/include" \
"-DCMAKE_CXX_FLAGS=-I$HBREW/include/SDL2 -I$HBREW/include"
主要フラグ:
-
WITH_FFMPEG=ON+WITH_VIDEO_FFMPEG=ON: FFmpeg経由のH.264 → Apple VideoToolboxハードウェアアクセラレーション -
WITH_OPENH264=ON: OpenH264ソフトウェアフォールバック -
WITH_VAAPI=OFF: Linux専用。macOSでは非対象 -
CMAKE_OSX_ARCHITECTURES=arm64: Apple Siliconネイティブバイナリ
ビルド
ninja -C build -j$(sysctl -n hw.ncpu)
インストール
mkdir -p ~/bin
cp build/client/X11/xfreerdp ~/bin/xfreerdp-jis
# ~/bin がPATHに未追加の場合(~/.zshrc に追記)
echo 'export PATH="$HOME/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
使用方法
xfreerdp-jis /v:HOST /u:USERNAME /p:PASSWORD \
/kbd:layout:Japanese /smart-sizing \
/sound /microphone /bpp:32
パッチ適用後のJISキーマッピング:
| 物理キー(JIS) | RDPセッションでの入力結果 |
|---|---|
¥ キー |
\ バックスラッシュ |
Shift + ¥ キー |
| パイプ |
Shift + ろ キー |
_ アンダースコア |
パッチの出典
元のSDLキーボードパッチ: MORIYA Seiji氏による moriya9n/FreeRDP-SDL-JISKBD(2023年7月)。
X11キーボードパッチ、SDL3マウス修正、ビルド手順: 本ビルド作業中に発見・開発(2025年3月)。
トラブルシューティング
| 症状 | 対処法 |
|---|---|
xcode-select: tool 'ibtool' requires Xcode |
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer |
Could NOT find OpenH264 |
brew install openh264 |
SDL_ttf.h not found |
brew install sdl2_ttf を実行し、C/CXXフラグに -I$(brew --prefix)/include/SDL2 を追加 |
| SDL3マウスのクリック時クラッシュ |
sdl_context.cpp の getFirstWindow() フォールバックパッチを適用 |
freerdp_bitmap_decompress_planar failed |
/gfx および /video フラグを削除(xrdp非対応) |
Unknown key with X keycode 0x65/0x66 |
xf_keyboard.c にX11キーボードパッチを適用 |
$(brew --prefix) 使用後に zsh: command not found
|
事前に HBREW=$(brew --prefix) で変数に代入してから $HBREW を使用 |