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

OpenCanopy: Initial double-click support

上级 0a97ed4f
...@@ -16,13 +16,6 @@ typedef struct GUI_OUTPUT_CONTEXT_ GUI_OUTPUT_CONTEXT; ...@@ -16,13 +16,6 @@ typedef struct GUI_OUTPUT_CONTEXT_ GUI_OUTPUT_CONTEXT;
typedef struct GUI_POINTER_CONTEXT_ GUI_POINTER_CONTEXT; typedef struct GUI_POINTER_CONTEXT_ GUI_POINTER_CONTEXT;
typedef struct GUI_KEY_CONTEXT_ GUI_KEY_CONTEXT; typedef struct GUI_KEY_CONTEXT_ GUI_KEY_CONTEXT;
typedef struct {
UINT32 X;
UINT32 Y;
BOOLEAN PrimaryDown;
BOOLEAN SecondaryDown;
} GUI_POINTER_STATE;
GUI_OUTPUT_CONTEXT * GUI_OUTPUT_CONTEXT *
GuiOutputConstruct ( GuiOutputConstruct (
VOID VOID
...@@ -53,10 +46,16 @@ GuiOutputDestruct ( ...@@ -53,10 +46,16 @@ GuiOutputDestruct (
IN GUI_OUTPUT_CONTEXT *Context IN GUI_OUTPUT_CONTEXT *Context
); );
BOOLEAN
GuiPointerGetEvent (
IN OUT GUI_POINTER_CONTEXT *Context,
OUT GUI_PTR_EVENT *Event
);
VOID VOID
GuiPointerGetState ( GuiPointerGetPosition (
IN OUT GUI_POINTER_CONTEXT *Context, IN OUT GUI_POINTER_CONTEXT *Context,
OUT GUI_POINTER_STATE *State OUT GUI_PTR_POSITION *Position
); );
VOID VOID
...@@ -69,7 +68,8 @@ GuiPointerConstruct ( ...@@ -69,7 +68,8 @@ GuiPointerConstruct (
IN UINT32 DefaultX, IN UINT32 DefaultX,
IN UINT32 DefaultY, IN UINT32 DefaultY,
IN UINT32 Width, IN UINT32 Width,
IN UINT32 Height IN UINT32 Height,
IN UINT8 UiScale
); );
VOID VOID
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <Library/BaseLib.h> #include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h> #include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
#include <Library/OcCpuLib.h>
#include <Library/OcGuardLib.h> #include <Library/OcGuardLib.h>
#include <Library/OcMiscLib.h> #include <Library/OcMiscLib.h>
#include <Library/UefiBootServicesTableLib.h> #include <Library/UefiBootServicesTableLib.h>
...@@ -20,16 +21,25 @@ ...@@ -20,16 +21,25 @@
#include "../OpenCanopy.h" #include "../OpenCanopy.h"
#include "../GuiIo.h" #include "../GuiIo.h"
#define ABS_DOUBLE_CLICK_RADIUS 25U
#define IS_POWER_2(x) (((x) & ((x) - 1)) == 0 && (x) != 0)
struct GUI_POINTER_CONTEXT_ { struct GUI_POINTER_CONTEXT_ {
APPLE_EVENT_PROTOCOL *AppleEvent; APPLE_EVENT_PROTOCOL *AppleEvent;
EFI_ABSOLUTE_POINTER_PROTOCOL *AbsPointer; EFI_ABSOLUTE_POINTER_PROTOCOL *AbsPointer;
APPLE_EVENT_HANDLE AppleEventHandle; APPLE_EVENT_HANDLE AppleEventHandle;
UINT32 MaxX; UINT32 MaxX;
UINT32 MaxY; UINT32 MaxY;
INT32 RawX; GUI_PTR_POSITION RawPos;
INT32 RawY; GUI_PTR_POSITION CurPos;
GUI_POINTER_STATE CurState; GUI_PTR_POSITION AbsLastDownPos;
BOOLEAN AbsPrimaryDown;
BOOLEAN AbsDoubleClick;
UINT8 UiScale;
UINT8 LockedBy; UINT8 LockedBy;
UINT8 EventQueueHead;
UINT8 EventQueueTail;
GUI_PTR_EVENT EventQueue[16];
}; };
enum { enum {
...@@ -38,6 +48,63 @@ enum { ...@@ -38,6 +48,63 @@ enum {
PointerLockedAbsolute PointerLockedAbsolute
}; };
STATIC
VOID
InternalQueuePointerEvent (
IN OUT GUI_POINTER_CONTEXT *Context,
IN UINT8 Type,
IN UINT32 X,
IN UINT32 Y
)
{
UINT32 Tail;
//
// Tail can be accessed concurrently, so increment atomically.
// Due to the modulus, wraparounds do not matter. The size of the queue must
// be a power of two for this to hold.
//
STATIC_ASSERT (
IS_POWER_2 (ARRAY_SIZE (Context->EventQueue)),
"The pointer event queue must have a power of two length."
);
Tail = OcAtomicPreIncUint8 (&Context->EventQueueTail) % ARRAY_SIZE (Context->EventQueue);
Context->EventQueue[Tail].Type = Type;
Context->EventQueue[Tail].Pos.Pos.X = X;
Context->EventQueue[Tail].Pos.Pos.Y = Y;
}
BOOLEAN
GuiPointerGetEvent (
IN OUT GUI_POINTER_CONTEXT *Context,
OUT GUI_PTR_EVENT *Event
)
{
//
// EventQueueHead cannot be accessed concurrently.
//
if (Context->EventQueueHead == Context->EventQueueTail) {
return FALSE;
}
CopyMem (
Event,
&Context->EventQueue[Context->EventQueueHead % ARRAY_SIZE (Context->EventQueue)],
sizeof (*Event)
);
//
// Due to the modulus, wraparounds do not matter. The size of the queue must
// be a power of two for this to hold.
//
STATIC_ASSERT (
IS_POWER_2 (ARRAY_SIZE (Context->EventQueue)),
"The pointer event queue must have a power of two length."
);
++Context->EventQueueHead;
return TRUE;
}
STATIC STATIC
VOID VOID
EFIAPI EFIAPI
...@@ -48,8 +115,8 @@ InternalAppleEventNotification ( ...@@ -48,8 +115,8 @@ InternalAppleEventNotification (
{ {
APPLE_POINTER_EVENT_TYPE EventType; APPLE_POINTER_EVENT_TYPE EventType;
GUI_POINTER_CONTEXT *Context; GUI_POINTER_CONTEXT *Context;
INT32 NewX; GUI_PTR_POSITION NewPos;
INT32 NewY; GUI_PTR_POSITION NewRaw;
INT64 NewCoord; INT64 NewCoord;
Context = NotifyContext; Context = NotifyContext;
...@@ -62,12 +129,6 @@ InternalAppleEventNotification ( ...@@ -62,12 +129,6 @@ InternalAppleEventNotification (
return; return;
} }
if ((Context->CurState.PrimaryDown | Context->CurState.SecondaryDown) == 0) {
ASSERT (Context->LockedBy == PointerUnlocked);
} else {
ASSERT (Context->LockedBy == PointerLockedSimple);
}
EventType = Information->EventData.PointerEventType; EventType = Information->EventData.PointerEventType;
if ((EventType & APPLE_EVENT_TYPE_MOUSE_MOVED) != 0) { if ((EventType & APPLE_EVENT_TYPE_MOUSE_MOVED) != 0) {
...@@ -75,49 +136,63 @@ InternalAppleEventNotification ( ...@@ -75,49 +136,63 @@ InternalAppleEventNotification (
// Use a factor of 2 for pointer acceleration. // Use a factor of 2 for pointer acceleration.
// //
NewX = Information->PointerPosition.Horizontal; NewRaw.Pos.X = (UINT32) Information->PointerPosition.Horizontal;
NewCoord = (INT64) Context->CurState.X + 2 * ((INT64) NewX - Context->RawX); NewCoord = (INT64) Context->CurPos.Pos.X + 2 * ((INT64) NewRaw.Pos.X - Context->RawPos.Pos.X);
if (NewCoord < 0) { if (NewCoord < 0) {
NewCoord = 0; NewPos.Pos.X = 0;
} else if (NewCoord > Context->MaxX) { } else if (NewCoord > Context->MaxX) {
NewCoord = Context->MaxX; NewPos.Pos.X = Context->MaxX;
} else {
NewPos.Pos.X = (UINT32) NewCoord;
} }
Context->CurState.X = (UINT32) NewCoord; NewRaw.Pos.Y = (UINT32) Information->PointerPosition.Vertical;
Context->RawX = NewX;
NewY = Information->PointerPosition.Vertical; NewCoord = (INT64) Context->CurPos.Pos.Y + 2 * ((INT64) NewRaw.Pos.Y - Context->RawPos.Pos.Y);
NewCoord = (INT64) Context->CurState.Y + 2 * ((INT64) NewY - Context->RawY);
if (NewCoord < 0) { if (NewCoord < 0) {
NewCoord = 0; NewPos.Pos.Y = 0;
} else if (NewCoord > Context->MaxY) { } else if (NewCoord > Context->MaxY) {
NewCoord = Context->MaxY; NewPos.Pos.Y = Context->MaxY;
} else {
NewPos.Pos.Y = (UINT32) NewCoord;
} }
Context->CurState.Y = (UINT32) NewCoord; Context->CurPos.Uint64 = NewPos.Uint64;
Context->RawY = NewY; Context->RawPos.Uint64 = NewRaw.Uint64;
} }
if ((EventType & APPLE_EVENT_TYPE_MOUSE_DOWN) != 0) { if ((EventType & APPLE_EVENT_TYPE_MOUSE_DOWN) != 0) {
if ((EventType & APPLE_EVENT_TYPE_LEFT_BUTTON) != 0) { if ((EventType & APPLE_EVENT_TYPE_LEFT_BUTTON) != 0) {
Context->CurState.PrimaryDown = TRUE; ASSERT (Context->LockedBy == PointerUnlocked);
} else if ((EventType & APPLE_EVENT_TYPE_RIGHT_BUTTON) != 0) { InternalQueuePointerEvent (
Context->CurState.SecondaryDown = TRUE; Context,
GuiPointerPrimaryDown,
Context->CurPos.Pos.X,
Context->CurPos.Pos.Y
);
Context->LockedBy = PointerLockedSimple;
} }
} else if ((EventType & APPLE_EVENT_TYPE_MOUSE_UP) != 0) { } else if ((EventType & APPLE_EVENT_TYPE_MOUSE_UP) != 0) {
if ((EventType & APPLE_EVENT_TYPE_LEFT_BUTTON) != 0) { if ((EventType & APPLE_EVENT_TYPE_LEFT_BUTTON) != 0) {
Context->CurState.PrimaryDown = FALSE; ASSERT (Context->LockedBy == PointerLockedSimple);
} else if ((EventType & APPLE_EVENT_TYPE_RIGHT_BUTTON) != 0) { InternalQueuePointerEvent (
Context->CurState.SecondaryDown = FALSE; Context,
GuiPointerPrimaryUp,
Context->CurPos.Pos.X,
Context->CurPos.Pos.Y
);
Context->LockedBy = PointerUnlocked;
}
} else if ((EventType & APPLE_EVENT_TYPE_MOUSE_DOUBLE_CLICK) != 0) {
if ((EventType & APPLE_EVENT_TYPE_LEFT_BUTTON) != 0) {
InternalQueuePointerEvent (
Context,
GuiPointerPrimaryDoubleClick,
Context->CurPos.Pos.X,
Context->CurPos.Pos.Y
);
} }
}
if ((Context->CurState.PrimaryDown | Context->CurState.SecondaryDown) == 0) {
Context->LockedBy = PointerUnlocked;
} else {
Context->LockedBy = PointerLockedSimple;
} }
} }
...@@ -131,6 +206,7 @@ InternalUpdateContextAbsolute ( ...@@ -131,6 +206,7 @@ InternalUpdateContextAbsolute (
EFI_ABSOLUTE_POINTER_STATE PointerState; EFI_ABSOLUTE_POINTER_STATE PointerState;
UINT64 NewX; UINT64 NewX;
UINT64 NewY; UINT64 NewY;
GUI_PTR_POSITION NewPos;
ASSERT (Context != NULL); ASSERT (Context != NULL);
...@@ -144,12 +220,6 @@ InternalUpdateContextAbsolute ( ...@@ -144,12 +220,6 @@ InternalUpdateContextAbsolute (
return; return;
} }
if ((Context->CurState.PrimaryDown | Context->CurState.SecondaryDown) == 0) {
ASSERT (Context->LockedBy == PointerUnlocked);
} else {
ASSERT (Context->LockedBy == PointerLockedAbsolute);
}
Status = Context->AbsPointer->GetState (Context->AbsPointer, &PointerState); Status = Context->AbsPointer->GetState (Context->AbsPointer, &PointerState);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return; return;
...@@ -157,27 +227,69 @@ InternalUpdateContextAbsolute ( ...@@ -157,27 +227,69 @@ InternalUpdateContextAbsolute (
NewX = PointerState.CurrentX - Context->AbsPointer->Mode->AbsoluteMinX; NewX = PointerState.CurrentX - Context->AbsPointer->Mode->AbsoluteMinX;
NewX *= Context->MaxX + 1; NewX *= Context->MaxX + 1;
Context->CurState.X = (UINT32) DivU64x32 ( NewPos.Pos.X = (UINT32) DivU64x32 (
NewX, NewX,
(UINT32) (Context->AbsPointer->Mode->AbsoluteMaxX - Context->AbsPointer->Mode->AbsoluteMinX) (UINT32) (Context->AbsPointer->Mode->AbsoluteMaxX - Context->AbsPointer->Mode->AbsoluteMinX)
); );
Context->RawX = (INT32) Context->CurState.X;
NewY = PointerState.CurrentY - Context->AbsPointer->Mode->AbsoluteMinY; NewY = PointerState.CurrentY - Context->AbsPointer->Mode->AbsoluteMinY;
NewY *= Context->MaxY + 1; NewY *= Context->MaxY + 1;
Context->CurState.Y = (UINT32) DivU64x32 ( NewPos.Pos.Y = (UINT32) DivU64x32 (
NewY, NewY,
(UINT32) (Context->AbsPointer->Mode->AbsoluteMaxY - Context->AbsPointer->Mode->AbsoluteMinY) (UINT32) (Context->AbsPointer->Mode->AbsoluteMaxY - Context->AbsPointer->Mode->AbsoluteMinY)
); );
Context->RawY = (INT32) Context->CurState.Y; //
// This is not perfectly concurrent, but good enough.
//
Context->CurPos.Uint64 = NewPos.Uint64;
Context->RawPos.Uint64 = NewPos.Uint64;
//
// Cancel double click when the finger is moved too far away.
//
if (Context->AbsDoubleClick) {
if (ABS ((INT64) NewPos.Pos.X - Context->AbsLastDownPos.Pos.X) > ABS_DOUBLE_CLICK_RADIUS * Context->UiScale
|| ABS ((INT64) NewPos.Pos.Y - Context->AbsLastDownPos.Pos.Y) > ABS_DOUBLE_CLICK_RADIUS * Context->UiScale) {
Context->AbsDoubleClick = FALSE;
}
}
Context->CurState.PrimaryDown = (PointerState.ActiveButtons & EFI_ABSP_TouchActive) != 0; if (Context->AbsPrimaryDown != ((PointerState.ActiveButtons & EFI_ABSP_TouchActive) != 0)) {
Context->CurState.SecondaryDown = (PointerState.ActiveButtons & EFI_ABS_AltActive) != 0; Context->AbsPrimaryDown = ((PointerState.ActiveButtons & EFI_ABSP_TouchActive) != 0);
if (Context->AbsPrimaryDown) {
ASSERT (Context->LockedBy == PointerUnlocked);
InternalQueuePointerEvent (
Context,
GuiPointerPrimaryDown,
NewPos.Pos.X,
NewPos.Pos.Y
);
Context->LockedBy = PointerLockedAbsolute;
if ((Context->CurState.PrimaryDown | Context->CurState.SecondaryDown) == 0) { Context->AbsLastDownPos.Pos.X = NewPos.Pos.X;
Context->LockedBy = PointerUnlocked; Context->AbsLastDownPos.Pos.Y = NewPos.Pos.Y;
} else { Context->AbsDoubleClick = TRUE;
Context->LockedBy = PointerLockedAbsolute; } else {
ASSERT (Context->LockedBy == PointerLockedAbsolute);
InternalQueuePointerEvent (
Context,
GuiPointerPrimaryUp,
NewPos.Pos.X,
NewPos.Pos.Y
);
Context->LockedBy = PointerUnlocked;
ASSERT (Context->UiScale > 0);
if (Context->AbsDoubleClick) {
InternalQueuePointerEvent (
Context,
GuiPointerPrimaryDoubleClick,
NewPos.Pos.X,
NewPos.Pos.Y
);
Context->AbsDoubleClick = FALSE;
}
}
} }
} }
...@@ -198,32 +310,34 @@ GuiPointerReset ( ...@@ -198,32 +310,34 @@ GuiPointerReset (
} }
VOID VOID
GuiPointerGetState ( GuiPointerGetPosition (
IN OUT GUI_POINTER_CONTEXT *Context, IN OUT GUI_POINTER_CONTEXT *Context,
OUT GUI_POINTER_STATE *State OUT GUI_PTR_POSITION *Position
) )
{ {
EFI_TPL OldTpl; EFI_TPL OldTpl;
ASSERT (Context != NULL); ASSERT (Context != NULL);
ASSERT (State != NULL); ASSERT (Position != NULL);
// //
// Prevent simple pointer updates during state retrieval. // Prevent simple pointer updates during state retrieval.
// On 64+-bit systems, the operation is atomic.
// //
OldTpl = gBS->RaiseTPL (TPL_NOTIFY); if (sizeof (UINTN) < sizeof (UINT64)) {
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
}
// //
// The simple pointer updates are done in InternalAppleEventNotification(). // The simple pointer updates are done in InternalAppleEventNotification().
// //
InternalUpdateContextAbsolute (Context); InternalUpdateContextAbsolute (Context);
// //
// Return the current pointer state. // Return the current pointer position.
// //
State->X = Context->CurState.X; Position->Uint64 = Context->CurPos.Uint64;
State->Y = Context->CurState.Y;
State->PrimaryDown = Context->CurState.PrimaryDown;
State->SecondaryDown = Context->CurState.SecondaryDown;
gBS->RestoreTPL (OldTpl); if (sizeof (UINTN) < sizeof (UINT64)) {
gBS->RestoreTPL (OldTpl);
}
} }
GUI_POINTER_CONTEXT * GUI_POINTER_CONTEXT *
...@@ -231,7 +345,8 @@ GuiPointerConstruct ( ...@@ -231,7 +345,8 @@ GuiPointerConstruct (
IN UINT32 DefaultX, IN UINT32 DefaultX,
IN UINT32 DefaultY, IN UINT32 DefaultY,
IN UINT32 Width, IN UINT32 Width,
IN UINT32 Height IN UINT32 Height,
IN UINT8 UiScale
) )
{ {
// TODO: alloc on the fly? // TODO: alloc on the fly?
...@@ -246,12 +361,13 @@ GuiPointerConstruct ( ...@@ -246,12 +361,13 @@ GuiPointerConstruct (
ASSERT (Width <= MAX_INT32); ASSERT (Width <= MAX_INT32);
ASSERT (Height <= MAX_INT32); ASSERT (Height <= MAX_INT32);
Context.MaxX = Width - 1; Context.MaxX = Width - 1;
Context.MaxY = Height - 1; Context.MaxY = Height - 1;
Context.CurState.X = DefaultX; Context.CurPos.Pos.X = DefaultX;
Context.CurState.Y = DefaultY; Context.CurPos.Pos.Y = DefaultY;
Context.RawX = (INT32) DefaultX; Context.RawPos.Pos.X = DefaultX;
Context.RawY = (INT32) DefaultY; Context.RawPos.Pos.Y = DefaultY;
Context.UiScale = UiScale;
Status = OcHandleProtocolFallback ( Status = OcHandleProtocolFallback (
gST->ConsoleInHandle, gST->ConsoleInHandle,
......
...@@ -38,13 +38,13 @@ STATIC EFI_CONSOLE_CONTROL_SCREEN_MODE mPreviousMode; ...@@ -38,13 +38,13 @@ STATIC EFI_CONSOLE_CONTROL_SCREEN_MODE mPreviousMode;
STATIC STATIC
EFI_STATUS EFI_STATUS
OcShowMenuByOcEnter ( OcShowMenuByOcEnter (
IN OC_BOOT_CONTEXT *BootContext IN BOOT_PICKER_GUI_CONTEXT *GuiContext
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
Status = GuiLibConstruct ( Status = GuiLibConstruct (
BootContext->PickerContext, GuiContext,
mGuiContext.CursorDefaultX, mGuiContext.CursorDefaultX,
mGuiContext.CursorDefaultY mGuiContext.CursorDefaultY
); );
...@@ -94,7 +94,7 @@ OcShowMenuByOc ( ...@@ -94,7 +94,7 @@ OcShowMenuByOc (
mGuiContext.PickerContext = BootContext->PickerContext; mGuiContext.PickerContext = BootContext->PickerContext;
mGuiContext.AudioPlaybackTimeout = -1; mGuiContext.AudioPlaybackTimeout = -1;
Status = OcShowMenuByOcEnter (BootContext); Status = OcShowMenuByOcEnter (&mGuiContext);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }
......
...@@ -209,11 +209,9 @@ GuiObjDelegatePtrEvent ( ...@@ -209,11 +209,9 @@ GuiObjDelegatePtrEvent (
IN OUT GUI_OBJ *This, IN OUT GUI_OBJ *This,
IN OUT GUI_DRAWING_CONTEXT *DrawContext, IN OUT GUI_DRAWING_CONTEXT *DrawContext,
IN BOOT_PICKER_GUI_CONTEXT *Context, IN BOOT_PICKER_GUI_CONTEXT *Context,
IN GUI_PTR_EVENT Event,
IN INT64 BaseX, IN INT64 BaseX,
IN INT64 BaseY, IN INT64 BaseY,
IN INT64 OffsetX, IN CONST GUI_PTR_EVENT *Event
IN INT64 OffsetY
) )
{ {
UINTN Index; UINTN Index;
...@@ -221,18 +219,20 @@ GuiObjDelegatePtrEvent ( ...@@ -221,18 +219,20 @@ GuiObjDelegatePtrEvent (
GUI_OBJ_CHILD *Child; GUI_OBJ_CHILD *Child;
ASSERT (This != NULL); ASSERT (This != NULL);
ASSERT (This->Width > OffsetX); ASSERT (Event->Pos.Pos.X >= BaseX);
ASSERT (This->Height > OffsetY); ASSERT (Event->Pos.Pos.Y >= BaseY);
ASSERT (This->Width > Event->Pos.Pos.X - BaseX);
ASSERT (This->Height > Event->Pos.Pos.Y - BaseY);
ASSERT (DrawContext != NULL); ASSERT (DrawContext != NULL);
// //
// Pointer event propagation is backwards due to forwards draw order. // Pointer event propagation is backwards due to forwards draw order.
// //
for (Index = This->NumChildren; Index > 0; --Index) { for (Index = This->NumChildren; Index > 0; --Index) {
Child = This->Children[Index - 1]; Child = This->Children[Index - 1];
if (OffsetX < Child->Obj.OffsetX if (Event->Pos.Pos.X - BaseX < Child->Obj.OffsetX
|| OffsetX >= Child->Obj.OffsetX + Child->Obj.Width || Event->Pos.Pos.X - BaseX >= Child->Obj.OffsetX + Child->Obj.Width
|| OffsetY < Child->Obj.OffsetY || Event->Pos.Pos.Y - BaseY < Child->Obj.OffsetY
|| OffsetY >= Child->Obj.OffsetY + Child->Obj.Height) { || Event->Pos.Pos.Y - BaseY >= Child->Obj.OffsetY + Child->Obj.Height) {
continue; continue;
} }
...@@ -241,11 +241,9 @@ GuiObjDelegatePtrEvent ( ...@@ -241,11 +241,9 @@ GuiObjDelegatePtrEvent (
&Child->Obj, &Child->Obj,
DrawContext, DrawContext,
Context, Context,
Event, BaseX + Child->Obj.OffsetX,
BaseX + Child->Obj.OffsetX, BaseY + Child->Obj.OffsetY,
BaseY + Child->Obj.OffsetY, Event
OffsetX - Child->Obj.OffsetX,
OffsetY - Child->Obj.OffsetY
); );
if (Obj != NULL) { if (Obj != NULL) {
return Obj; return Obj;
...@@ -592,17 +590,17 @@ GuiOverlayPointer ( ...@@ -592,17 +590,17 @@ GuiOverlayPointer (
IN OUT GUI_DRAWING_CONTEXT *DrawContext IN OUT GUI_DRAWING_CONTEXT *DrawContext
) )
{ {
CONST GUI_IMAGE *CursorImage; CONST GUI_IMAGE *CursorImage;
UINT32 MaxWidth; UINT32 MaxWidth;
UINT32 MaxHeight; UINT32 MaxHeight;
GUI_POINTER_STATE PointerState; GUI_PTR_POSITION PointerPos;
INT64 BaseX; INT64 BaseX;
INT64 BaseY; INT64 BaseY;
UINT32 ImageOffsetX; UINT32 ImageOffsetX;
UINT32 ImageOffsetY; UINT32 ImageOffsetY;
UINT32 DrawBaseX; UINT32 DrawBaseX;
UINT32 DrawBaseY; UINT32 DrawBaseY;
ASSERT (DrawContext != NULL); ASSERT (DrawContext != NULL);
...@@ -612,10 +610,10 @@ GuiOverlayPointer ( ...@@ -612,10 +610,10 @@ GuiOverlayPointer (
// //
// Poll the current cursor position late to reduce input lag. // Poll the current cursor position late to reduce input lag.
// //
GuiPointerGetState (mPointerContext, &PointerState); GuiPointerGetPosition (mPointerContext, &PointerPos);
ASSERT (PointerState.X < DrawContext->Screen->Width); ASSERT (PointerPos.Pos.X < DrawContext->Screen->Width);
ASSERT (PointerState.Y < DrawContext->Screen->Height); ASSERT (PointerPos.Pos.Y < DrawContext->Screen->Height);
// //
// Unconditionally draw the cursor to increase frametime consistency and // Unconditionally draw the cursor to increase frametime consistency and
...@@ -629,7 +627,7 @@ GuiOverlayPointer ( ...@@ -629,7 +627,7 @@ GuiOverlayPointer (
// Draw the new cursor at the new position. // Draw the new cursor at the new position.
// //
BaseX = (INT64) PointerState.X - BOOT_CURSOR_OFFSET * DrawContext->Scale; BaseX = (INT64) PointerPos.Pos.X - BOOT_CURSOR_OFFSET * DrawContext->Scale;
if (BaseX < 0) { if (BaseX < 0) {
ImageOffsetX = (UINT32) -BaseX; ImageOffsetX = (UINT32) -BaseX;
DrawBaseX = 0; DrawBaseX = 0;
...@@ -640,7 +638,7 @@ GuiOverlayPointer ( ...@@ -640,7 +638,7 @@ GuiOverlayPointer (
MaxWidth = MIN (CursorImage->Width, (UINT32) (DrawContext->Screen->Width - BaseX)); MaxWidth = MIN (CursorImage->Width, (UINT32) (DrawContext->Screen->Width - BaseX));
BaseY = (INT64) PointerState.Y - BOOT_CURSOR_OFFSET * DrawContext->Scale; BaseY = (INT64) PointerPos.Pos.Y - BOOT_CURSOR_OFFSET * DrawContext->Scale;
if (BaseY < 0) { if (BaseY < 0) {
ImageOffsetY = (UINT32) -BaseY; ImageOffsetY = (UINT32) -BaseY;
DrawBaseY = 0; DrawBaseY = 0;
...@@ -792,9 +790,9 @@ GuiRedrawAndFlushScreen ( ...@@ -792,9 +790,9 @@ GuiRedrawAndFlushScreen (
EFI_STATUS EFI_STATUS
GuiLibConstruct ( GuiLibConstruct (
IN OC_PICKER_CONTEXT *PickerContext, IN BOOT_PICKER_GUI_CONTEXT *GuiContext,
IN UINT32 CursorDefaultX, IN UINT32 CursorDefaultX,
IN UINT32 CursorDefaultY IN UINT32 CursorDefaultY
) )
{ {
CONST EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *OutputInfo; CONST EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *OutputInfo;
...@@ -811,19 +809,20 @@ GuiLibConstruct ( ...@@ -811,19 +809,20 @@ GuiLibConstruct (
CursorDefaultX = MIN (CursorDefaultX, OutputInfo->HorizontalResolution - 1); CursorDefaultX = MIN (CursorDefaultX, OutputInfo->HorizontalResolution - 1);
CursorDefaultY = MIN (CursorDefaultY, OutputInfo->VerticalResolution - 1); CursorDefaultY = MIN (CursorDefaultY, OutputInfo->VerticalResolution - 1);
if ((PickerContext->PickerAttributes & OC_ATTR_USE_POINTER_CONTROL) != 0) { if ((GuiContext->PickerContext->PickerAttributes & OC_ATTR_USE_POINTER_CONTROL) != 0) {
mPointerContext = GuiPointerConstruct ( mPointerContext = GuiPointerConstruct (
CursorDefaultX, CursorDefaultX,
CursorDefaultY, CursorDefaultY,
OutputInfo->HorizontalResolution, OutputInfo->HorizontalResolution,
OutputInfo->VerticalResolution OutputInfo->VerticalResolution,
GuiContext->Scale
); );
if (mPointerContext == NULL) { if (mPointerContext == NULL) {
DEBUG ((DEBUG_WARN, "OCUI: Failed to initialise pointer\n")); DEBUG ((DEBUG_WARN, "OCUI: Failed to initialise pointer\n"));
} }
} }
mKeyContext = GuiKeyConstruct (PickerContext); mKeyContext = GuiKeyConstruct (GuiContext->PickerContext);
if (mKeyContext == NULL) { if (mKeyContext == NULL) {
DEBUG ((DEBUG_WARN, "OCUI: Failed to initialise key input\n")); DEBUG ((DEBUG_WARN, "OCUI: Failed to initialise key input\n"));
} }
...@@ -911,12 +910,12 @@ GuiViewDeinitialize ( ...@@ -911,12 +910,12 @@ GuiViewDeinitialize (
OUT BOOT_PICKER_GUI_CONTEXT *GuiContext OUT BOOT_PICKER_GUI_CONTEXT *GuiContext
) )
{ {
GUI_POINTER_STATE PointerState; GUI_PTR_POSITION PointerPos;
if (mPointerContext != NULL) { if (mPointerContext != NULL) {
GuiPointerGetState (mPointerContext, &PointerState); GuiPointerGetPosition (mPointerContext, &PointerPos);
GuiContext->CursorDefaultX = PointerState.X; GuiContext->CursorDefaultX = PointerPos.Pos.X;
GuiContext->CursorDefaultY = PointerState.Y; GuiContext->CursorDefaultY = PointerPos.Pos.Y;
} }
ZeroMem (DrawContext, sizeof (*DrawContext)); ZeroMem (DrawContext, sizeof (*DrawContext));
...@@ -974,31 +973,35 @@ GuiDrawLoop ( ...@@ -974,31 +973,35 @@ GuiDrawLoop (
IN UINT32 TimeOutSeconds IN UINT32 TimeOutSeconds
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
BOOLEAN Result; BOOLEAN Result;
INTN InputKey; INTN InputKey;
BOOLEAN Modifier; BOOLEAN Modifier;
GUI_POINTER_STATE PointerState; GUI_PTR_EVENT PointerEvent;
GUI_OBJ *HoldObject; GUI_OBJ *TempObject;
INT64 HoldObjBaseX; GUI_OBJ *HoldObject;
INT64 HoldObjBaseY; INT64 HoldObjBaseX;
CONST LIST_ENTRY *AnimEntry; INT64 HoldObjBaseY;
CONST GUI_ANIMATION *Animation; CONST LIST_ENTRY *AnimEntry;
UINT64 LoopStartTsc; CONST GUI_ANIMATION *Animation;
UINT64 LastTsc; UINT64 LoopStartTsc;
UINT64 NewLastTsc; UINT64 LastTsc;
BOOLEAN ObjectHeld; UINT64 NewLastTsc;
BOOLEAN ObjectHeld;
CONST GUI_IMAGE *CursorImage;
UINT64 FrameTime; CONST GUI_IMAGE *CursorImage;
UINT64 FrameTime;
ASSERT (DrawContext != NULL); ASSERT (DrawContext != NULL);
mNumValidDrawReqs = 0; mNumValidDrawReqs = 0;
FrameTime = 0; FrameTime = 0;
HoldObject = NULL; HoldObject = NULL;
ObjectHeld = FALSE;
DEBUG_CODE_BEGIN ();
ObjectHeld = FALSE;
DEBUG_CODE_END ();
// //
// Clear previous inputs. // Clear previous inputs.
...@@ -1038,29 +1041,65 @@ GuiDrawLoop ( ...@@ -1038,29 +1041,65 @@ GuiDrawLoop (
// //
// Process pointer events. // Process pointer events.
// //
GuiPointerGetState (mPointerContext, &PointerState); Result = GuiPointerGetEvent (mPointerContext, &PointerEvent);
if (Result) {
if (PointerState.PrimaryDown) { if (PointerEvent.Type == GuiPointerPrimaryUp) {
if (!ObjectHeld && HoldObject == NULL) { //
HoldObject = GuiObjDelegatePtrEvent ( // 'Button down' must have caught and set an interaction object.
DrawContext->Screen, // It may be NULL for objects that solely delegate pointer events.
DrawContext, //
DrawContext->GuiContext, ASSERT (ObjectHeld);
GuiPointerPrimaryDown,
0, if (HoldObject != NULL) {
0, GuiGetBaseCoords (
PointerState.X, HoldObject,
PointerState.Y DrawContext,
); &HoldObjBaseX,
&HoldObjBaseY
} );
HoldObject->PtrEvent (
ObjectHeld = TRUE; HoldObject,
} else { DrawContext,
ObjectHeld = FALSE; DrawContext->GuiContext,
} HoldObjBaseX,
HoldObjBaseY,
&PointerEvent
);
HoldObject = NULL;
}
if (HoldObject != NULL) { DEBUG_CODE_BEGIN ();
ObjectHeld = FALSE;
DEBUG_CODE_END ();
} else {
//
// HoldObject == NULL cannot be tested here as double-click may arrive
// before button up.
//
ASSERT (PointerEvent.Type != GuiPointerPrimaryUp);
TempObject = GuiObjDelegatePtrEvent (
DrawContext->Screen,
DrawContext,
DrawContext->GuiContext,
0,
0,
&PointerEvent
);
if (PointerEvent.Type == GuiPointerPrimaryDown) {
DEBUG_CODE_BEGIN ();
ObjectHeld = TRUE;
DEBUG_CODE_END ();
HoldObject = TempObject;
}
}
} else if (HoldObject != NULL) {
//
// If there are no events to process, update the cursor position with
// the interaction object for visual effects.
//
PointerEvent.Type = GuiPointerPrimaryDown;
GuiPointerGetPosition (mPointerContext, &PointerEvent.Pos);
GuiGetBaseCoords ( GuiGetBaseCoords (
HoldObject, HoldObject,
DrawContext, DrawContext,
...@@ -1068,18 +1107,13 @@ GuiDrawLoop ( ...@@ -1068,18 +1107,13 @@ GuiDrawLoop (
&HoldObjBaseY &HoldObjBaseY
); );
HoldObject->PtrEvent ( HoldObject->PtrEvent (
HoldObject, HoldObject,
DrawContext, DrawContext,
DrawContext->GuiContext, DrawContext->GuiContext,
!PointerState.PrimaryDown ? GuiPointerPrimaryUp : GuiPointerPrimaryHold, HoldObjBaseX,
HoldObjBaseX, HoldObjBaseY,
HoldObjBaseY, &PointerEvent
(INT64)PointerState.X - HoldObjBaseX, );
(INT64)PointerState.Y - HoldObjBaseY
);
if (!PointerState.PrimaryDown) {
HoldObject = NULL;
}
} }
} }
......
...@@ -20,11 +20,23 @@ typedef struct _BOOT_PICKER_GUI_CONTEXT BOOT_PICKER_GUI_CONTEXT; ...@@ -20,11 +20,23 @@ typedef struct _BOOT_PICKER_GUI_CONTEXT BOOT_PICKER_GUI_CONTEXT;
enum { enum {
GuiPointerPrimaryDown, GuiPointerPrimaryDown,
GuiPointerPrimaryHold, GuiPointerPrimaryUp,
GuiPointerPrimaryUp GuiPointerPrimaryDoubleClick
}; };
typedef UINT8 GUI_PTR_EVENT; typedef union {
struct {
UINT32 X;
UINT32 Y;
} Pos;
UINT64 Uint64;
} GUI_PTR_POSITION;
typedef struct {
UINT8 Type;
GUI_PTR_POSITION Pos;
} GUI_PTR_EVENT;
typedef typedef
VOID VOID
...@@ -46,11 +58,9 @@ GUI_OBJ * ...@@ -46,11 +58,9 @@ GUI_OBJ *
IN OUT GUI_OBJ *This, IN OUT GUI_OBJ *This,
IN OUT GUI_DRAWING_CONTEXT *DrawContext, IN OUT GUI_DRAWING_CONTEXT *DrawContext,
IN BOOT_PICKER_GUI_CONTEXT *Context, IN BOOT_PICKER_GUI_CONTEXT *Context,
IN GUI_PTR_EVENT Event,
IN INT64 BaseX, IN INT64 BaseX,
IN INT64 BaseY, IN INT64 BaseY,
IN INT64 OffsetX, IN CONST GUI_PTR_EVENT *Event
IN INT64 OffsetY
); );
typedef typedef
...@@ -181,11 +191,9 @@ GuiObjDelegatePtrEvent ( ...@@ -181,11 +191,9 @@ GuiObjDelegatePtrEvent (
IN OUT GUI_OBJ *This, IN OUT GUI_OBJ *This,
IN OUT GUI_DRAWING_CONTEXT *DrawContext, IN OUT GUI_DRAWING_CONTEXT *DrawContext,
IN BOOT_PICKER_GUI_CONTEXT *Context, IN BOOT_PICKER_GUI_CONTEXT *Context,
IN GUI_PTR_EVENT Event,
IN INT64 BaseX, IN INT64 BaseX,
IN INT64 BaseY, IN INT64 BaseY,
IN INT64 OffsetX, IN CONST GUI_PTR_EVENT *Event
IN INT64 OffsetY
); );
BOOLEAN BOOLEAN
...@@ -271,9 +279,9 @@ GuiClearScreen ( ...@@ -271,9 +279,9 @@ GuiClearScreen (
EFI_STATUS EFI_STATUS
GuiLibConstruct ( GuiLibConstruct (
IN OC_PICKER_CONTEXT *PickerContext, IN BOOT_PICKER_GUI_CONTEXT *GuiContext,
IN UINT32 CursorDefaultX, IN UINT32 CursorDefaultX,
IN UINT32 CursorDefaultY IN UINT32 CursorDefaultY
); );
VOID VOID
......
...@@ -473,24 +473,22 @@ InternalBootPickerEntryPtrEvent ( ...@@ -473,24 +473,22 @@ InternalBootPickerEntryPtrEvent (
IN OUT GUI_OBJ *This, IN OUT GUI_OBJ *This,
IN OUT GUI_DRAWING_CONTEXT *DrawContext, IN OUT GUI_DRAWING_CONTEXT *DrawContext,
IN BOOT_PICKER_GUI_CONTEXT *Context, IN BOOT_PICKER_GUI_CONTEXT *Context,
IN GUI_PTR_EVENT Event,
IN INT64 BaseX, IN INT64 BaseX,
IN INT64 BaseY, IN INT64 BaseY,
IN INT64 OffsetX, IN CONST GUI_PTR_EVENT *Event
IN INT64 OffsetY
) )
{ {
STATIC BOOLEAN SameIter = FALSE;
GUI_VOLUME_ENTRY *Entry; GUI_VOLUME_ENTRY *Entry;
BOOLEAN IsHit; BOOLEAN IsHit;
UINT32 OffsetX;
UINT32 OffsetY;
ASSERT (Event == GuiPointerPrimaryDown OffsetX = (UINT32) (Event->Pos.Pos.X - BaseX);
|| Event == GuiPointerPrimaryHold OffsetY = (UINT32) (Event->Pos.Pos.Y - BaseY);
|| Event == GuiPointerPrimaryUp);
if (Event == GuiPointerPrimaryHold) { ASSERT (Event->Type == GuiPointerPrimaryDown
return This; || Event->Type == GuiPointerPrimaryUp
} || Event->Type == GuiPointerPrimaryDoubleClick);
if (OffsetX < BOOT_ENTRY_ICON_SPACE * DrawContext->Scale if (OffsetX < BOOT_ENTRY_ICON_SPACE * DrawContext->Scale
|| OffsetY < BOOT_ENTRY_ICON_SPACE * DrawContext->Scale) { || OffsetY < BOOT_ENTRY_ICON_SPACE * DrawContext->Scale) {
...@@ -508,7 +506,7 @@ InternalBootPickerEntryPtrEvent ( ...@@ -508,7 +506,7 @@ InternalBootPickerEntryPtrEvent (
return This; return This;
} }
if (Event == GuiPointerPrimaryDown) { if (Event->Type == GuiPointerPrimaryDown) {
if (mBootPicker.SelectedIndex != Entry->Index) { if (mBootPicker.SelectedIndex != Entry->Index) {
ASSERT (Entry->Hdr.Parent == &mBootPicker.Hdr.Obj); ASSERT (Entry->Hdr.Parent == &mBootPicker.Hdr.Obj);
InternalBootPickerChangeEntry ( InternalBootPickerChangeEntry (
...@@ -518,21 +516,16 @@ InternalBootPickerEntryPtrEvent ( ...@@ -518,21 +516,16 @@ InternalBootPickerEntryPtrEvent (
BaseY - This->OffsetY, BaseY - This->OffsetY,
Entry->Index Entry->Index
); );
SameIter = TRUE;
} }
} else { } else if (Event->Type == GuiPointerPrimaryDoubleClick) {
// //
// This must be ensured because the UI directs Move/Up events to the object // This must be ensured because the UI directs Move/Up events to the object
// Down had been sent to. // Down had been sent to.
// //
ASSERT (mBootPicker.SelectedIndex == Entry->Index); ASSERT (mBootPicker.SelectedIndex == Entry->Index);
if (SameIter) { Context->ReadyToBoot = TRUE;
SameIter = FALSE; ASSERT (Context->BootEntry == Entry->Context);
} else {
Context->ReadyToBoot = TRUE;
ASSERT (Context->BootEntry == Entry->Context);
}
} }
// //
// There should be no children. // There should be no children.
...@@ -724,17 +717,17 @@ InternalBootPickerSelectorPtrEvent ( ...@@ -724,17 +717,17 @@ InternalBootPickerSelectorPtrEvent (
IN OUT GUI_OBJ *This, IN OUT GUI_OBJ *This,
IN OUT GUI_DRAWING_CONTEXT *DrawContext, IN OUT GUI_DRAWING_CONTEXT *DrawContext,
IN BOOT_PICKER_GUI_CONTEXT *Context, IN BOOT_PICKER_GUI_CONTEXT *Context,
IN GUI_PTR_EVENT Event,
IN INT64 BaseX, IN INT64 BaseX,
IN INT64 BaseY, IN INT64 BaseY,
IN INT64 OffsetX, IN CONST GUI_PTR_EVENT *Event
IN INT64 OffsetY
) )
{ {
GUI_OBJ_CLICKABLE *Clickable; GUI_OBJ_CLICKABLE *Clickable;
CONST GUI_IMAGE *ButtonImage; CONST GUI_IMAGE *ButtonImage;
BOOLEAN IsHit; BOOLEAN IsHit;
UINT32 OffsetX;
UINT32 OffsetY;
ASSERT (This != NULL); ASSERT (This != NULL);
ASSERT (DrawContext != NULL); ASSERT (DrawContext != NULL);
...@@ -744,12 +737,15 @@ InternalBootPickerSelectorPtrEvent ( ...@@ -744,12 +737,15 @@ InternalBootPickerSelectorPtrEvent (
// //
ASSERT (This->NumChildren == 0); ASSERT (This->NumChildren == 0);
OffsetX = (UINT32) (Event->Pos.Pos.X - BaseX);
OffsetY = (UINT32) (Event->Pos.Pos.Y - BaseY);
Clickable = BASE_CR (This, GUI_OBJ_CLICKABLE, Hdr.Obj); Clickable = BASE_CR (This, GUI_OBJ_CLICKABLE, Hdr.Obj);
ButtonImage = &Context->Icons[ICON_SELECTOR][ICON_TYPE_BASE]; ButtonImage = &Context->Icons[ICON_SELECTOR][ICON_TYPE_BASE];
ASSERT (Event == GuiPointerPrimaryDown ASSERT (Event->Type == GuiPointerPrimaryDown
|| Event == GuiPointerPrimaryHold || Event->Type == GuiPointerPrimaryUp
|| Event == GuiPointerPrimaryUp); || Event->Type == GuiPointerPrimaryDoubleClick);
if (OffsetX >= (BOOT_SELECTOR_BACKGROUND_DIMENSION * DrawContext->Scale - ButtonImage->Width) / 2 if (OffsetX >= (BOOT_SELECTOR_BACKGROUND_DIMENSION * DrawContext->Scale - ButtonImage->Width) / 2
&& OffsetY >= (BOOT_SELECTOR_BACKGROUND_DIMENSION + BOOT_SELECTOR_BUTTON_SPACE) * DrawContext->Scale) { && OffsetY >= (BOOT_SELECTOR_BACKGROUND_DIMENSION + BOOT_SELECTOR_BUTTON_SPACE) * DrawContext->Scale) {
IsHit = GuiClickableIsHit ( IsHit = GuiClickableIsHit (
...@@ -758,7 +754,7 @@ InternalBootPickerSelectorPtrEvent ( ...@@ -758,7 +754,7 @@ InternalBootPickerSelectorPtrEvent (
OffsetY - (BOOT_SELECTOR_BACKGROUND_DIMENSION + BOOT_SELECTOR_BUTTON_SPACE) * DrawContext->Scale OffsetY - (BOOT_SELECTOR_BACKGROUND_DIMENSION + BOOT_SELECTOR_BUTTON_SPACE) * DrawContext->Scale
); );
if (IsHit) { if (IsHit) {
if (Event == GuiPointerPrimaryUp) { if (Event->Type == GuiPointerPrimaryUp) {
ASSERT (Context->BootEntry == InternalGetVolumeEntry (mBootPicker.SelectedIndex)->Context); ASSERT (Context->BootEntry == InternalGetVolumeEntry (mBootPicker.SelectedIndex)->Context);
Context->ReadyToBoot = TRUE; Context->ReadyToBoot = TRUE;
} else { } else {
...@@ -787,11 +783,9 @@ InternalBootPickerLeftScrollPtrEvent ( ...@@ -787,11 +783,9 @@ InternalBootPickerLeftScrollPtrEvent (
IN OUT GUI_OBJ *This, IN OUT GUI_OBJ *This,
IN OUT GUI_DRAWING_CONTEXT *DrawContext, IN OUT GUI_DRAWING_CONTEXT *DrawContext,
IN BOOT_PICKER_GUI_CONTEXT *Context, IN BOOT_PICKER_GUI_CONTEXT *Context,
IN GUI_PTR_EVENT Event,
IN INT64 BaseX, IN INT64 BaseX,
IN INT64 BaseY, IN INT64 BaseY,
IN INT64 OffsetX, IN CONST GUI_PTR_EVENT *Event
IN INT64 OffsetY
) )
{ {
GUI_OBJ_CLICKABLE *Clickable; GUI_OBJ_CLICKABLE *Clickable;
...@@ -812,19 +806,19 @@ InternalBootPickerLeftScrollPtrEvent ( ...@@ -812,19 +806,19 @@ InternalBootPickerLeftScrollPtrEvent (
Clickable = BASE_CR (This, GUI_OBJ_CLICKABLE, Hdr.Obj); Clickable = BASE_CR (This, GUI_OBJ_CLICKABLE, Hdr.Obj);
ButtonImage = &Context->Icons[ICON_LEFT][ICON_TYPE_BASE]; ButtonImage = &Context->Icons[ICON_LEFT][ICON_TYPE_BASE];
ASSERT (Event == GuiPointerPrimaryDown ASSERT (Event->Type == GuiPointerPrimaryDown
|| Event == GuiPointerPrimaryHold || Event->Type == GuiPointerPrimaryUp
|| Event == GuiPointerPrimaryUp); || Event->Type == GuiPointerPrimaryDoubleClick);
ASSERT (ButtonImage->Width == This->Width); ASSERT (ButtonImage->Width == This->Width);
ASSERT (ButtonImage->Height == This->Height); ASSERT (ButtonImage->Height == This->Height);
IsHit = GuiClickableIsHit ( IsHit = GuiClickableIsHit (
ButtonImage, ButtonImage,
OffsetX, Event->Pos.Pos.X - BaseX,
OffsetY Event->Pos.Pos.Y - BaseY
); );
if (IsHit) { if (IsHit) {
if (Event != GuiPointerPrimaryUp) { if (Event->Type == GuiPointerPrimaryDown) {
ButtonImage = &Context->Icons[ICON_LEFT][ICON_TYPE_HELD]; ButtonImage = &Context->Icons[ICON_LEFT][ICON_TYPE_HELD];
} else if (mBootPicker.Hdr.Obj.OffsetX < 0) { } else if (mBootPicker.Hdr.Obj.OffsetX < 0) {
// //
...@@ -891,11 +885,9 @@ InternalBootPickerRightScrollPtrEvent ( ...@@ -891,11 +885,9 @@ InternalBootPickerRightScrollPtrEvent (
IN OUT GUI_OBJ *This, IN OUT GUI_OBJ *This,
IN OUT GUI_DRAWING_CONTEXT *DrawContext, IN OUT GUI_DRAWING_CONTEXT *DrawContext,
IN BOOT_PICKER_GUI_CONTEXT *Context, IN BOOT_PICKER_GUI_CONTEXT *Context,
IN GUI_PTR_EVENT Event,
IN INT64 BaseX, IN INT64 BaseX,
IN INT64 BaseY, IN INT64 BaseY,
IN INT64 OffsetX, IN CONST GUI_PTR_EVENT *Event
IN INT64 OffsetY
) )
{ {
GUI_OBJ_CLICKABLE *Clickable; GUI_OBJ_CLICKABLE *Clickable;
...@@ -916,17 +908,17 @@ InternalBootPickerRightScrollPtrEvent ( ...@@ -916,17 +908,17 @@ InternalBootPickerRightScrollPtrEvent (
Clickable = BASE_CR (This, GUI_OBJ_CLICKABLE, Hdr.Obj); Clickable = BASE_CR (This, GUI_OBJ_CLICKABLE, Hdr.Obj);
ButtonImage = &Context->Icons[ICON_RIGHT][ICON_TYPE_BASE]; ButtonImage = &Context->Icons[ICON_RIGHT][ICON_TYPE_BASE];
ASSERT (Event == GuiPointerPrimaryDown ASSERT (Event->Type == GuiPointerPrimaryDown
|| Event == GuiPointerPrimaryHold || Event->Type == GuiPointerPrimaryUp
|| Event == GuiPointerPrimaryUp); || Event->Type == GuiPointerPrimaryDoubleClick);
IsHit = GuiClickableIsHit ( IsHit = GuiClickableIsHit (
ButtonImage, ButtonImage,
OffsetX, Event->Pos.Pos.X - BaseX,
OffsetY Event->Pos.Pos.Y - BaseY
); );
if (IsHit) { if (IsHit) {
if (Event != GuiPointerPrimaryUp) { if (Event->Type == GuiPointerPrimaryDown) {
ButtonImage = &Context->Icons[ICON_RIGHT][ICON_TYPE_HELD]; ButtonImage = &Context->Icons[ICON_RIGHT][ICON_TYPE_HELD];
} else if (mBootPicker.Hdr.Obj.OffsetX + mBootPicker.Hdr.Obj.Width > mBootPickerContainer.Obj.Width) { } else if (mBootPicker.Hdr.Obj.OffsetX + mBootPicker.Hdr.Obj.Width > mBootPickerContainer.Obj.Width) {
// //
...@@ -1038,11 +1030,9 @@ InternalBootPickerShutDownPtrEvent ( ...@@ -1038,11 +1030,9 @@ InternalBootPickerShutDownPtrEvent (
IN OUT GUI_OBJ *This, IN OUT GUI_OBJ *This,
IN OUT GUI_DRAWING_CONTEXT *DrawContext, IN OUT GUI_DRAWING_CONTEXT *DrawContext,
IN BOOT_PICKER_GUI_CONTEXT *Context, IN BOOT_PICKER_GUI_CONTEXT *Context,
IN GUI_PTR_EVENT Event,
IN INT64 BaseX, IN INT64 BaseX,
IN INT64 BaseY, IN INT64 BaseY,
IN INT64 OffsetX, IN CONST GUI_PTR_EVENT *Event
IN INT64 OffsetY
) )
{ {
GUI_OBJ_CLICKABLE *Clickable; GUI_OBJ_CLICKABLE *Clickable;
...@@ -1052,17 +1042,17 @@ InternalBootPickerShutDownPtrEvent ( ...@@ -1052,17 +1042,17 @@ InternalBootPickerShutDownPtrEvent (
Clickable = BASE_CR (This, GUI_OBJ_CLICKABLE, Hdr.Obj); Clickable = BASE_CR (This, GUI_OBJ_CLICKABLE, Hdr.Obj);
ButtonImage = &Context->Icons[ICON_SHUT_DOWN][ICON_TYPE_BASE]; ButtonImage = &Context->Icons[ICON_SHUT_DOWN][ICON_TYPE_BASE];
ASSERT (Event == GuiPointerPrimaryDown ASSERT (Event->Type == GuiPointerPrimaryDown
|| Event == GuiPointerPrimaryHold || Event->Type == GuiPointerPrimaryUp
|| Event == GuiPointerPrimaryUp); || Event->Type == GuiPointerPrimaryDoubleClick);
IsHit = GuiClickableIsHit ( IsHit = GuiClickableIsHit (
ButtonImage, ButtonImage,
OffsetX, Event->Pos.Pos.X - BaseX,
OffsetY Event->Pos.Pos.Y - BaseY
); );
if (IsHit) { if (IsHit) {
if (Event != GuiPointerPrimaryUp) { if (Event->Type == GuiPointerPrimaryDown) {
ButtonImage = &Context->Icons[ICON_SHUT_DOWN][ICON_TYPE_HELD]; ButtonImage = &Context->Icons[ICON_SHUT_DOWN][ICON_TYPE_HELD];
} else { } else {
gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL); gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);
...@@ -1090,11 +1080,9 @@ InternalBootPickerRestartPtrEvent ( ...@@ -1090,11 +1080,9 @@ InternalBootPickerRestartPtrEvent (
IN OUT GUI_OBJ *This, IN OUT GUI_OBJ *This,
IN OUT GUI_DRAWING_CONTEXT *DrawContext, IN OUT GUI_DRAWING_CONTEXT *DrawContext,
IN BOOT_PICKER_GUI_CONTEXT *Context, IN BOOT_PICKER_GUI_CONTEXT *Context,
IN GUI_PTR_EVENT Event,
IN INT64 BaseX, IN INT64 BaseX,
IN INT64 BaseY, IN INT64 BaseY,
IN INT64 OffsetX, IN CONST GUI_PTR_EVENT *Event
IN INT64 OffsetY
) )
{ {
GUI_OBJ_CLICKABLE *Clickable; GUI_OBJ_CLICKABLE *Clickable;
...@@ -1104,17 +1092,17 @@ InternalBootPickerRestartPtrEvent ( ...@@ -1104,17 +1092,17 @@ InternalBootPickerRestartPtrEvent (
Clickable = BASE_CR (This, GUI_OBJ_CLICKABLE, Hdr.Obj); Clickable = BASE_CR (This, GUI_OBJ_CLICKABLE, Hdr.Obj);
ButtonImage = &Context->Icons[ICON_RESTART][ICON_TYPE_BASE]; ButtonImage = &Context->Icons[ICON_RESTART][ICON_TYPE_BASE];
ASSERT (Event == GuiPointerPrimaryDown ASSERT (Event->Type == GuiPointerPrimaryDown
|| Event == GuiPointerPrimaryHold || Event->Type == GuiPointerPrimaryUp
|| Event == GuiPointerPrimaryUp); || Event->Type == GuiPointerPrimaryDoubleClick);
IsHit = GuiClickableIsHit ( IsHit = GuiClickableIsHit (
ButtonImage, ButtonImage,
OffsetX, Event->Pos.Pos.X - BaseX,
OffsetY Event->Pos.Pos.Y - BaseY
); );
if (IsHit) { if (IsHit) {
if (Event != GuiPointerPrimaryUp) { if (Event->Type == GuiPointerPrimaryDown) {
ButtonImage = &Context->Icons[ICON_RESTART][ICON_TYPE_HELD]; ButtonImage = &Context->Icons[ICON_RESTART][ICON_TYPE_HELD];
} else { } else {
gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL); gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册