mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-14 13:19:20 +02:00
* Keyhandling rework. Virtual keycodes are looked up by the keycode of the key pressed.
+ Added dynamic modifier mask lookup. git-svn-id: trunk@10422 -
This commit is contained in:
parent
114f79c897
commit
6c79de53ed
@ -1431,11 +1431,6 @@ begin
|
|||||||
Result := false;
|
Result := false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TWidgetSet.VkKeyScan(AChar: Char): Short;
|
|
||||||
begin
|
|
||||||
Result := -1; // $FFFF
|
|
||||||
end;
|
|
||||||
|
|
||||||
Function TWidgetSet.WindowFromPoint(Point : TPoint) : HWND;
|
Function TWidgetSet.WindowFromPoint(Point : TPoint) : HWND;
|
||||||
begin
|
begin
|
||||||
Result := 0;
|
Result := 0;
|
||||||
|
@ -842,11 +842,6 @@ begin
|
|||||||
Result := WidgetSet.UpdateWindow(Handle);
|
Result := WidgetSet.UpdateWindow(Handle);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function VkKeyScan(AChar: Char): Short;
|
|
||||||
begin
|
|
||||||
Result := WidgetSet.VkKeyScan(AChar);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function WindowFromPoint(Point : TPoint) : HWND;
|
function WindowFromPoint(Point : TPoint) : HWND;
|
||||||
begin
|
begin
|
||||||
Result := WidgetSet.WindowFromPoint(Point);
|
Result := WidgetSet.WindowFromPoint(Point);
|
||||||
|
@ -237,8 +237,6 @@ function UpdateWindow(Handle: HWND): Boolean; {$IFDEF IF_BASE_MEMBER}virtual;{$E
|
|||||||
|
|
||||||
//function UnionRect --> independent
|
//function UnionRect --> independent
|
||||||
|
|
||||||
function VkKeyScan(AChar: Char): Short; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}
|
|
||||||
|
|
||||||
Function WindowFromPoint(Point : TPoint) : HWND; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}
|
Function WindowFromPoint(Point : TPoint) : HWND; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}
|
||||||
//##apiwiz##eps## // Do not remove
|
//##apiwiz##eps## // Do not remove
|
||||||
{******************************************************************************
|
{******************************************************************************
|
||||||
|
@ -978,11 +978,6 @@ begin
|
|||||||
Result:=inherited TextOut(DC, X, Y, Str, Count);
|
Result:=inherited TextOut(DC, X, Y, Str, Count);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCarbonWidgetSet.VkKeyScan(AChar: Char): Short;
|
|
||||||
begin
|
|
||||||
Result:=inherited VkKeyScan(AChar);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TCarbonWidgetSet.WindowFromPoint(Point: TPoint): HWND;
|
function TCarbonWidgetSet.WindowFromPoint(Point: TPoint): HWND;
|
||||||
begin
|
begin
|
||||||
Result:=inherited WindowFromPoint(Point);
|
Result:=inherited WindowFromPoint(Point);
|
||||||
|
@ -202,8 +202,6 @@ function StretchMaskBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; X
|
|||||||
|
|
||||||
function TextOut(DC: HDC; X,Y : Integer; Str : Pchar; Count: Integer) : Boolean; override;
|
function TextOut(DC: HDC; X,Y : Integer; Str : Pchar; Count: Integer) : Boolean; override;
|
||||||
|
|
||||||
function VkKeyScan(AChar: Char): Short; override;
|
|
||||||
|
|
||||||
function WindowFromPoint(Point : TPoint) : HWND; override;
|
function WindowFromPoint(Point : TPoint) : HWND; override;
|
||||||
|
|
||||||
//##apiwiz##eps## // Do not remove, no wizard declaration after this line
|
//##apiwiz##eps## // Do not remove, no wizard declaration after this line
|
||||||
|
@ -584,16 +584,24 @@ begin
|
|||||||
EventTrace('map', data);
|
EventTrace('map', data);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function GTKKeyUpDown(Widget: PGtkWidget; Event: PGdkEventKey;
|
function GTKKeyPress(Widget: PGtkWidget; Event: PGdkEventKey; Data: gPointer) : GBoolean; cdecl;
|
||||||
Data: gPointer) : GBoolean; cdecl;
|
|
||||||
begin
|
begin
|
||||||
Result:=HandleGtkKeyUpDown(Widget,Event,Data,true);
|
Result := HandleGtkKeyUpDown(Widget,Event,Data,true, True);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function GTKKeyUpDownAfter(Widget: PGtkWidget; Event: pgdkeventkey;
|
function GTKKeyPressAfter(Widget: PGtkWidget; Event: pgdkeventkey; Data: gPointer): GBoolean; cdecl;
|
||||||
Data: gPointer): GBoolean; cdecl;
|
|
||||||
begin
|
begin
|
||||||
Result:=HandleGtkKeyUpDown(Widget,Event,Data,false);
|
Result := HandleGtkKeyUpDown(Widget,Event,Data,false, True);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GTKKeyRelease(Widget: PGtkWidget; Event: PGdkEventKey; Data: gPointer) : GBoolean; cdecl;
|
||||||
|
begin
|
||||||
|
Result := HandleGtkKeyUpDown(Widget,Event,Data,true, False);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GTKKeyReleaseAfter(Widget: PGtkWidget; Event: pgdkeventkey; Data: gPointer): GBoolean; cdecl;
|
||||||
|
begin
|
||||||
|
Result := HandleGtkKeyUpDown(Widget,Event,Data,false, False);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function GTKFocusCB( widget: PGtkWidget; event:PGdkEventFocus;
|
function GTKFocusCB( widget: PGtkWidget; event:PGdkEventFocus;
|
||||||
@ -914,7 +922,7 @@ begin
|
|||||||
Point(TruncToInt(Event^.X),TruncToInt(Event^.Y)),
|
Point(TruncToInt(Event^.X),TruncToInt(Event^.Y)),
|
||||||
PGtkWidget(AWinControl.Handle));
|
PGtkWidget(AWinControl.Handle));
|
||||||
|
|
||||||
ShiftState := GTKEventState2ShiftState(Event^.State);
|
ShiftState := GTKEventStateToShiftState(Event^.State);
|
||||||
with Msg do
|
with Msg do
|
||||||
begin
|
begin
|
||||||
Msg := LM_MouseMove;
|
Msg := LM_MouseMove;
|
||||||
@ -1252,7 +1260,7 @@ begin
|
|||||||
MousePositionValid:=false;
|
MousePositionValid:=false;
|
||||||
|
|
||||||
EventXY:=Point(TruncToInt(Event^.X),TruncToInt(Event^.Y));
|
EventXY:=Point(TruncToInt(Event^.X),TruncToInt(Event^.Y));
|
||||||
ShiftState := GTKEventState2ShiftState(Event^.State);
|
ShiftState := GTKEventStateToShiftState(Event^.State);
|
||||||
MappedXY:=TranslateGdkPointToClientArea(Event^.Window,EventXY,
|
MappedXY:=TranslateGdkPointToClientArea(Event^.Window,EventXY,
|
||||||
PGtkWidget(AWinControl.Handle));
|
PGtkWidget(AWinControl.Handle));
|
||||||
//DebugLn('DeliverMouseDownMessage ',DbgSName(AWinControl),' Mapped=',dbgs(MappedXY.X),',',dbgs(MappedXY.Y),' Event=',dbgs(EventXY.X),',',dbgs(EventXY.Y));
|
//DebugLn('DeliverMouseDownMessage ',DbgSName(AWinControl),' Mapped=',dbgs(MappedXY.X),',',dbgs(MappedXY.Y),' Event=',dbgs(EventXY.X),',',dbgs(EventXY.Y));
|
||||||
@ -1526,7 +1534,7 @@ begin
|
|||||||
MessI.XPos := MappedXY.X;
|
MessI.XPos := MappedXY.X;
|
||||||
MessI.YPos := MappedXY.Y;
|
MessI.YPos := MappedXY.Y;
|
||||||
|
|
||||||
ShiftState := gtkeventstate2shiftstate(Event^.State);
|
ShiftState := gtkeventstateToshiftstate(Event^.State);
|
||||||
MessI.Keys := 0;
|
MessI.Keys := 0;
|
||||||
if ssShift in ShiftState then MessI.Keys := MessI.Keys or MK_SHIFT;
|
if ssShift in ShiftState then MessI.Keys := MessI.Keys or MK_SHIFT;
|
||||||
if ssCtrl in ShiftState then MessI.Keys := MessI.Keys or MK_CONTROL;
|
if ssCtrl in ShiftState then MessI.Keys := MessI.Keys or MK_CONTROL;
|
||||||
@ -1679,7 +1687,7 @@ begin
|
|||||||
and (ofAllowMultiSelect in TOpenDialog(theDialog).Options)
|
and (ofAllowMultiSelect in TOpenDialog(theDialog).Options)
|
||||||
and (FileSelWidget^.file_list=widget) then begin
|
and (FileSelWidget^.file_list=widget) then begin
|
||||||
// multi selection
|
// multi selection
|
||||||
ShiftState := GTKEventState2ShiftState(BEvent^.State);
|
ShiftState := GTKEventStateToShiftState(BEvent^.State);
|
||||||
if ssShift in ShiftState then begin
|
if ssShift in ShiftState then begin
|
||||||
if LastFileSelectRow <> -1 then begin
|
if LastFileSelectRow <> -1 then begin
|
||||||
startRow := LastFileSelectRow;
|
startRow := LastFileSelectRow;
|
||||||
@ -2876,11 +2884,11 @@ var
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
const
|
const
|
||||||
STATE_MAP: array[0..3] of Byte = (
|
STATE_MAP: array[0..3] of TShiftStateEnum = (
|
||||||
GDK_SHIFT_MASK, // shift
|
ssShift,
|
||||||
GDK_CONTROL_MASK, // control
|
ssCtrl,
|
||||||
GDK_MOD1_MASK, // alt
|
ssAlt,
|
||||||
GDK_MOD4_MASK // win
|
ssSuper
|
||||||
);
|
);
|
||||||
VK_MAP: array[0..3] of array[0..2] of Byte = (
|
VK_MAP: array[0..3] of array[0..2] of Byte = (
|
||||||
// (Main key, alt key 1, alt key 2) to check
|
// (Main key, alt key 1, alt key 2) to check
|
||||||
@ -2890,9 +2898,13 @@ const
|
|||||||
(VK_LWIN, VK_RWIN, 0)
|
(VK_LWIN, VK_RWIN, 0)
|
||||||
);
|
);
|
||||||
var
|
var
|
||||||
VKey: PVKeyRecord;
|
KeyCode: Word;
|
||||||
Pressed: Boolean;
|
KCInfo: TKeyCodeInfo;
|
||||||
|
VKey: Byte;
|
||||||
|
Pressed, InState: Boolean;
|
||||||
|
|
||||||
n: Integer;
|
n: Integer;
|
||||||
|
ShiftState: TShiftState;
|
||||||
begin
|
begin
|
||||||
Result := 0;
|
Result := 0;
|
||||||
|
|
||||||
@ -2905,54 +2917,80 @@ begin
|
|||||||
// not interested
|
// not interested
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
VKey := MKeySymToVKMap.GetDataPtr(Event^.keyval);
|
{$ifdef gtk1}
|
||||||
if VKey = nil
|
KeyCode := XKeysymToKeycode(gdk_display, Event^.keyval);
|
||||||
|
{$else}
|
||||||
|
KeyCode := Event^.hardware_keycode;
|
||||||
|
{$endif}
|
||||||
|
//DebugLn('GTKKeySnooper: KeyCode=%u -> %s', [KeyCode, {$IFDEF GTK2} Event^._String {$ELSE} Event^.theString {$ENDIF}]);
|
||||||
|
|
||||||
|
if KeyCode > High(MKeyCodeInfo)
|
||||||
then begin
|
then begin
|
||||||
if Pressed
|
if Pressed
|
||||||
then DebugLn(Format('[WARNING] Key pressed without VKey: K=0x%x S="%s"', [
|
then DebugLn('[WARNING] Key pressed with keycode (%u) larger than expected: K=0x%x S="%s"', [
|
||||||
|
KeyCode,
|
||||||
Event^.KeyVal,
|
Event^.KeyVal,
|
||||||
{$IFDEF GTK2} Event^._String {$ELSE} Event^.theString {$ENDIF}
|
{$IFDEF GTK2} Event^._String {$ELSE} Event^.theString {$ENDIF}
|
||||||
]));
|
]);
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
KCInfo := MKeyCodeInfo[KeyCode];
|
||||||
|
if KCInfo.VKey1 = 0
|
||||||
|
then begin
|
||||||
|
if Pressed
|
||||||
|
then DebugLn('[WARNING] Key pressed without VKey: K=0x%x S="%s"', [
|
||||||
|
Event^.KeyVal,
|
||||||
|
{$IFDEF GTK2} Event^._String {$ELSE} Event^.theString {$ENDIF}
|
||||||
|
]);
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if FuncData=nil then exit;
|
if FuncData = nil then exit;
|
||||||
KeyStateList := TObject(FuncData) as TFPList;
|
KeyStateList := TObject(FuncData) as TFPList;
|
||||||
|
|
||||||
|
ShiftState := GTKEventStateToShiftState(Event^.State);
|
||||||
|
|
||||||
|
if (KCInfo.Flags and KCINFO_FLAG_SHIFT_XOR_NUM <> 0)
|
||||||
|
and ((ssShift in ShiftState) xor (ssNum in ShiftState))
|
||||||
|
then VKey := KCInfo.VKey2
|
||||||
|
else VKey := KCInfo.VKey1;
|
||||||
|
|
||||||
UpdateList(Vkey^.VKey, Pressed);
|
UpdateList(VKey, Pressed);
|
||||||
if IsToggleKey(Vkey^.VKey)
|
if (KCInfo.Flags and KCINFO_FLAG_TOGGLE <> 0)
|
||||||
then UpdateToggleList(Vkey^.VKey);
|
then UpdateToggleList(VKey);
|
||||||
|
|
||||||
// Add special left and right codes
|
// Add special left and right codes
|
||||||
case Event^.KeyVal of
|
case Event^.KeyVal of
|
||||||
GDK_Key_Shift_L: UpdateList(VK_LSHIFT, Pressed);
|
GDK_Key_Shift_L: UpdateList(VK_LSHIFT, Pressed);
|
||||||
GDK_Key_Shift_R: UpdateList(VK_RSHIFT, Pressed);
|
GDK_Key_Shift_R: UpdateList(VK_RSHIFT, Pressed);
|
||||||
GDK_Key_Control_L: UpdateList(VK_LCONTROL, Pressed);
|
GDK_Key_Control_L: UpdateList(VK_LCONTROL, Pressed);
|
||||||
GDK_Key_Control_R: UpdateList(VK_RCONTROL, Pressed);
|
GDK_Key_Control_R: UpdateList(VK_RCONTROL, Pressed);
|
||||||
GDK_Key_Alt_L: UpdateList(VK_LMENU, Pressed);
|
GDK_Key_Alt_L: UpdateList(VK_LMENU, Pressed);
|
||||||
GDK_Key_Alt_R: UpdateList(VK_RMENU, Pressed);
|
GDK_Key_Alt_R: UpdateList(VK_RMENU, Pressed);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Recheck the list against the modifiers
|
// Recheck the list against the modifiers
|
||||||
for n := 0 to High(STATE_MAP) do
|
for n := 0 to High(STATE_MAP) do
|
||||||
begin
|
begin
|
||||||
// Skip our current key, since the state is updated after the event
|
// Skip our current key, since the state is updated after the event
|
||||||
if VKey^.Vkey = VK_MAP[n][0] then Continue;
|
if VKey = VK_MAP[n][0] then Continue;
|
||||||
if VKey^.Vkey = VK_MAP[n][1] then Continue;
|
if VKey = VK_MAP[n][1] then Continue;
|
||||||
if VKey^.Vkey = VK_MAP[n][2] then Continue;
|
if VKey = VK_MAP[n][2] then Continue;
|
||||||
|
|
||||||
UpdateList(VK_MAP[n][0], (STATE_MAP[n] and Event^.State) <> 0);
|
InState := STATE_MAP[n] in ShiftState;
|
||||||
UpdateList(VK_MAP[n][1], (STATE_MAP[n] and Event^.State) <> 0);
|
UpdateList(VK_MAP[n][0], InState);
|
||||||
UpdateList(VK_MAP[n][2], (STATE_MAP[n] and Event^.State) <> 0);
|
UpdateList(VK_MAP[n][1], InState);
|
||||||
|
UpdateList(VK_MAP[n][2], InState);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// if the VKey has multiple VK_codes then SHIFT distinguishes between them
|
// if the VKey has multiple VK_codes then SHIFT distinguishes between them
|
||||||
// In that case SHIFT is not pressed
|
// In that case SHIFT is not pressed
|
||||||
// On the next event the shift flag will be restored based on modifiers
|
// On the next event the shift flag will be restored based on modifiers
|
||||||
if Pressed and ((VKey^.Flags and VKEY_FLAG_MULTI_VK) <> 0)
|
if Pressed and ((KCInfo.Flags and KCINFO_FLAG_SHIFT_XOR_NUM) <> 0)
|
||||||
then begin
|
then begin
|
||||||
UpdateList(VK_SHIFT, False);
|
UpdateList(VK_SHIFT, False);
|
||||||
UpdateList(VK_LSHIFT, False);
|
UpdateList(VK_LSHIFT, False);
|
||||||
UpdateList(VK_RSHIFT, False);
|
UpdateList(VK_RSHIFT, False);
|
||||||
end;
|
end;
|
||||||
|
@ -3614,13 +3614,13 @@ procedure TGtkWidgetSet.SetCallback(const AMsg: LongInt;
|
|||||||
begin
|
begin
|
||||||
//debugln('ConnectKeyPressReleaseEvents A ALCLObject=',DbgSName(ALCLObject));
|
//debugln('ConnectKeyPressReleaseEvents A ALCLObject=',DbgSName(ALCLObject));
|
||||||
ConnectSenderSignal(AnObject,
|
ConnectSenderSignal(AnObject,
|
||||||
'key-press-event', @GTKKeyUpDown, GDK_KEY_PRESS_MASK);
|
'key-press-event', @GTKKeyPress, GDK_KEY_PRESS_MASK);
|
||||||
ConnectSenderSignalAfter(AnObject,
|
ConnectSenderSignalAfter(AnObject,
|
||||||
'key-press-event', @GTKKeyUpDownAfter, GDK_KEY_PRESS_MASK);
|
'key-press-event', @GTKKeyPressAfter, GDK_KEY_PRESS_MASK);
|
||||||
ConnectSenderSignal(AnObject,
|
ConnectSenderSignal(AnObject,
|
||||||
'key-release-event', @GTKKeyUpDown, GDK_KEY_RELEASE_MASK);
|
'key-release-event', @GTKKeyRelease, GDK_KEY_RELEASE_MASK);
|
||||||
ConnectSenderSignalAfter(AnObject,
|
ConnectSenderSignalAfter(AnObject,
|
||||||
'key-release-event', @GTKKeyUpDownAfter, GDK_KEY_RELEASE_MASK);
|
'key-release-event', @GTKKeyReleaseAfter, GDK_KEY_RELEASE_MASK);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function GetAdjustment(const gObject: PGTKObject; vertical: boolean):PGtkObject;
|
function GetAdjustment(const gObject: PGTKObject; vertical: boolean):PGtkObject;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -29,6 +29,9 @@ interface
|
|||||||
|
|
||||||
{off $DEFINE VerboseAccelerator}
|
{off $DEFINE VerboseAccelerator}
|
||||||
|
|
||||||
|
{off $define VerboseModifiermap}
|
||||||
|
|
||||||
|
|
||||||
{$IFDEF Unix}
|
{$IFDEF Unix}
|
||||||
{$DEFINE HasX}
|
{$DEFINE HasX}
|
||||||
{$IFDEF Gtk1}
|
{$IFDEF Gtk1}
|
||||||
@ -178,10 +181,16 @@ function gtkfrmactivateAfter( widget: PGtkWidget; Event: PgdkEventFocus;
|
|||||||
function gtkfrmdeactivateAfter( widget: PGtkWidget; Event: PgdkEventFocus;
|
function gtkfrmdeactivateAfter( widget: PGtkWidget; Event: PgdkEventFocus;
|
||||||
data: gPointer): GBoolean; cdecl;
|
data: gPointer): GBoolean; cdecl;
|
||||||
function GTKMap(Widget: PGTKWidget; Data: gPointer): GBoolean; cdecl;
|
function GTKMap(Widget: PGTKWidget; Data: gPointer): GBoolean; cdecl;
|
||||||
function GTKKeyUpDown(Widget: PGtkWidget; Event: pgdkeventkey;
|
|
||||||
|
function GTKKeyPress(Widget: PGtkWidget; Event: pgdkeventkey;
|
||||||
Data: gPointer): GBoolean; cdecl;
|
Data: gPointer): GBoolean; cdecl;
|
||||||
function GTKKeyUpDownAfter(Widget: PGtkWidget; Event: pgdkeventkey;
|
function GTKKeyPressAfter(Widget: PGtkWidget; Event: pgdkeventkey;
|
||||||
Data: gPointer): GBoolean; cdecl;
|
Data: gPointer): GBoolean; cdecl;
|
||||||
|
function GTKKeyRelease(Widget: PGtkWidget; Event: pgdkeventkey;
|
||||||
|
Data: gPointer): GBoolean; cdecl;
|
||||||
|
function GTKKeyReleaseAfter(Widget: PGtkWidget; Event: pgdkeventkey;
|
||||||
|
Data: gPointer): GBoolean; cdecl;
|
||||||
|
|
||||||
function GTKFocusCB(widget: PGtkWidget; event:PGdkEventFocus;
|
function GTKFocusCB(widget: PGtkWidget; event:PGdkEventFocus;
|
||||||
data: gPointer): GBoolean; cdecl;
|
data: gPointer): GBoolean; cdecl;
|
||||||
function GTKFocusCBAfter(widget: PGtkWidget; event:PGdkEventFocus;
|
function GTKFocusCBAfter(widget: PGtkWidget; event:PGdkEventFocus;
|
||||||
@ -502,18 +511,15 @@ function GetRGBAsKey(p: pointer): pointer;
|
|||||||
type
|
type
|
||||||
TVKeyUTF8Char = array[0..7] of Char;
|
TVKeyUTF8Char = array[0..7] of Char;
|
||||||
TVKeyInfo = record
|
TVKeyInfo = record
|
||||||
KeyCode: Byte;
|
KeyCode: array[Boolean] of Byte; // false is primary keycode, true the keycode of the other key when 2 keys exist (like CTRL or extended key)
|
||||||
KeySym: array[0..7] of Integer;
|
KeySym: array[0..7] of Integer;
|
||||||
KeyChar: array[0..3] of TVKeyUTF8Char;
|
KeyChar: array[0..3] of TVKeyUTF8Char;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure InitKeyboardTables;
|
procedure InitKeyboardTables;
|
||||||
procedure DoneKeyboardTables;
|
procedure DoneKeyboardTables;
|
||||||
function CharToVKandFlags(const AUTF8Char: TVKeyUTF8Char): Word;
|
|
||||||
function GetVKeyInfo(const AVKey: Byte): TVKeyInfo;
|
function GetVKeyInfo(const AVKey: Byte): TVKeyInfo;
|
||||||
function IsToggleKey(const AVKey: Byte): Boolean;
|
function GTKEventStateToShiftState(KeyState: Word): TShiftState;
|
||||||
function GTKEventState2ShiftState(KeyState: Word): TShiftState;
|
|
||||||
//function KeyToListCode_(KeyCode, VirtKeyCode: Word; Extended: boolean): integer;
|
|
||||||
procedure gdk_event_key_get_string(Event: PGDKEventKey; var theString: Pointer);
|
procedure gdk_event_key_get_string(Event: PGDKEventKey; var theString: Pointer);
|
||||||
procedure gdk_event_key_set_string(Event: PGDKEventKey; const NewString: PChar);
|
procedure gdk_event_key_set_string(Event: PGDKEventKey; const NewString: PChar);
|
||||||
function gdk_event_get_type(Event: Pointer): TGdkEventType;
|
function gdk_event_get_type(Event: Pointer): TGdkEventType;
|
||||||
@ -521,8 +527,8 @@ procedure RememberKeyEventWasHandledByLCL(Event: PGdkEventKey;
|
|||||||
BeforeEvent: boolean);
|
BeforeEvent: boolean);
|
||||||
function KeyEventWasHandledByLCL(Event: PGdkEventKey;
|
function KeyEventWasHandledByLCL(Event: PGdkEventKey;
|
||||||
BeforeEvent: boolean): boolean;
|
BeforeEvent: boolean): boolean;
|
||||||
function HandleGTKKeyUpDown(Widget: PGtkWidget; Event: PGdkEventKey;
|
function HandleGTKKeyUpDown(AWidget: PGtkWidget; AEvent: PGdkEventKey;
|
||||||
Data: gPointer; BeforeEvent: boolean) : GBoolean;
|
AData: gPointer; ABeforeEvent, AHandleDown: Boolean) : GBoolean;
|
||||||
|
|
||||||
// ----
|
// ----
|
||||||
|
|
||||||
@ -941,28 +947,43 @@ uses
|
|||||||
dynlibs;
|
dynlibs;
|
||||||
|
|
||||||
const
|
const
|
||||||
VKEY_FLAG_SHIFT = $01;
|
KCINFO_FLAG_SHIFT = $01;
|
||||||
VKEY_FLAG_CTRL = $02;
|
KCINFO_FLAG_CTRL = $02;
|
||||||
VKEY_FLAG_ALT = $04;
|
KCINFO_FLAG_ALTGR = $04;
|
||||||
VKEY_FLAG_KEY_MASK = $07;
|
KCINFO_FLAG_KEY_MASK = $07;
|
||||||
VKEY_FLAG_EXT = $10; // extended key
|
KCINFO_FLAG_EXT = $10; // extended key
|
||||||
VKEY_FLAG_MULTI_VK = $20; // key has more than one VK
|
KCINFO_FLAG_TOGGLE = $20; // toggle key
|
||||||
|
|
||||||
|
KCINFO_FLAG_SHIFT_XOR_NUM = $40; // second vkey should be used when numlock <>shift
|
||||||
|
KCINFO_FLAG_MULTI_MASK = $C0; // key has more than one VK
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
PVKeyRecord = ^TVKeyRecord;
|
PKeyCodeInfo = ^TKeyCodeInfo;
|
||||||
TVKeyRecord = record
|
TKeyCodeInfo = record
|
||||||
VKey: Byte;
|
VKey1: Byte;
|
||||||
|
VKey2: Byte; // second code to be used depending on the type of MULTI_VK flag
|
||||||
Flags: Byte; // indicates if Alt | Ctrl | Shift is needed
|
Flags: Byte; // indicates if Alt | Ctrl | Shift is needed
|
||||||
// extended state
|
// extended state
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
MKeyCodeToVK: array[Byte] of Byte;
|
MKeyCodeInfo: array[Byte] of TKeyCodeInfo;
|
||||||
MVKeyInfo: array[Byte] of TVKeyInfo;
|
MVKeyInfo: array[Byte] of TVKeyInfo;
|
||||||
MKeySymToVKMap: TMap; // keysym ->TVKeyRecord
|
|
||||||
MSymCharToVKMap: TMap; //char->TVKeyRecord
|
// Modifier keys can be set by a modmap and don't have to be the same on all systems
|
||||||
|
// Some defaults are set here incase we didn't find them
|
||||||
|
type
|
||||||
|
TModifier = record
|
||||||
|
Mask: Cardinal; // if UseValue is set, the modifier is set when the masked state matches the value
|
||||||
|
Value: Cardinal; // otherwise any nonzero value will match
|
||||||
|
UseValue: Boolean;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
MModifiers: array[TShiftStateEnum] of TModifier;
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
// TLCLHandledKeyEvent is used to remember, if an gdk key event was already
|
// TLCLHandledKeyEvent is used to remember, if an gdk key event was already
|
||||||
// handled.
|
// handled.
|
||||||
@ -1041,12 +1062,27 @@ procedure InitGTKProc;
|
|||||||
var
|
var
|
||||||
lgs: TLazGtkStyle;
|
lgs: TLazGtkStyle;
|
||||||
begin
|
begin
|
||||||
MKeySymToVKMap := TMap.Create(itu4, SizeOf(TVKeyRecord));
|
//MKeySymToVKMap := TMap.Create(itu4, SizeOf(TVKeyRecord));
|
||||||
// UTF8 is max 4 bytes, acombined makes it 8
|
// UTF8 is max 4 bytes, acombined makes it 8
|
||||||
MSymCharToVKMap := TMap.Create(itu8, SizeOf(TVKeyRecord));
|
//MSymCharToVKMap := TMap.Create(itu8, SizeOf(TVKeyRecord));
|
||||||
|
|
||||||
|
// fill initial modifier list
|
||||||
|
FillByte(MModifiers, SizeOf(MModifiers), 0);
|
||||||
|
// keyboard
|
||||||
|
MModifiers[ssShift].Mask := GDK_SHIFT_MASK;
|
||||||
|
MModifiers[ssCaps].Mask := GDK_LOCK_MASK;
|
||||||
|
MModifiers[ssCtrl].Mask := GDK_CONTROL_MASK;
|
||||||
|
MModifiers[ssAlt].Mask := GDK_MOD1_MASK;
|
||||||
|
MModifiers[ssNum].Mask := GDK_MOD3_MASK; //todo: check this I've 2 here,but 3 was the original code
|
||||||
|
MModifiers[ssSuper].Mask := GDK_MOD4_MASK;
|
||||||
|
MModifiers[ssScroll].Mask := GDK_MOD5_MASK; //todo: check this I've ssAltGr here, but ssScroll was the original code
|
||||||
|
MModifiers[ssAltGr].Mask := GDK_RELEASE_MASK;
|
||||||
|
// mouse
|
||||||
|
MModifiers[ssLeft].Mask := GDK_BUTTON1_MASK;
|
||||||
|
MModifiers[ssMiddle].Mask := GDK_BUTTON2_MASK;
|
||||||
|
MModifiers[ssRight].Mask := GDK_BUTTON3_MASK;
|
||||||
|
|
||||||
|
FillChar(MKeyCodeInfo, SizeOf(MKeyCodeInfo), $FF);
|
||||||
FillChar(MKeyCodeToVK, SizeOf(MKeyCodeToVK), $FF);
|
|
||||||
FillChar(MVKeyInfo, SizeOf(MVKeyInfo), 0);
|
FillChar(MVKeyInfo, SizeOf(MVKeyInfo), 0);
|
||||||
|
|
||||||
|
|
||||||
@ -1062,8 +1098,8 @@ end;
|
|||||||
procedure DoneGTKProc;
|
procedure DoneGTKProc;
|
||||||
begin
|
begin
|
||||||
DoneKeyboardTables;
|
DoneKeyboardTables;
|
||||||
FreeAndNil(MKeySymToVKMap);
|
// FreeAndNil(MKeySymToVKMap);
|
||||||
FreeAndNil(MSymCharToVKMap);
|
// FreeAndNil(MSymCharToVKMap);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{$IFDEF GTK1}
|
{$IFDEF GTK1}
|
||||||
|
@ -9665,21 +9665,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
{$EndIf}
|
{$EndIf}
|
||||||
{------------------------------------------------------------------------------
|
|
||||||
Function: VkKeyScan
|
|
||||||
Params: AChar: Character to translate
|
|
||||||
Returns: LoByte: VK-code
|
|
||||||
HiByte: ALT | CTRL | SHIFT pressed -> bit2 | bit1 | bit0
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------}
|
|
||||||
function TGtkWidgetSet.VkKeyScan(AChar: Char): Short;
|
|
||||||
var
|
|
||||||
UTF8Char: TVKeyUTF8Char;
|
|
||||||
begin
|
|
||||||
FillByte(UTF8Char, SizeOf(UTF8Char), 0);
|
|
||||||
UTF8Char[0] := AChar;
|
|
||||||
Result := CharToVkAndFlags(UTF8Char);
|
|
||||||
end;
|
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
Function: WindowFromPoint
|
Function: WindowFromPoint
|
||||||
|
@ -207,8 +207,6 @@ function StretchMaskBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; X
|
|||||||
|
|
||||||
Function TextOut(DC: HDC; X,Y : Integer; Str : Pchar; Count: Integer) : Boolean; override;
|
Function TextOut(DC: HDC; X,Y : Integer; Str : Pchar; Count: Integer) : Boolean; override;
|
||||||
|
|
||||||
function VkKeyScan(AChar: Char): Short; override;
|
|
||||||
|
|
||||||
Function WindowFromPoint(Point : TPoint) : HWND; override;
|
Function WindowFromPoint(Point : TPoint) : HWND; override;
|
||||||
|
|
||||||
//##apiwiz##eps## // Do not remove, no wizard declaration after this line
|
//##apiwiz##eps## // Do not remove, no wizard declaration after this line
|
||||||
|
@ -740,7 +740,7 @@ begin
|
|||||||
|
|
||||||
Msg.msg := LM_HSCROLL;
|
Msg.msg := LM_HSCROLL;
|
||||||
// get scrollcode
|
// get scrollcode
|
||||||
if ssLeft in GTKEventState2ShiftState(Word(Mask))
|
if ssLeft in GTKEventStateToShiftState(Word(Mask))
|
||||||
then Msg.ScrollCode := SB_THUMBTRACK
|
then Msg.ScrollCode := SB_THUMBTRACK
|
||||||
else if V <= L
|
else if V <= L
|
||||||
then Msg.ScrollCode := SB_TOP
|
then Msg.ScrollCode := SB_TOP
|
||||||
@ -802,7 +802,7 @@ begin
|
|||||||
|
|
||||||
Msg.msg := LM_VSCROLL;
|
Msg.msg := LM_VSCROLL;
|
||||||
// Get scrollcode
|
// Get scrollcode
|
||||||
if ssLeft in GTKEventState2ShiftState(Word(Mask))
|
if ssLeft in GTKEventStateToShiftState(Word(Mask))
|
||||||
then Msg.ScrollCode := SB_THUMBTRACK
|
then Msg.ScrollCode := SB_THUMBTRACK
|
||||||
else if V <= L
|
else if V <= L
|
||||||
then Msg.ScrollCode := SB_TOP
|
then Msg.ScrollCode := SB_TOP
|
||||||
|
@ -65,28 +65,28 @@ function GTK2KeyDown(Widget: PGtkWidget; Event : pgdkeventkey;
|
|||||||
Data: gPointer) : GBoolean; cdecl;
|
Data: gPointer) : GBoolean; cdecl;
|
||||||
begin
|
begin
|
||||||
//debugln('GTK2KeyDown ',DbgSName(TObject(Data)));
|
//debugln('GTK2KeyDown ',DbgSName(TObject(Data)));
|
||||||
Result := HandleGtkKeyUpDown(Widget, Event, Data, True);
|
Result := HandleGtkKeyUpDown(Widget, Event, Data, True, True);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function GTK2KeyDownAfter(Widget: PGtkWidget; Event : pgdkeventkey;
|
function GTK2KeyDownAfter(Widget: PGtkWidget; Event : pgdkeventkey;
|
||||||
Data: gPointer) : GBoolean; cdecl;
|
Data: gPointer) : GBoolean; cdecl;
|
||||||
begin
|
begin
|
||||||
//debugln('GTK2KeyDownAfter ',DbgSName(TObject(Data)));
|
//debugln('GTK2KeyDownAfter ',DbgSName(TObject(Data)));
|
||||||
Result := HandleGtkKeyUpDown(Widget, Event, Data, False);
|
Result := HandleGtkKeyUpDown(Widget, Event, Data, False, True);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function GTK2KeyUp(Widget: PGtkWidget; Event : pgdkeventkey;
|
function GTK2KeyUp(Widget: PGtkWidget; Event : pgdkeventkey;
|
||||||
Data: gPointer) : GBoolean; cdecl;
|
Data: gPointer) : GBoolean; cdecl;
|
||||||
begin
|
begin
|
||||||
//debugln('GTK2KeyUp ',DbgSName(TObject(Data)));
|
//debugln('GTK2KeyUp ',DbgSName(TObject(Data)));
|
||||||
Result := HandleGtkKeyUpDown(Widget, Event, Data, True);
|
Result := HandleGtkKeyUpDown(Widget, Event, Data, True, False);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function GTK2KeyUpAfter(Widget: PGtkWidget; Event : pgdkeventkey;
|
function GTK2KeyUpAfter(Widget: PGtkWidget; Event : pgdkeventkey;
|
||||||
Data: gPointer) : GBoolean; cdecl;
|
Data: gPointer) : GBoolean; cdecl;
|
||||||
begin
|
begin
|
||||||
//debugln('GTK2KeyUpAfter ',DbgSName(TObject(Data)));
|
//debugln('GTK2KeyUpAfter ',DbgSName(TObject(Data)));
|
||||||
Result := HandleGtkKeyUpDown(Widget, Event, Data, False);
|
Result := HandleGtkKeyUpDown(Widget, Event, Data, False, False);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function GTK2KillFocusCB(widget: PGtkWidget; event:PGdkEventFocus;
|
function GTK2KillFocusCB(widget: PGtkWidget; event:PGdkEventFocus;
|
||||||
|
@ -27,7 +27,7 @@ unit Gtk2WSComCtrls;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
// libs
|
// libs
|
||||||
GLib2, Gtk2, Gdk2, Gdk2pixbuf,
|
GLib2, Gtk2, Gdk2, Gdk2pixbuf,
|
||||||
// LCL
|
// LCL
|
||||||
ComCtrls, Classes, FPCAdds, LCLType, LMessages, Controls, Graphics, CommCtrl,
|
ComCtrls, Classes, FPCAdds, LCLType, LMessages, Controls, Graphics, CommCtrl,
|
||||||
|
@ -2483,12 +2483,6 @@ Begin
|
|||||||
// Result := 0;
|
// Result := 0;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
{function TWinCEWidgetSet.VkKeyScan(AChar: Char): Short;
|
|
||||||
begin
|
|
||||||
Result:=inherited VkKeyScan(AChar);
|
|
||||||
end;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
Method: CallDefaultWndHandler
|
Method: CallDefaultWndHandler
|
||||||
|
@ -228,7 +228,6 @@ function StretchMaskBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; X
|
|||||||
Function TextOut(DC: HDC; X,Y : Integer; Str : Pchar; Count: Integer) : Boolean; override;
|
Function TextOut(DC: HDC; X,Y : Integer; Str : Pchar; Count: Integer) : Boolean; override;
|
||||||
|
|
||||||
function UpdateWindow(Handle: HWND): Boolean;override;
|
function UpdateWindow(Handle: HWND): Boolean;override;
|
||||||
{function VkKeyScan(AChar: Char): Short; override;}
|
|
||||||
|
|
||||||
Function WindowFromPoint(Point : TPoint) : HWND; override;
|
Function WindowFromPoint(Point : TPoint) : HWND; override;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user