mirror of https://github.com/jetkvm/kvm.git
chore: resolve conflicts
This commit is contained in:
parent
44b25eb33f
commit
8484bb3f38
|
@ -1,27 +1,20 @@
|
||||||
import { useCallback, useRef } from "react";
|
import { useCallback, useRef } from "react";
|
||||||
|
|
||||||
import {
|
|
||||||
hidErrorRollOver,
|
|
||||||
hidKeyBufferSize,
|
|
||||||
KeysDownState,
|
|
||||||
useHidStore,
|
|
||||||
useRTCStore,
|
|
||||||
} from "@/hooks/stores";
|
|
||||||
import {
|
|
||||||
hidErrorRollOver,
|
|
||||||
hidKeyBufferSize,
|
|
||||||
KeysDownState,
|
|
||||||
useHidStore,
|
|
||||||
useRTCStore,
|
|
||||||
} from "@/hooks/stores";
|
|
||||||
import { JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc";
|
|
||||||
import { useHidRpc } from "@/hooks/useHidRpc";
|
|
||||||
import {
|
import {
|
||||||
KeyboardLedStateMessage,
|
KeyboardLedStateMessage,
|
||||||
KeyboardMacroStateMessage,
|
KeyboardMacroStateMessage,
|
||||||
KeyboardMacroStep,
|
KeyboardMacroStep,
|
||||||
KeysDownStateMessage,
|
KeysDownStateMessage,
|
||||||
} from "@/hooks/hidRpc";
|
} from "@/hooks/hidRpc";
|
||||||
|
import {
|
||||||
|
hidErrorRollOver,
|
||||||
|
hidKeyBufferSize,
|
||||||
|
KeysDownState,
|
||||||
|
useHidStore,
|
||||||
|
useRTCStore,
|
||||||
|
} from "@/hooks/stores";
|
||||||
|
import { useHidRpc } from "@/hooks/useHidRpc";
|
||||||
|
import { JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc";
|
||||||
import { hidKeyToModifierMask, keys, modifiers } from "@/keyboardMappings";
|
import { hidKeyToModifierMask, keys, modifiers } from "@/keyboardMappings";
|
||||||
|
|
||||||
const MACRO_RESET_KEYBOARD_STATE = {
|
const MACRO_RESET_KEYBOARD_STATE = {
|
||||||
|
@ -72,7 +65,6 @@ export default function useKeyboard() {
|
||||||
cancelOngoingKeyboardMacro: cancelOngoingKeyboardMacroHidRpc,
|
cancelOngoingKeyboardMacro: cancelOngoingKeyboardMacroHidRpc,
|
||||||
reportKeypressKeepAlive: sendKeypressKeepAliveHidRpc,
|
reportKeypressKeepAlive: sendKeypressKeepAliveHidRpc,
|
||||||
rpcHidReady,
|
rpcHidReady,
|
||||||
} = useHidRpc(message => {
|
|
||||||
} = useHidRpc(message => {
|
} = useHidRpc(message => {
|
||||||
switch (message.constructor) {
|
switch (message.constructor) {
|
||||||
case KeysDownStateMessage:
|
case KeysDownStateMessage:
|
||||||
|
@ -100,36 +92,10 @@ export default function useKeyboard() {
|
||||||
// On older backends, we need to set the keysDownState manually since without the hidRpc API, the state doesn't trickle down from the backend
|
// On older backends, we need to set the keysDownState manually since without the hidRpc API, the state doesn't trickle down from the backend
|
||||||
setKeysDownState({ modifier, keys });
|
setKeysDownState({ modifier, keys });
|
||||||
});
|
});
|
||||||
// sendKeyboardEvent is used to send the full keyboard state to the device for macro handling
|
|
||||||
// and resetting keyboard state. It sends the keys currently pressed and the modifier state.
|
|
||||||
// The device will respond with the keysDownState if it supports the keyPressReport API
|
|
||||||
// or just accept the state if it does not support (returning no result)
|
|
||||||
const sendKeyboardEvent = useCallback(
|
|
||||||
async (state: KeysDownState) => {
|
|
||||||
if (rpcDataChannel?.readyState !== "open" && !rpcHidReady) return;
|
|
||||||
|
|
||||||
console.debug(
|
|
||||||
`Send keyboardReport keys: ${state.keys}, modifier: ${state.modifier}`,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (rpcHidReady) {
|
|
||||||
console.debug("Sending keyboard report via HidRPC");
|
|
||||||
sendKeyboardEventHidRpc(state.keys, state.modifier);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
send(
|
|
||||||
"keyboardReport",
|
|
||||||
{ keys: state.keys, modifier: state.modifier },
|
|
||||||
(resp: JsonRpcResponse) => {
|
|
||||||
if ("error" in resp) {
|
|
||||||
console.error(`Failed to send keyboard report ${state}`, resp.error);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
[send, setKeysDownState],
|
[send, setKeysDownState],
|
||||||
);
|
);
|
||||||
|
|
||||||
const sendKeystrokeLegacy = useCallback(async (keys: number[], modifier: number, ac?: AbortController) => {
|
const sendKeystrokeLegacy = useCallback(async (keys: number[], modifier: number, ac?: AbortController) => {
|
||||||
return await new Promise<void>((resolve, reject) => {
|
return await new Promise<void>((resolve, reject) => {
|
||||||
const abortListener = () => {
|
const abortListener = () => {
|
||||||
|
@ -149,22 +115,6 @@ export default function useKeyboard() {
|
||||||
});
|
});
|
||||||
}, [send]);
|
}, [send]);
|
||||||
|
|
||||||
// resetKeyboardState is used to reset the keyboard state to no keys pressed and no modifiers.
|
|
||||||
// This is useful for macros and when the browser loses focus to ensure that the keyboard state
|
|
||||||
// is clean.
|
|
||||||
const resetKeyboardState = useCallback(async () => {
|
|
||||||
// Reset the keys buffer to zeros and the modifier state to zero
|
|
||||||
const { keys, modifier } = MACRO_RESET_KEYBOARD_STATE;
|
|
||||||
if (rpcHidReady) {
|
|
||||||
sendKeyboardEventHidRpc(keys, modifier);
|
|
||||||
} else {
|
|
||||||
// Older backends don't support the hidRpc API, so we send the full reset state
|
|
||||||
handleLegacyKeyboardReport(keys, modifier);
|
|
||||||
}
|
|
||||||
}, [rpcHidReady, sendKeyboardEventHidRpc, handleLegacyKeyboardReport]);
|
|
||||||
|
|
||||||
[rpcDataChannel?.readyState, rpcHidReady, send, sendKeyboardEventHidRpc],
|
|
||||||
);
|
|
||||||
|
|
||||||
// executeMacro is used to execute a macro consisting of multiple steps.
|
// executeMacro is used to execute a macro consisting of multiple steps.
|
||||||
// Each step can have multiple keys, multiple modifiers and a delay.
|
// Each step can have multiple keys, multiple modifiers and a delay.
|
||||||
|
@ -260,7 +210,6 @@ export default function useKeyboard() {
|
||||||
// we don't need to cancel it actually
|
// we don't need to cancel it actually
|
||||||
cancelOngoingKeyboardMacroHidRpc();
|
cancelOngoingKeyboardMacroHidRpc();
|
||||||
}, [rpcHidReady, cancelOngoingKeyboardMacroHidRpc, abortController]);
|
}, [rpcHidReady, cancelOngoingKeyboardMacroHidRpc, abortController]);
|
||||||
};
|
|
||||||
|
|
||||||
const KEEPALIVE_INTERVAL = 50;
|
const KEEPALIVE_INTERVAL = 50;
|
||||||
|
|
||||||
|
@ -285,13 +234,15 @@ export default function useKeyboard() {
|
||||||
const resetKeyboardState = useCallback(async () => {
|
const resetKeyboardState = useCallback(async () => {
|
||||||
// Cancel keepalive since we're resetting the keyboard state
|
// Cancel keepalive since we're resetting the keyboard state
|
||||||
cancelKeepAlive();
|
cancelKeepAlive();
|
||||||
|
|
||||||
// Reset the keys buffer to zeros and the modifier state to zero
|
// Reset the keys buffer to zeros and the modifier state to zero
|
||||||
keysDownState.keys.length = hidKeyBufferSize;
|
const { keys, modifier } = MACRO_RESET_KEYBOARD_STATE;
|
||||||
keysDownState.keys.fill(0);
|
if (rpcHidReady) {
|
||||||
keysDownState.modifier = 0;
|
sendKeyboardEventHidRpc(keys, modifier);
|
||||||
sendKeyboardEvent(keysDownState);
|
} else {
|
||||||
}, [keysDownState, sendKeyboardEvent, cancelKeepAlive]);
|
// Older backends don't support the hidRpc API, so we send the full reset state
|
||||||
|
handleLegacyKeyboardReport(keys, modifier);
|
||||||
|
}
|
||||||
|
}, [rpcHidReady, sendKeyboardEventHidRpc, handleLegacyKeyboardReport, cancelKeepAlive]);
|
||||||
|
|
||||||
// handleKeyPress is used to handle a key press or release event.
|
// handleKeyPress is used to handle a key press or release event.
|
||||||
// This function handle both key press and key release events.
|
// This function handle both key press and key release events.
|
||||||
|
@ -331,13 +282,9 @@ export default function useKeyboard() {
|
||||||
// 1. Calculate the state
|
// 1. Calculate the state
|
||||||
// 2. Send the newly calculated state to the device
|
// 2. Send the newly calculated state to the device
|
||||||
const downState = simulateDeviceSideKeyHandlingForLegacyDevices(
|
const downState = simulateDeviceSideKeyHandlingForLegacyDevices(
|
||||||
|
|
||||||
keysDownState,
|
keysDownState,
|
||||||
|
|
||||||
key,
|
key,
|
||||||
|
|
||||||
press,
|
press,
|
||||||
,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
handleLegacyKeyboardReport(downState.keys, downState.modifier);
|
handleLegacyKeyboardReport(downState.keys, downState.modifier);
|
||||||
|
@ -351,25 +298,18 @@ export default function useKeyboard() {
|
||||||
[
|
[
|
||||||
rpcDataChannel?.readyState,
|
rpcDataChannel?.readyState,
|
||||||
rpcHidReady,
|
rpcHidReady,
|
||||||
sendKeypressEventHidRpc,
|
|
||||||
keysDownState,
|
keysDownState,
|
||||||
handleLegacyKeyboardReport,
|
handleLegacyKeyboardReport,
|
||||||
resetKeyboardState,
|
resetKeyboardState,
|
||||||
rpcDataChannel?.readyState,
|
|
||||||
sendKeyboardEvent,
|
|
||||||
sendKeypress,
|
sendKeypress,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
// IMPORTANT: See the keyPressReportApiAvailable comment above for the reason this exists
|
// IMPORTANT: See the keyPressReportApiAvailable comment above for the reason this exists
|
||||||
function simulateDeviceSideKeyHandlingForLegacyDevices(
|
function simulateDeviceSideKeyHandlingForLegacyDevices(
|
||||||
|
|
||||||
state: KeysDownState,
|
state: KeysDownState,
|
||||||
|
|
||||||
key: number,
|
key: number,
|
||||||
|
|
||||||
press: boolean,
|
press: boolean,
|
||||||
,
|
|
||||||
): KeysDownState {
|
): KeysDownState {
|
||||||
// IMPORTANT: This code parallels the logic in the kernel's hid-gadget driver
|
// IMPORTANT: This code parallels the logic in the kernel's hid-gadget driver
|
||||||
// for handling key presses and releases. It ensures that the USB gadget
|
// for handling key presses and releases. It ensures that the USB gadget
|
||||||
|
@ -415,17 +355,13 @@ export default function useKeyboard() {
|
||||||
// If we reach here it means we didn't find an empty slot or the key in the buffer
|
// If we reach here it means we didn't find an empty slot or the key in the buffer
|
||||||
if (overrun) {
|
if (overrun) {
|
||||||
if (press) {
|
if (press) {
|
||||||
console.warn(
|
console.warn(`keyboard buffer overflow current keys ${keys}, key: ${key} not added`);
|
||||||
|
|
||||||
`keyboard buffer overflow current keys ${keys}, key: ${key} not added`,
|
|
||||||
,
|
|
||||||
);
|
|
||||||
// Fill all key slots with ErrorRollOver (0x01) to indicate overflow
|
// Fill all key slots with ErrorRollOver (0x01) to indicate overflow
|
||||||
keys.length = hidKeyBufferSize;
|
keys.length = hidKeyBufferSize;
|
||||||
keys.fill(hidErrorRollOver);
|
keys.fill(hidErrorRollOver);
|
||||||
} else {
|
} else {
|
||||||
// If we are releasing a key, and we didn't find it in a slot, who cares?
|
// If we are releasing a key, and we didn't find it in a slot, who cares?
|
||||||
console.debug(`key ${key} not found in buffer, nothing to release`);;
|
console.debug(`key ${key} not found in buffer, nothing to release`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue