提交 c7b10630 编写于 作者: M Marvin Häuser

OcAppleEventLib: Support dwell-clicking

Fixes https://github.com/acidanthera/bugtracker/issues/2067
上级 b6d62ed5
......@@ -4,6 +4,7 @@ OpenCore Changelog
- Updated emulated NVRAM save script for compatibilty with earlier macOS (Snow Leopard+ tested)
- Updated emulated NVRAM save script to automatically install as launch daemon (Yosemite+) or logout hook
- Fixed maximum click duration and double click speed for non-standard poll frequencies
- Added support for pointer dwell-clicking
#### v0.8.5
- Updated builtin firmware versions for SMBIOS and the rest
......
......@@ -7604,6 +7604,40 @@ for additional options.
optionally be modified in combination with \texttt{PointerSpeedDiv}, according to user
preference, to achieve customised mouse movement scaling.
\item
\texttt{PointerDwellClickTimeout}\\
\textbf{Type}: \texttt{plist\ integer}\\
\textbf{Failsafe}: \texttt{0}\\
\textbf{Description}: Configure pointer dwell-clicking single left click timeout in
milliseconds in the OpenCore re-implementation of the Apple Event protocol.
Has no effect when using the OEM Apple implementation (see \texttt{AppleEvent} setting).
When the timeout expires, a single left click is issued at the current position.
\texttt{0} indicates the timeout is disabled.
\item
\texttt{PointerDwellDoubleClickTimeout}\\
\textbf{Type}: \texttt{plist\ integer}\\
\textbf{Failsafe}: \texttt{0}\\
\textbf{Description}: Configure pointer dwell-clicking single left double click timeout in
milliseconds in the OpenCore re-implementation of the Apple Event protocol.
Has no effect when using the OEM Apple implementation (see \texttt{AppleEvent} setting).
When the timeout expires, a single left double click is issued at the current position.
\texttt{0} indicates the timeout is disabled.
\item
\texttt{PointerDwellRadius}\\
\textbf{Type}: \texttt{plist\ integer}\\
\textbf{Failsafe}: \texttt{0}\\
\textbf{Description}: Configure pointer dwell-clicking tolerance radius in pixels in the
OpenCore re-implementation of the Apple Event protocol.
Has no effect when using the OEM Apple implementation (see \texttt{AppleEvent} setting).
The radius is scaled by \texttt{UIScale}. When the pointer leaves this radius, the timeouts for \texttt{PointerDwellClickTimeout}
and \texttt{PointerDwellDoubleClickTimeout} are reset and the new position is the centre
for the new dwell-clicking tolerance radius.
\end{enumerate}
\subsection{Audio Properties}\label{uefiaudioprops}
......
......@@ -1379,6 +1379,12 @@
<integer>50</integer>
<key>KeySubsequentDelay</key>
<integer>5</integer>
<key>PointerDwellClickTimeout</key>
<integer>0</integer>
<key>PointerDwellDoubleClickTimeout</key>
<integer>0</integer>
<key>PointerDwellRadius</key>
<integer>0</integer>
<key>PointerPollMask</key>
<integer>-1</integer>
<key>PointerPollMax</key>
......
......@@ -1747,6 +1747,12 @@
<integer>50</integer>
<key>KeySubsequentDelay</key>
<integer>5</integer>
<key>PointerDwellClickTimeout</key>
<integer>0</integer>
<key>PointerDwellDoubleClickTimeout</key>
<integer>0</integer>
<key>PointerDwellRadius</key>
<integer>0</integer>
<key>PointerPollMask</key>
<integer>-1</integer>
<key>PointerPollMax</key>
......
......@@ -24,23 +24,26 @@
/**
Install and initialise Apple Event protocol.
@param[in] Install If false, do not install even when no suitable OEM version found.
@param[in] Reinstall If true, force overwrite installed protocol.
If false, use Apple OEM protocol where possible.
@param[in] CustomDelays If true, use key delays specified.
If false, use Apple OEM default key delay values.
OC builtin AppleEvent only.
@param[in] KeyInitialDelay Key repeat initial delay in 10ms units.
@param[in] KeySubsequentDelay Key repeat subsequent delay in 10ms units.
If zero, warn and use 1.
@param[in] GraphicsInputMirroring If true, disable Apple default behaviour which can
prevent keyboard input reaching non-Apple GUI UEFI apps.
OC builtin AppleEvent only.
@param[in] PointerPollMin Pointer polling minimal period in ms.
@param[in] PointerPollMax Pointer polling maximum period in ms.
@param[in] PointerPollMask Pointer polling mask to choose polled handles.
@param[in] PointerSpeedDiv Pointer speed divisor. If zero, warn and use 1.
@param[in] PointerSpeedMul Pointer speed multiplier.
@param[in] Install If false, do not install even when no suitable OEM version found.
@param[in] Reinstall If true, force overwrite installed protocol.
If false, use Apple OEM protocol where possible.
@param[in] CustomDelays If true, use key delays specified.
If false, use Apple OEM default key delay values.
OC builtin AppleEvent only.
@param[in] KeyInitialDelay Key repeat initial delay in 10ms units.
@param[in] KeySubsequentDelay Key repeat subsequent delay in 10ms units.
If zero, warn and use 1.
@param[in] GraphicsInputMirroring If true, disable Apple default behaviour which can
prevent keyboard input reaching non-Apple GUI UEFI apps.
OC builtin AppleEvent only.
@param[in] PointerPollMin Pointer polling minimal period in ms.
@param[in] PointerPollMax Pointer polling maximum period in ms.
@param[in] PointerPollMask Pointer polling mask to choose polled handles.
@param[in] PointerSpeedDiv Pointer speed divisor. If zero, warn and use 1.
@param[in] PointerSpeedMul Pointer speed multiplier.
@param[in] PointerDwellClickTimeout Pointer dwell-clicking single left click timeout.
@param[in] PointerDwellDoubleClickTimeout Pointer dwell-clicking single left double click timeout.
@param[in] PointerDwellRadius Pointer dwell-clicking tolerance radius in pixels.
@retval installed or located protocol or NULL.
**/
......@@ -56,7 +59,10 @@ OcAppleEventInstallProtocol (
IN UINT32 PointerPollMax,
IN UINT32 PointerPollMask,
IN UINT16 PointerSpeedDiv,
IN UINT16 PointerSpeedMul
IN UINT16 PointerSpeedMul,
IN UINT16 PointerDwellClickTimeout,
IN UINT16 PointerDwellDoubleClickTimeout,
IN UINT16 PointerDwellRadius
);
#endif // OC_APPLE_EVENT_LIB_H
......@@ -633,16 +633,19 @@ OC_DECLARE (OC_UEFI_APFS)
/// AppleInput is a set of options to configure OpenCore's reverse engingeered then customised implementation of the AppleEvent protocol.
///
#define OC_UEFI_APPLEINPUT_FIELDS(_, __) \
_(OC_STRING , AppleEvent , , OC_STRING_CONSTR ("Auto", _, __) , OC_DESTR (OC_STRING) ) \
_(BOOLEAN , CustomDelays , , FALSE , ()) \
_(UINT16 , KeyInitialDelay , , 50 , ()) \
_(UINT16 , KeySubsequentDelay , , 5 , ()) \
_(BOOLEAN , GraphicsInputMirroring, , FALSE , ()) \
_(UINT32 , PointerPollMin , , 0 , ()) \
_(UINT32 , PointerPollMax , , 0 , ()) \
_(UINT32 , PointerPollMask , , ((UINT32) (-1)) , ()) \
_(UINT16 , PointerSpeedDiv , , 1 , ()) \
_(UINT16 , PointerSpeedMul , , 1 , ())
_(OC_STRING , AppleEvent , , OC_STRING_CONSTR ("Auto", _, __) , OC_DESTR (OC_STRING) ) \
_(BOOLEAN , CustomDelays , , FALSE , ()) \
_(UINT16 , KeyInitialDelay , , 50 , ()) \
_(UINT16 , KeySubsequentDelay , , 5 , ()) \
_(BOOLEAN , GraphicsInputMirroring , , FALSE , ()) \
_(UINT32 , PointerPollMin , , 0 , ()) \
_(UINT32 , PointerPollMax , , 0 , ()) \
_(UINT32 , PointerPollMask , , ((UINT32) (-1)) , ()) \
_(UINT16 , PointerSpeedDiv , , 1 , ()) \
_(UINT16 , PointerSpeedMul , , 1 , ()) \
_(UINT16 , PointerDwellClickTimeout , , 0 , ()) \
_(UINT16 , PointerDwellDoubleClickTimeout, , 0 , ()) \
_(UINT16 , PointerDwellRadius , , 0 , ())
OC_DECLARE (OC_UEFI_APPLEINPUT)
///
......
......@@ -164,6 +164,11 @@ InternalSetKeyBehaviour (
IN BOOLEAN GraphicsInputMirroring
);
VOID
InternalInitializePointerUiScale (
VOID
);
VOID
InternalSetPointerPolling (
IN UINT32 PointerPollMin,
......@@ -177,6 +182,13 @@ InternalSetPointerSpeed (
IN UINT16 PointerSpeedMul
);
VOID
InternalSetDwellClicking (
IN UINT16 ClickTimeout,
IN UINT16 DoubleClickTimeout,
IN UINT16 Radius
);
extern UINT32 mPointerSpeedMul;
extern UINT32 mPointerSpeedDiv;
......
......@@ -564,7 +564,10 @@ OcAppleEventInstallProtocol (
IN UINT32 PointerPollMax,
IN UINT32 PointerPollMask,
IN UINT16 PointerSpeedDiv,
IN UINT16 PointerSpeedMul
IN UINT16 PointerSpeedMul,
IN UINT16 PointerDwellClickTimeout,
IN UINT16 PointerDwellDoubleClickTimeout,
IN UINT16 PointerDwellRadius
)
{
EFI_STATUS Status;
......@@ -618,8 +621,14 @@ OcAppleEventInstallProtocol (
GraphicsInputMirroring
);
InternalInitializePointerUiScale ();
InternalSetPointerPolling (PointerPollMin, PointerPollMax, PointerPollMask);
InternalSetPointerSpeed (PointerSpeedDiv, PointerSpeedMul);
InternalSetDwellClicking (
PointerDwellClickTimeout,
PointerDwellDoubleClickTimeout,
PointerDwellRadius
);
Status = gBS->InstallMultipleProtocolInterfaces (
&gImageHandle,
......
......@@ -144,6 +144,33 @@ STATIC UINT64 mMaxPointerResolutionY = 1;
STATIC UINT64 mPointerRawX;
STATIC UINT64 mPointerRawY;
STATIC UINT32 mDwellClickTimeout;
STATIC UINT32 mDwellDoubleClickTimeout;
STATIC UINT32 mDwellClickRadiusSqr;
STATIC DIMENSION mDwellPosition;
STATIC UINT32 mDwellClickTime;
VOID
InternalInitializePointerUiScale (
VOID
)
{
EFI_STATUS Status;
UINTN DataSize;
DataSize = sizeof (mUiScale);
Status = gRT->GetVariable (
APPLE_UI_SCALE_VARIABLE_NAME,
&gAppleVendorVariableGuid,
NULL,
&DataSize,
(VOID *)&mUiScale
);
if (EFI_ERROR (Status) || (mUiScale != 2)) {
mUiScale = 1;
}
}
VOID
InternalSetPointerPolling (
IN UINT32 PointerPollMin,
......@@ -193,6 +220,18 @@ InternalSetPointerSpeed (
mPointerSpeedMul = PointerSpeedMul;
}
VOID
InternalSetDwellClicking (
IN UINT16 ClickTimeout,
IN UINT16 DoubleClickTimeout,
IN UINT16 Radius
)
{
mDwellClickTimeout = (UINT32)ClickTimeout * 10000;
mDwellDoubleClickTimeout = (UINT32)DoubleClickTimeout * 10000;
mDwellClickRadiusSqr = ((UINT32)Radius * Radius) * (mUiScale * mUiScale);
}
// InternalRegisterSimplePointerInterface
STATIC
VOID
......@@ -720,6 +759,90 @@ InternalHandleButtonInteraction (
++Pointer->ButtonTicksSinceClick;
}
STATIC
VOID
InternalResetDwellClicking (
VOID
)
{
mDwellClickTime = 0;
CopyMem (
&mDwellPosition,
&mCursorPosition,
sizeof (mDwellPosition)
);
}
STATIC
VOID
InternalQueueDwellClick (
IN APPLE_EVENT_TYPE EventType,
IN APPLE_MODIFIER_MAP Modifiers
)
{
APPLE_EVENT_INFORMATION *Information;
Information = InternalCreatePointerEventQueueInformation (
APPLE_EVENT_TYPE_LEFT_BUTTON | APPLE_EVENT_TYPE_MOUSE_DOWN,
Modifiers
);
if (Information != NULL) {
EventAddEventToQueue (Information);
}
Information = InternalCreatePointerEventQueueInformation (
APPLE_EVENT_TYPE_LEFT_BUTTON | APPLE_EVENT_TYPE_MOUSE_UP,
Modifiers
);
if (Information != NULL) {
EventAddEventToQueue (Information);
}
Information = InternalCreatePointerEventQueueInformation (
APPLE_EVENT_TYPE_LEFT_BUTTON | EventType,
Modifiers
);
if (Information != NULL) {
EventAddEventToQueue (Information);
}
}
STATIC
VOID
InternalHandleDwellClicking (
IN APPLE_MODIFIER_MAP Modifiers
)
{
BOOLEAN ClickDisabled;
BOOLEAN DoubleClickDisabled;
INT32 DistX;
INT32 DistY;
ClickDisabled = mDwellClickTimeout == 0;
DoubleClickDisabled = mDwellDoubleClickTimeout == 0;
if (ClickDisabled && DoubleClickDisabled) {
return;
}
DistX = mCursorPosition.Horizontal - mDwellPosition.Horizontal;
DistY = mCursorPosition.Vertical - mDwellPosition.Vertical;
if ((UINT32)(DistX * DistX + DistY * DistY) <= mDwellClickRadiusSqr) {
mDwellClickTime += mSimplePointerPollTime;
if (!DoubleClickDisabled && (mDwellClickTime >= mDwellDoubleClickTimeout)) {
InternalQueueDwellClick (APPLE_EVENT_TYPE_MOUSE_DOUBLE_CLICK, Modifiers);
InternalResetDwellClicking ();
} else if (!ClickDisabled && (mDwellClickTime >= mDwellClickTimeout)) {
InternalQueueDwellClick (APPLE_EVENT_TYPE_MOUSE_CLICK, Modifiers);
if (DoubleClickDisabled) {
InternalResetDwellClicking ();
}
}
} else {
InternalResetDwellClicking ();
}
}
// InternalSimplePointerPollNotifyFunction
STATIC
VOID
......@@ -879,6 +1002,8 @@ InternalSimplePointerPollNotifyFunction (
InternalHandleButtonInteraction (CommonStatus, &mLeftButtonInfo, Modifiers);
InternalHandleButtonInteraction (CommonStatus, &mRightButtonInfo, Modifiers);
InternalHandleDwellClicking (Modifiers);
}
if (EFI_ERROR (CommonStatus)) {
......@@ -944,25 +1069,10 @@ EventCreateSimplePointerPollEvent (
)
{
EFI_STATUS Status;
UINTN DataSize;
UINTN Index;
DEBUG ((DEBUG_VERBOSE, "EventCreateSimplePointerPollEvent\n"));
DataSize = sizeof (mUiScale);
Status = gRT->GetVariable (
APPLE_UI_SCALE_VARIABLE_NAME,
&gAppleVendorVariableGuid,
NULL,
&DataSize,
(VOID *)&mUiScale
);
if (EFI_ERROR (Status) || (mUiScale != 2)) {
mUiScale = 1;
}
InternalRemoveUninstalledInstances (
&mPointerProtocols,
&mNumberOfPointerProtocols,
......
......@@ -764,16 +764,19 @@ OC_SCHEMA
STATIC
OC_SCHEMA
mUefiAppleInputSchema[] = {
OC_SCHEMA_STRING_IN ("AppleEvent", OC_GLOBAL_CONFIG, Uefi.AppleInput.AppleEvent),
OC_SCHEMA_BOOLEAN_IN ("CustomDelays", OC_GLOBAL_CONFIG, Uefi.AppleInput.CustomDelays),
OC_SCHEMA_BOOLEAN_IN ("GraphicsInputMirroring", OC_GLOBAL_CONFIG, Uefi.AppleInput.GraphicsInputMirroring),
OC_SCHEMA_INTEGER_IN ("KeyInitialDelay", OC_GLOBAL_CONFIG, Uefi.AppleInput.KeyInitialDelay),
OC_SCHEMA_INTEGER_IN ("KeySubsequentDelay", OC_GLOBAL_CONFIG, Uefi.AppleInput.KeySubsequentDelay),
OC_SCHEMA_INTEGER_IN ("PointerPollMask", OC_GLOBAL_CONFIG, Uefi.AppleInput.PointerPollMask),
OC_SCHEMA_INTEGER_IN ("PointerPollMax", OC_GLOBAL_CONFIG, Uefi.AppleInput.PointerPollMax),
OC_SCHEMA_INTEGER_IN ("PointerPollMin", OC_GLOBAL_CONFIG, Uefi.AppleInput.PointerPollMin),
OC_SCHEMA_INTEGER_IN ("PointerSpeedDiv", OC_GLOBAL_CONFIG, Uefi.AppleInput.PointerSpeedDiv),
OC_SCHEMA_INTEGER_IN ("PointerSpeedMul", OC_GLOBAL_CONFIG, Uefi.AppleInput.PointerSpeedMul),
OC_SCHEMA_STRING_IN ("AppleEvent", OC_GLOBAL_CONFIG, Uefi.AppleInput.AppleEvent),
OC_SCHEMA_BOOLEAN_IN ("CustomDelays", OC_GLOBAL_CONFIG, Uefi.AppleInput.CustomDelays),
OC_SCHEMA_BOOLEAN_IN ("GraphicsInputMirroring", OC_GLOBAL_CONFIG, Uefi.AppleInput.GraphicsInputMirroring),
OC_SCHEMA_INTEGER_IN ("KeyInitialDelay", OC_GLOBAL_CONFIG, Uefi.AppleInput.KeyInitialDelay),
OC_SCHEMA_INTEGER_IN ("KeySubsequentDelay", OC_GLOBAL_CONFIG, Uefi.AppleInput.KeySubsequentDelay),
OC_SCHEMA_INTEGER_IN ("PointerDwellClickTimeout", OC_GLOBAL_CONFIG, Uefi.AppleInput.PointerDwellClickTimeout),
OC_SCHEMA_INTEGER_IN ("PointerDwellDoubleClickTimeout", OC_GLOBAL_CONFIG, Uefi.AppleInput.PointerDwellDoubleClickTimeout),
OC_SCHEMA_INTEGER_IN ("PointerDwellRadius", OC_GLOBAL_CONFIG, Uefi.AppleInput.PointerDwellRadius),
OC_SCHEMA_INTEGER_IN ("PointerPollMask", OC_GLOBAL_CONFIG, Uefi.AppleInput.PointerPollMask),
OC_SCHEMA_INTEGER_IN ("PointerPollMax", OC_GLOBAL_CONFIG, Uefi.AppleInput.PointerPollMax),
OC_SCHEMA_INTEGER_IN ("PointerPollMin", OC_GLOBAL_CONFIG, Uefi.AppleInput.PointerPollMin),
OC_SCHEMA_INTEGER_IN ("PointerSpeedDiv", OC_GLOBAL_CONFIG, Uefi.AppleInput.PointerSpeedDiv),
OC_SCHEMA_INTEGER_IN ("PointerSpeedMul", OC_GLOBAL_CONFIG, Uefi.AppleInput.PointerSpeedMul),
};
STATIC
......
......@@ -451,7 +451,10 @@ OcReinstallProtocols (
Config->Uefi.AppleInput.PointerPollMax,
Config->Uefi.AppleInput.PointerPollMask,
Config->Uefi.AppleInput.PointerSpeedDiv,
Config->Uefi.AppleInput.PointerSpeedMul
Config->Uefi.AppleInput.PointerSpeedMul,
Config->Uefi.AppleInput.PointerDwellClickTimeout,
Config->Uefi.AppleInput.PointerDwellDoubleClickTimeout,
Config->Uefi.AppleInput.PointerDwellRadius
) == NULL)
&& InstallAppleEvent)
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册