customdrawnws: X11: Starts implementing events. Implements OnMouseMove, form closing, OnClick

git-svn-id: trunk@33728 -
This commit is contained in:
sekelsenmat 2011-11-23 15:54:52 +00:00
parent 77e748c9cb
commit fc9d9ffdc9
4 changed files with 196 additions and 54 deletions

View File

@ -7,7 +7,7 @@ interface
uses
// rtl+ftl
Types, Classes, SysUtils,
fpimage, fpcanvas,
fpimage, fpcanvas, ctypes,
X, XLib,
// Custom Drawn Canvas
IntfGraphics, lazcanvas,
@ -31,7 +31,24 @@ type
Canvas: TLazCanvas;
end;
function XButtonToMouseButton(const XButton: cint; var MouseButton: TMouseButton): Boolean;
implementation
{ Returns True if the button is indeed a mouse button
and False if it's the mouse wheel }
function XButtonToMouseButton(const XButton: cint; var MouseButton: TMouseButton): Boolean;
const
ButtonTable: array[1..3] of TMouseButton = (mbLeft, mbMiddle, mbRight);
begin
Result := False;
if (XButton > 3) or (XButton < 1) then Exit;
MouseButton := ButtonTable[XButton];
Result := True;
end;
end.

View File

@ -162,11 +162,11 @@ procedure TCDWidgetSet.AppRun(const ALoop: TApplicationMainLoop);
var
XEvent: TXEvent;
WindowEntry: TWinControl;
MouseButton: TMouseButton;
Sum: Integer;
NewEvent: TXEvent;
DoBreakRun: Boolean = False;
lWindowListIndex: Integer;
CurWindowInfo: TX11WindowInfo;
begin
while (DoBreakRun = False) do
begin
@ -182,11 +182,6 @@ begin
else}
XNextEvent(FDisplay, @XEvent);
// if the event filter returns true then it ate the message
//if Assigned(FEventFilter) and FEventFilter(XEvent) then continue;
//if Forms.Count = 0 then continue;
// According to a comment in X.h, the valid event types start with 2!
if XEvent._type >= 2 then
begin
@ -199,7 +194,12 @@ begin
Continue;
end;
TX11WindowInfo(WindowList.Items[lWindowListIndex]).XEvent := @XEvent;
CurWindowInfo := TX11WindowInfo(WindowList.Items[lWindowListIndex]);
CurWindowInfo.XEvent := @XEvent;
{$ifdef VerboseCDEvents}
DebugLn('LCL-CustomDrawn-X11: X11 event received: ', GetXEventName(XEvent._type));
{$endif}
case XEvent._type of
X.DestroyNotify:
@ -208,73 +208,39 @@ begin
end;
X.KeyPress:
begin
//TCDWSCustomForm.EvKeyPressed(WindowEntry, TX11WindowInfo(WindowList.Items[lWindowListIndex]));
//WindowEntry.EvKeyPressed(XEvent.xkey.keycode);
TCDWSCustomForm.EvKeyPressed(WindowEntry, CurWindowInfo, XEvent.xkey);
end;
X.KeyRelease:
begin
// WindowEntry.EvKeyReleased(XEvent.xkey.keycode);
TCDWSCustomForm.EvKeyReleased(WindowEntry, CurWindowInfo, XEvent.xkey);
end;
X.ButtonPress:
begin
{ if XButtonToMouseButton(XEvent.xbutton.button, MouseButton) then
WindowEntry.EvMousePressed(MouseButton,
Point(XEvent.xbutton.x, XEvent.xbutton.y))
else
begin
if XEvent.xbutton.button = 4 then Sum := -1
else Sum := 1;
// Check for other mouse wheel messages in the queue
while XCheckTypedWindowEvent(GFApplication.Handle,
WindowEntry.Handle, X.ButtonPress, @NewEvent) do
begin
if NewEvent.xbutton.Button = 4 then Dec(Sum)
else if NewEvent.xbutton.Button = 5 then Inc(Sum)
else
begin
XPutBackEvent(GFApplication.Handle, @NewEvent);
break;
end;
end;
WindowEntry.EvMouseWheel(
Sum, Point(XEvent.xbutton.x, XEvent.xbutton.y));
end;}
TCDWSCustomForm.EvMousePressed(WindowEntry, CurWindowInfo, XEvent.xbutton);
end;
X.ButtonRelease:
begin
{ Release events are only for mouse buttons, and not mouse wheel moviments }
{ if (XEvent.xbutton.button >= 1) and (XEvent.xbutton.button <= 3) then
begin
XButtonToMouseButton(XEvent.xbutton.button, MouseButton);
WindowEntry.EvMouseReleased(
MouseButton,
Point(XEvent.xbutton.x, XEvent.xbutton.y));
end;}
TCDWSCustomForm.EvMouseReleased(WindowEntry, CurWindowInfo, XEvent.xbutton);
end;
X.EnterNotify:
begin
// WindowEntry.EvMouseEnter(
// Point(XEvent.xbutton.x, XEvent.xbutton.y));
TCDWSCustomForm.EvMouseEnter(WindowEntry, CurWindowInfo);
end;
X.LeaveNotify:
begin
// WindowEntry.EvMouseLeave();
TCDWSCustomForm.EvMouseLeave(WindowEntry, CurWindowInfo);
end;
X.MotionNotify:
begin
// WindowEntry.EvMouseMove(
// Point(XEvent.xbutton.x, XEvent.xbutton.y));
TCDWSCustomForm.EvMouseMove(WindowEntry, CurWindowInfo, XEvent.xmotion);
end;
X.FocusIn:
begin
// WindowEntry.EvFocusIn();
TCDWSCustomForm.EvFocusIn(WindowEntry, CurWindowInfo);
end;
X.FocusOut:
begin
// WindowEntry.EvFocusOut();
TCDWSCustomForm.EvFocusOut(WindowEntry, CurWindowInfo);
end;
X.MapNotify:
begin
@ -294,22 +260,24 @@ begin
For now we are just ignoring all expose messages where Count <> 0 }
if XEvent.xexpose.count = 0 then
begin
TCDWSCustomForm.EvPaint(WindowEntry, TX11WindowInfo(WindowList.Items[lWindowListIndex]));
TCDWSCustomForm.EvPaint(WindowEntry, CurWindowInfo);
end;
end;
X.ConfigureNotify:
begin
// WindowEntry.Dispatch(XEvent);
TCDWSCustomForm.EvConfigureNotify(WindowEntry, CurWindowInfo, XEvent.xconfigure);
end;
X.ClientMessage:
begin
// WindowEntry.Dispatch(XEvent);
TCDWSCustomForm.EvClientMessage(WindowEntry, CurWindowInfo, XEvent.xclient);
end;
else
DebugLn('LCL-CustomDrawn-X11: Unhandled X11 event received: ', GetXEventName(XEvent._type));
end;
end;
DoBreakRun := Application.Terminated;
end;
DoBreakRun := False;
end;

View File

@ -104,7 +104,25 @@ type
class procedure DrawRawImageToGC_XPutImage(ARawImage: TRawImage;
ADestWindowInfo: TX11WindowInfo; ADestX, ADestY, ADestWidth, ADestHeight: Integer);
// Event handling
class procedure EvKeyPressed(const AWinControl: TWinControl;
AWindowInfo: TX11WindowInfo; var Event: TXKeyEvent);
class procedure EvKeyReleased(const AWinControl: TWinControl;
AWindowInfo: TX11WindowInfo; var Event: TXKeyEvent);
class procedure EvMousePressed(const AWinControl: TWinControl; AWindowInfo: TX11WindowInfo;
var Event: TXButtonEvent);
class procedure EvMouseReleased(const AWinControl: TWinControl; AWindowInfo: TX11WindowInfo;
var Event: TXButtonEvent);
class procedure EvMouseEnter(const AWinControl: TWinControl; AWindowInfo: TX11WindowInfo);
class procedure EvMouseLeave(const AWinControl: TWinControl; AWindowInfo: TX11WindowInfo);
class procedure EvMouseMove(const AWinControl: TWinControl; AWindowInfo: TX11WindowInfo;
var Event: TXMotionEvent);
class procedure EvFocusIn(const AWinControl: TWinControl; AWindowInfo: TX11WindowInfo);
class procedure EvFocusOut(const AWinControl: TWinControl; AWindowInfo: TX11WindowInfo);
class procedure EvPaint(const AWinControl: TWinControl; AWindowInfo: TX11WindowInfo);
class procedure EvConfigureNotify(const AWinControl: TWinControl; AWindowInfo: TX11WindowInfo;
var Event: TXConfigureEvent);
class procedure EvClientMessage(const AWinControl: TWinControl;
AWindowInfo: TX11WindowInfo; var Event: TXClientMessageEvent);
{$endif}
published
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;

View File

@ -470,6 +470,101 @@ begin
// XDestroyImage(Image);
end;
class procedure TCDWSCustomForm.EvKeyPressed(const AWinControl: TWinControl;
AWindowInfo: TX11WindowInfo; var Event: TXKeyEvent);
{var
KeySym: TKeySym;}
begin
{ KeySym := StartComposing(FXEvent^);
inherited EvKeyPressed(AKey);
if (FXEvent^.xkey.state and (ControlMask or Mod1Mask)) = 0 then EndComposing;}
end;
class procedure TCDWSCustomForm.EvKeyReleased(const AWinControl: TWinControl;
AWindowInfo: TX11WindowInfo; var Event: TXKeyEvent);
{var
KeySym: TKeySym;}
begin
{ KeySym := StartComposing(FXEvent^);
inherited EvKeyReleased(AKey);
// Do not call EndComposing, as this would generate duplicate KeyChar events!}
end;
class procedure TCDWSCustomForm.EvMousePressed(const AWinControl: TWinControl; AWindowInfo: TX11WindowInfo;
var Event: TXButtonEvent);
var
MouseButton: TMouseButton;
begin
if XButtonToMouseButton(Event.button, MouseButton) then
begin
LCLSendMouseDownMsg(AWinControl, Event.x, Event.y, MouseButton, []);
end
else
begin
{ if Event.button = 4 then Sum := -1
else Sum := 1;
// Check for other mouse wheel messages in the queue
while XCheckTypedWindowEvent(GFApplication.Handle,
WindowEntry.Handle, X.ButtonPress, @NewEvent) do
begin
if NewEvent.xbutton.Button = 4 then Dec(Sum)
else if NewEvent.xbutton.Button = 5 then Inc(Sum)
else
begin
XPutBackEvent(GFApplication.Handle, @NewEvent);
break;
end;
end;
WindowEntry.EvMouseWheel(
Sum, Point(XEvent.xbutton.x, XEvent.xbutton.y));}
end;
end;
class procedure TCDWSCustomForm.EvMouseReleased(const AWinControl: TWinControl; AWindowInfo: TX11WindowInfo;
var Event: TXButtonEvent);
var
MouseButton: TMouseButton;
begin
{ Release events are only for mouse buttons, and not mouse wheel moviments }
if (Event.button >= 1) and (Event.button <= 3) then
begin
XButtonToMouseButton(Event.button, MouseButton);
LCLSendMouseUpMsg(AWinControl, Event.x, Event.y, MouseButton, []);
LCLSendClickedMsg(AWinControl);
end;
end;
class procedure TCDWSCustomForm.EvMouseEnter(const AWinControl: TWinControl; AWindowInfo: TX11WindowInfo);
begin
end;
class procedure TCDWSCustomForm.EvMouseLeave(const AWinControl: TWinControl; AWindowInfo: TX11WindowInfo);
begin
end;
class procedure TCDWSCustomForm.EvMouseMove(const AWinControl: TWinControl; AWindowInfo: TX11WindowInfo;
var Event: TXMotionEvent);
begin
LCLSendMouseMoveMsg(AWinControl, Event.x, Event.y, []);
end;
class procedure TCDWSCustomForm.EvFocusIn(const AWinControl: TWinControl; AWindowInfo: TX11WindowInfo);
begin
LCLSendActivateMsg(AWinControl, True, false);
end;
class procedure TCDWSCustomForm.EvFocusOut(const AWinControl: TWinControl; AWindowInfo: TX11WindowInfo);
begin
LCLSendDeactivateStartMsg(AWinControl);
end;
class procedure TCDWSCustomForm.EvPaint(const AWinControl: TWinControl; AWindowInfo: TX11WindowInfo);
var
struct : TPaintStruct;
@ -529,6 +624,50 @@ begin
{$ENDIF}
end;
class procedure TCDWSCustomForm.EvConfigureNotify(const AWinControl: TWinControl; AWindowInfo: TX11WindowInfo;
var Event: TXConfigureEvent);
begin
// Remove other repeated events
//while XCheckTypedWindowEvent(CDWidget.FDisplay, AWindowInfo.Window, X.ConfigureNotify, @Event) do;
{ // Move event
if (Event.x <> AWinControl.Left) or (Event.y <> AWinControl.Top) then
begin
LCLSendMoveMsg(AWinControl, Event.x, Event.y);
end;
// Size event
if (Event.Width <> AWinControl.Width) or (Event.Height <> AWinControl.Height) then
begin
//SIZENORMAL, SIZEICONIC, SIZEFULLSCREEN, SIZEZOOMSHOW, SIZEZOOMHIDE.
LCLSendSizeMsg(AWinControl, Event.Width, Event.Height, SIZENORMAL);
// TX11Canvas(Canvas).Resized(ClientWidth, ClientHeight);
end;}
end;
class procedure TCDWSCustomForm.EvClientMessage(const AWinControl: TWinControl;
AWindowInfo: TX11WindowInfo; var Event: TXClientMessageEvent);
var
CanClose: Boolean;
begin
if Event.message_type = CDWidgetset.FWMProtocols then
begin
if Event.Data.l[0] = CDWidgetset.FWMDeleteWindow then
begin
// Message results : 0 - do nothing, 1 - destroy window (felipe: is this comment correct? taken from lcl-cocoa)
CanClose:=LCLSendCloseQueryMsg(AWinControl)>0;
if {CanClose} True then // CanClose is returning false -> ToDo: find out why
begin
LCLSendCloseUpMsg(AWinControl);
XDestroyWindow(CDWidgetset.FDisplay, AWinControl.Handle);
end;
end
else
DebugLn(Format('LCL-CustomDrawn-X11: Unknown client protocol message: %d', [Event.Data.l[0]]));
end
else
DebugLn(Format('LCL-CustomDrawn-X11: Unknown client message: %d', [Event.message_type]));
end;
{------------------------------------------------------------------------------
Method: TCDWSCustomForm.CreateHandle
Params: None