Patch from Giuliano: Fixes compilation, adds a new smart painting for X11, improves trayicon for X11

git-svn-id: trunk@36721 -
This commit is contained in:
sekelsenmat 2012-04-11 08:28:09 +00:00
parent 34e6e9ce12
commit c74dcfc14e
6 changed files with 105 additions and 22 deletions

View File

@ -29,6 +29,10 @@ type
Colormap: TColormap;
GC: TGC;
ColorDepth: Byte;
{$ifdef CD_X11_SmartPaint}
Valid: Boolean;
Moved: Boolean;
{$endif}
end;
{$ifdef CD_X11_UseNewTimer}

View File

@ -50,6 +50,7 @@
{$define CD_X11_NewNativePaint}
{$define CD_X11_UseLCL_MainLoop}
{$define CD_X11_UseNewTimer}
{$define CD_X11_SmartPaint}
// ==================
// X11 experimental options
@ -58,7 +59,7 @@
// To be able to use TThreads, UseCThreads must be defined in the application!
{ $ifdef UseCTthreads}
{$ifdef CD_X11_UseNewTimer}
{ $define TimerUseCThreads}
{.$define TimerUseCThreads}
{$endif}
{ $endif}
{$endif}
@ -73,5 +74,6 @@
{.$define VerboseCDBitmap}
{.$define VerboseCDForms}
{.$define VerboseCDX11WinAPI}
{.$define VerboseCDEvents}
{.$define VerboseCDAccessibility}

View File

@ -29,13 +29,15 @@ interface
uses
// RTL
Classes, SysUtils, Math,
// for CD_Cocoa Types needs to be after the platform-specif units or else Mac
// will catch MacOSAll.Rect/Size/Point
{$ifndef CD_Cocoa}Types,{$endif}Classes, SysUtils, Math,
fpimage, fpcanvas, fpimgcanv, ctypes, dateutils,
// XML
XMLRead, Dom,
// Platform specific
{$ifdef CD_Windows}Windows, customdrawn_WinProc,{$endif}
{$ifdef CD_Cocoa}MacOSAll, CocoaAll, customdrawn_cocoaproc, CocoaGDIObjects,{$endif}
{$ifdef CD_Cocoa}MacOSAll, CocoaAll, customdrawn_cocoaproc, CocoaGDIObjects,Types,{$endif}
{$ifdef CD_X11}X, XLib, XUtil, BaseUnix, customdrawn_x11proc,{$ifdef CD_UseNativeText}xft, fontconfig,{$endif}{$endif}
{$ifdef CD_Android}
customdrawn_androidproc, jni, bitmap, log, keycodes,
@ -47,8 +49,6 @@ uses
// LazFreeType
LazFreeTypeIntfDrawer, LazFreeType, EasyLazFreeType, IniFiles,
{$endif}
// Types needs to be after the platform-specif units or else Mac will catch MacOSAll.Rect/Size/Point
Types,
// Widgetset
customdrawnproc,
// LCL
@ -92,6 +92,9 @@ type
function applicationShouldTerminate(sender: NSApplication): NSApplicationTerminateReply; message 'applicationShouldTerminate:';
end;
{$endif}
{$ifdef CD_X11}
// Just in case...
{$endif}
// Return true to disable the form background drawing
TDisableFormBackgroundDrawingProc = function (AForm: TCustomForm): Boolean of object;
@ -148,6 +151,8 @@ type
{$ifdef CD_X11}
FDisplayName: string;
FDisplay: PDisplay;
FScreen: longint;
FVisual: TVisual; // Visual from X11
LeaderWindow: X.TWindow;
ClientLeaderAtom: TAtom;

View File

@ -42,6 +42,10 @@ begin
if XWindowList.Strings[I] <> 'Paint' then begin
XWindowList.Strings[I] := 'Paint';
Result:= True;
{$ifdef CD_X11_SmartPaint}
AWindowInfo.Valid:= True;
AWindowInfo.Moved:= False;
{$endif}
Exit;
end;
end;
@ -152,6 +156,10 @@ end;
procedure TCDWidgetSet.AppInit(var ScreenInfo: TScreenInfo);
var
ClassHint: PXClassHint;
DW,DH,DWMM,DHMM: culong;
I: Integer;
APVisual: PVisual;
begin
{$ifdef Verbose_CDWS}
// DebugLn('TCDWidgetSet.AppInit');
@ -171,6 +179,8 @@ begin
if not Assigned(FDisplay) then
raise Exception.Create('[TCDWidgetSet.AppInit] XOpenDisplay failed');
// if we have a Display then we should have a Screen too
FScreen:= XDefaultScreen(FDisplay);
// Keyboard initialization
@ -181,12 +191,47 @@ begin
if InputContext = nil then DebugLn('[TCDWidgetSet.BackendInit] Failed to initialize the Keyboard handling!');
// Initialize ScreenInfo
ScreenInfo.PixelsPerInchX:= 96;
ScreenInfo.PixelsPerInchY:= 96;
// Screen Metrics
DW:= XDisplayWidth(FDisplay,FScreen);
DWMM:= XDisplayWidthMM(FDisplay,FScreen);
ScreenInfo.PixelsPerInchX:= round(float(DW)/(DWMM/25.4));
DH:= XDisplayHeight(FDisplay,FScreen);
DHMM:=XDisplayHeightMM(FDisplay,FScreen);
ScreenInfo.PixelsPerInchY:= round(float(DH)/(DHMM/25.4));
// Color Depth
ScreenInfo.ColorDepth:= XDefaultDepth(FDisplay,FScreen);
ScreenInfo.Initialized:= True;
// ToDo: Actually check which format it is at
ScreenFormat := clfBGR24;
// Pixmap Format
APVisual:= XDefaultVisual(FDisplay,FScreen);
FVisual:= APVisual^;
if (ScreenInfo.ColorDepth = 16) then ScreenFormat:= clfRGB16_R5G6B5
else if (ScreenInfo.ColorDepth = 24) then begin
if (FVisual.blue_mask = $FF) and
(FVisual.green_mask = $FF00) and
(FVisual.red_mask = $FF0000) then
ScreenFormat:= clfBGR24
else if (FVisual.red_mask = $FF) and
(FVisual.green_mask = $FF00) and
(FVisual.blue_mask = $FF0000) then
ScreenFormat:= clfRGB24;
end
else if (ScreenInfo.ColorDepth = 32) then begin
if (FVisual.blue_mask = $FF) and
(FVisual.green_mask = $FF00) and
(FVisual.red_mask = $FF0000) then
ScreenFormat:= clfBGRA32
else if (FVisual.red_mask = $FF) and
(FVisual.green_mask = $FF00) and
(FVisual.blue_mask = $FF0000) then
ScreenFormat:= clfRGBA32
else if (FVisual.red_mask = $FF00) and
(FVisual.green_mask = $FF0000) and
(FVisual.blue_mask = $FF000000) then
ScreenFormat:= clfARGB32;
end;
//ScreenFormat := clfBGR24;
//if (not (woX11SkipWMHints in WindowOptions)) and (woWindow in WindowOptions) then
//begin
@ -440,7 +485,15 @@ begin
// http://tronche.com/gui/x/xlib/events/exposure/expose.html
if XEvent.xexpose.count = 0 then
begin
TCDWSCustomForm.EvPaint(WindowEntry, CurWindowInfo);
{$ifdef VerboseCDEvents}
DebugLn(Format('X11 event X.Expose - Window %d',[CurWindowInfo.Window]));
{$endif}
{$ifdef CD_X11_SmartPaint}
if CurWindowInfo.Valid then
TCDWSCustomForm.EvPaintEx(WindowEntry, CurWindowInfo)
else
{$endif}
TCDWSCustomForm.EvPaint(WindowEntry, CurWindowInfo);
end;
end;
X.ConfigureNotify:
@ -450,12 +503,13 @@ begin
X.ClientMessage:
begin
if XClientEvent.message_type = CDWidgetSet.FWMPaint then begin
{$ifdef VerboseCDEvents}
DebugLn(Format('X11 event WM_PAINT - Window %d',[CurWindowInfo.Window]));
{$endif}
{$IFDEF VerboseCDPaintProfiler}
lMessageTime:= DateTimeToMilliseconds(Now)-XClientEvent.data.l[1];
DebugLn(Format('X11 event WM_PAINT - Window %d, Delay %d ms',[CurWindowInfo.Window,lMessageTime]));
DebugLn(Format('CD_X11 event WM_PAINT - Window %d, Delay %d ms',[CurWindowInfo.Window,lMessageTime]));
{$else}
{$ifdef VerboseCDEvents}
DebugLn(Format('CD_X11 event WM_PAINT - Window %d',[CurWindowInfo.Window]));
{$endif}
{$ENDIF}
TCDWSCustomForm.EvPaintEx(WindowEntry, CurWindowInfo);
WindowUpdated(CurWindowInfo.Window);

View File

@ -21,6 +21,7 @@ type
procedure PaintForm(Sender: TObject);
function Send_Message(window: TWindow; msg: Integer;data1, data2,data3: Integer): boolean;
public
constructor create;
destructor Destroy; override;
procedure CreateForm(id: Integer);
function GetPosition: TPoint;
@ -149,6 +150,11 @@ begin
Result := false;//(untrap_errors() = 0);
end;
constructor TX11TrayIconHandle.create;
begin
inherited create;
end;
function TX11TrayIconHandle.TrayParent(UseCachedValue: Boolean = True): TWindow;
var
buf: array[0..32] of char;
@ -157,15 +163,12 @@ begin
if (fTrayParent <> 0) and UseCachedValue then
Exit(fTrayParent);
fDisplay := CDWidgetset.FDisplay;
fScreenID := DefaultScreen(CDWidgetSet.FDisplay);
XGrabServer(fDisplay);
fScreenID := CDWidgetSet.FScreen;
buf := PChar('_NET_SYSTEM_TRAY_S' + IntToStr(fScreenID));
selection_atom := XInternAtom(fDisplay, buf, false);
fTrayParent := XGetSelectionOwner(fDisplay, selection_atom);
XUngrabServer(fDisplay);
Result := fTrayParent;
end;
@ -208,10 +211,7 @@ begin
Sleep(80);
xsync(fdisplay,true);
XGrabServer(fDisplay);
XSelectInput(fDisplay, TrayParent, StructureNotifyMask);
XUngrabServer(fDisplay);
XFlush(fDisplay);
//fWindow := GDK_WINDOW_XWINDOW (Pointer(PGtkWidget(plug)^.window));
@ -251,7 +251,6 @@ begin
gtk_signal_connect_object(G_OBJECT(drawingarea), 'motion-notify-event', TGtkSignalFunc(@TGtk1TrayIconHandle.NotifyMouseMove), G_OBJECT(Self));
gtk_signal_connect_object(G_OBJECT(drawingarea), 'button-press-event', TGtkSignalFunc(@TGtk1TrayIconHandle.NotifyMouseDown), G_OBJECT(Self));
gtk_signal_connect_object(G_OBJECT(drawingarea), 'button-release-event', TGtkSignalFunc(@TGtk1TrayIconHandle.NotifyMouseUp), G_OBJECT(Self));}
//
fEmbedded := False;
GetCanvas;

View File

@ -209,6 +209,10 @@ begin
GCValues.graphics_exposures := 0;
AWindowInfo.GC := XCreateGC(CDWidgetSet.FDisplay, AWindowInfo.Window, GCGraphicsExposures, @GCValues);
{$ifdef CD_X11_SmartPaint}
AWindowInfo.Valid:= False; // Need Paint
AWindowInfo.Moved:= False; // And not move
{$endif}
// if not Assigned(GC) then
// raise EX11Error.Create(SGCCreationFailed);
@ -665,9 +669,18 @@ begin
TrueColor = 4;
DirectColor = 5;}
{$ENDIF}
{$ifdef CD_X11_SmartPaint}
if AWindowInfo.InvalidateRequestedInAnyControl then AWindowInfo.Valid:= False;
if (not AWindowInfo.Moved) or (not AWindowInfo.Valid) then begin // we're here just because a Move. We don't need to repaint
UpdateControlLazImageAndCanvas(AWindowInfo.Image, AWindowInfo.Canvas, lWidth, lHeight, clfBGR24);
RenderForm(AWindowInfo.Image, AWindowInfo.Canvas, TCustomForm(AWinControl));
end;
{$else}
UpdateControlLazImageAndCanvas(AWindowInfo.Image, AWindowInfo.Canvas, lWidth, lHeight, clfBGR24);
RenderForm(AWindowInfo.Image, AWindowInfo.Canvas, TCustomForm(AWinControl));
{$endif}
{$IFDEF VerboseCDPaintProfiler}
lCDTimeEnd := NowUTC();
@ -732,11 +745,17 @@ begin
// Move event
if (Event.x <> AWinControl.Left) or (Event.y <> AWinControl.Top) then
begin
{$ifdef CD_X11_SmartPaint}
AWindowInfo.Moved:= True; // doesn't need full painting
{$endif}
LCLSendMoveMsg(AWinControl, Event.x, Event.y);
end;
// Size event
if (Event.Width <> AWinControl.Width) or (Event.Height <> AWinControl.Height) then
begin
{$ifdef CD_X11_SmartPaint}
AWindowInfo.Valid:= False; // Needs full Painting
{$endif}
//SIZENORMAL, SIZEICONIC, SIZEFULLSCREEN, SIZEZOOMSHOW, SIZEZOOMHIDE.
LCLSendSizeMsg(AWinControl, Event.Width, Event.Height, SIZENORMAL);