mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-20 12:19:31 +02:00
Qt: implemented eventHandler via QSocketNotifier, patch by Almindor.
git-svn-id: trunk@25251 -
This commit is contained in:
parent
ba8e8616b1
commit
59f8b84790
@ -61,6 +61,7 @@ type
|
||||
SavedDCList: TFPList;
|
||||
CriticalSection: TRTLCriticalSection;
|
||||
SavedHandlesList: TMap;
|
||||
FSocketEventMap: TMap;
|
||||
// global hooks
|
||||
FAppEvenFilterHook: QObject_hookH;
|
||||
FAppFocusChangedHook: QApplication_hookH;
|
||||
|
@ -30,11 +30,95 @@
|
||||
|
||||
//##apiwiz##sps## // Do not remove
|
||||
|
||||
{
|
||||
This is the common cdecl callback function used for Qt4
|
||||
QSocketNotifier activated.
|
||||
}
|
||||
procedure TQtWidgetSet.SocketNotifierRead_cb(aSocket: Integer); cdecl;
|
||||
var
|
||||
wheh: PWaitHandleEventHandler;
|
||||
begin
|
||||
if FSocketEventMap.GetData(aSocket, wheh) then
|
||||
wheh^.user_callback(wheh^.udata, EVE_IO_READ);
|
||||
end;
|
||||
|
||||
procedure TQtWidgetSet.SocketNotifierWrite_cb(aSocket: Integer); cdecl;
|
||||
var
|
||||
wheh: PWaitHandleEventHandler;
|
||||
begin
|
||||
if FSocketEventMap.GetData(aSocket, wheh) then
|
||||
wheh^.user_callback(wheh^.udata, EVE_IO_WRITE);
|
||||
end;
|
||||
|
||||
procedure TQtWidgetSet.SocketNotifierError_cb(aSocket: Integer); cdecl;
|
||||
var
|
||||
wheh: PWaitHandleEventHandler;
|
||||
begin
|
||||
if FSocketEventMap.GetData(aSocket, wheh) then
|
||||
wheh^.user_callback(wheh^.udata, EVE_IO_ERROR);
|
||||
end;
|
||||
|
||||
function TQtWidgetSet.AddEventHandler(AHandle: THandle; AFlags: dword;
|
||||
AEventHandler: TWaitHandleEvent; AData: PtrInt): PEventHandler;
|
||||
{
|
||||
QSocketNotifier requires 1 notifier per event type
|
||||
and doesn't provide userdata in the callback. We need to
|
||||
make a map of socket -> userdata to store userdata
|
||||
and also create 3 notifiers for each event. We also need to
|
||||
use our own constants for the event types in the userland callback.
|
||||
For simplicity same as GTK G_IO values are used here and
|
||||
their ORs will be emulated. The callback will always only get
|
||||
1 event tho.
|
||||
}
|
||||
|
||||
function CreateQt4NotifierRec(aNR: PWaitHandleEventHandler;
|
||||
const aType: QSocketNotifierType; aCallback: QSocketNotifier_activated_Event): PWaitHandleEventHandler;
|
||||
var
|
||||
qsn: QSocketNotifierH;
|
||||
qsn_hook: QSocketNotifier_hookH;
|
||||
i: QSocketNotifierType;
|
||||
begin
|
||||
if aNR = nil then begin
|
||||
Result := new(PWaitHandleEventHandler);
|
||||
for i := QSocketNotifierRead to QSocketNotifierException do begin
|
||||
Result^.qsn[i] := nil; // nil them so removeeventhandler can find out what to free
|
||||
Result^.qsn_hook[i] := nil;
|
||||
end;
|
||||
end else
|
||||
Result := aNR;
|
||||
|
||||
qsn := QSocketNotifier_create(aHandle, aType);
|
||||
qsn_hook := QSocketNotifier_hook_create(qsn);
|
||||
QSocketNotifier_hook_hook_activated(qsn_hook, aCallback); // todo: !!
|
||||
|
||||
Result^.qsn[aType] := qsn;
|
||||
Result^.qsn_hook[aType] := qsn_hook;
|
||||
end;
|
||||
|
||||
begin
|
||||
// todo
|
||||
Result := nil;
|
||||
|
||||
if AFlags and (EVE_IO_READ or EVE_IO_WRITE or EVE_IO_ERROR) = 0 then
|
||||
Exit; // no flag set, no dice
|
||||
|
||||
if AFlags and EVE_IO_READ = EVE_IO_READ then
|
||||
Result := CreateQt4NotifierRec(Result, QSocketNotifierRead, @SocketNotifierRead_cb);
|
||||
|
||||
if AFlags and EVE_IO_WRITE = EVE_IO_WRITE then
|
||||
Result := CreateQt4NotifierRec(Result, QSocketNotifierWrite, @SocketNotifierWrite_cb);
|
||||
|
||||
if AFlags and EVE_IO_ERROR = EVE_IO_ERROR then
|
||||
Result := CreateQt4NotifierRec(Result, QSocketNotifierException, @SocketNotifierError_cb);
|
||||
|
||||
PWaitHandleEventHandler(Result)^.user_callback := AEventHandler;
|
||||
PWaitHandleEventHandler(Result)^.udata := aData;
|
||||
PWaitHandleEventHandler(Result)^.socket := AHandle;
|
||||
|
||||
if FSocketEventMap.HasId(aHandle) then begin // if we encounter this (shouldn't happen)
|
||||
Debugln('TQtWidgetSet.AddEventHandler Duplicate handle: ' + IntToStr(aHandle));
|
||||
FSocketEventMap.Delete(aHandle); // delete the previous one, potentially losing it..
|
||||
end;
|
||||
FSocketEventMap.Add(AHandle, Result);
|
||||
end;
|
||||
|
||||
function TQtWidgetSet.AddPipeEventHandler(AHandle: THandle;
|
||||
@ -659,8 +743,20 @@ begin
|
||||
end;
|
||||
|
||||
procedure TQtWidgetSet.RemoveEventHandler(var AHandler: PEventHandler);
|
||||
var
|
||||
wheh: PWaitHandleEventHandler;
|
||||
i: QSocketNotifierType;
|
||||
begin
|
||||
// todo
|
||||
wheh := PWaitHandleEventHandler(aHandler);
|
||||
FSocketEventMap.Delete(wheh^.socket); // delete from the map
|
||||
|
||||
for i := QSocketNotifierRead to QSocketNotifierException do
|
||||
if Assigned(wheh^.qsn[i]) then begin
|
||||
QSocketNotifier_destroy(wheh^.qsn[i]);
|
||||
QSocketNotifier_hook_destroy(wheh^.qsn_hook[i]);
|
||||
end;
|
||||
dispose(wheh);
|
||||
aHandler := nil;
|
||||
end;
|
||||
|
||||
procedure TQtWidgetSet.RemovePipeEventHandler(var AHandler: PPipeEventHandler);
|
||||
@ -673,6 +769,25 @@ begin
|
||||
// todo
|
||||
end;
|
||||
|
||||
procedure TQtWidgetSet.SetEventHandlerFlags(AHandler: PEventHandler;
|
||||
NewFlags: dword);
|
||||
var
|
||||
wheh: PWaitHandleEventHandler;
|
||||
do_read: boolean;
|
||||
do_write: boolean;
|
||||
do_error: boolean;
|
||||
begin
|
||||
wheh := PWaitHandleEventHandler(aHandler);
|
||||
|
||||
do_read := NewFlags and EVE_IO_READ = EVE_IO_READ;
|
||||
do_write := NewFlags and EVE_IO_WRITE = EVE_IO_WRITE;
|
||||
do_error := NewFlags and EVE_IO_ERROR = EVE_IO_ERROR;
|
||||
|
||||
QSocketNotifier_setEnabled(wheh^.qsn[QSocketNotifierRead], do_read);
|
||||
QSocketNotifier_setEnabled(wheh^.qsn[QSocketNotifierWrite], do_write);
|
||||
QSocketNotifier_setEnabled(wheh^.qsn[QSocketNotifierException], do_error);
|
||||
end;
|
||||
|
||||
function TQtWidgetSet.TextUTF8Out(DC: HDC; X, Y: Integer; Str: PChar; Count: Longint): Boolean;
|
||||
begin
|
||||
Result := False;
|
||||
|
@ -30,6 +30,9 @@
|
||||
|
||||
//##apiwiz##sps## // Do not remove
|
||||
|
||||
procedure SocketNotifierRead_cb(aSocket: Integer); cdecl; // internal callback, don't use!
|
||||
procedure SocketNotifierWrite_cb(aSocket: Integer); cdecl; // internal callback, don't use!
|
||||
procedure SocketNotifierError_cb(aSocket: Integer); cdecl; // internal callback, don't use!
|
||||
function AddEventHandler(AHandle: THandle; AFlags: dword;
|
||||
AEventHandler: TWaitHandleEvent; AData: PtrInt): PEventHandler; override;
|
||||
function AddPipeEventHandler(AHandle: THandle;
|
||||
@ -73,6 +76,8 @@ procedure RemoveEventHandler(var AHandler: PEventHandler); override;
|
||||
procedure RemovePipeEventHandler(var AHandler: PPipeEventHandler); override;
|
||||
procedure RemoveProcessEventHandler(var AHandler: PProcessEventHandler); override;
|
||||
|
||||
procedure SetEventHandlerFlags(AHandler: PEventHandler; NewFlags: dword); override;
|
||||
|
||||
function TextUTF8Out(DC: HDC; X, Y: Integer; Str: PChar; Count: Longint): Boolean; override;
|
||||
|
||||
//##apiwiz##eps## // Do not remove, no wizard declaration after this line
|
||||
|
@ -37,6 +37,7 @@ begin
|
||||
FDragImageLock := False;
|
||||
System.InitCriticalSection(CriticalSection);
|
||||
SavedHandlesList := TMap.Create(TMapIdType(ituPtrSize), SizeOf(TObject));
|
||||
FSocketEventMap := TMap.Create(TMapIdType(its4), SizeOf(Pointer));
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
@ -70,6 +71,7 @@ begin
|
||||
SavedHandlesList.Free;
|
||||
SavedHandlesList := nil;
|
||||
end;
|
||||
FSocketEventMap.Free;
|
||||
|
||||
System.DoneCriticalsection(CriticalSection);
|
||||
|
||||
|
@ -32,10 +32,27 @@ interface
|
||||
{$I qtdefines.inc}
|
||||
|
||||
uses
|
||||
InterfaceBase,
|
||||
qt4,
|
||||
GraphType,
|
||||
LCLProc;
|
||||
|
||||
const
|
||||
EVE_IO_READ = 1;
|
||||
EVE_IO_WRITE = 4;
|
||||
EVE_IO_ERROR = 8;
|
||||
|
||||
type
|
||||
PWaitHandleEventHandler = ^TWaitHandleEventHandler;
|
||||
TWaitHandleEventHandler = record
|
||||
qsn: array[QSocketNotifierRead..QSocketNotifierException] of QSocketNotifierH; // the notifiers for events
|
||||
qsn_hook: array[QSocketNotifierRead..QSocketNotifierException] of QSocketNotifier_hookH; // the hooks
|
||||
user_callback: TWaitHandleEvent;
|
||||
udata: PtrInt; // the userdata
|
||||
socket: Integer; // for mapping
|
||||
end;
|
||||
|
||||
|
||||
procedure FillStandardDescription(var Desc: TRawImageDescription);
|
||||
function GetPixelsPerInch: Integer;
|
||||
function GetUtf8String(S: String): WideString;
|
||||
|
Loading…
Reference in New Issue
Block a user