Starts screenshot taking code in LCL-CustomDrawn-Cocoa, already works, but the colors are switched

git-svn-id: trunk@34268 -
This commit is contained in:
sekelsenmat 2011-12-19 08:36:19 +00:00
parent 2a70b1b482
commit d2c89a1ff3
6 changed files with 77 additions and 294 deletions

View File

@ -239,7 +239,7 @@ begin
javaEnvRef^^.CallVoidMethod(javaEnvRef, javaActivityObject, javaMethod_LCLDoShowMessageBox); javaEnvRef^^.CallVoidMethod(javaEnvRef, javaActivityObject, javaMethod_LCLDoShowMessageBox);
end; end;
(*{------------------------------------------------------------------------------ {------------------------------------------------------------------------------
Function: RawImage_FromDevice Function: RawImage_FromDevice
Params: ADC: Params: ADC:
ARect: ARect:
@ -255,27 +255,9 @@ end;
So get this internal bitmap and pass it to RawImage_FromBitmap So get this internal bitmap and pass it to RawImage_FromBitmap
------------------------------------------------------------------------------} ------------------------------------------------------------------------------}
function TQtWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean; function TQtWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean;
var
Desc: TRawImageDescription absolute ARawImage.Description;
//SrcWidth, SrcHeight: Integer;
WinID: Cardinal;
DCSize: TSize;
Pixmap: TQtPixmap;
Image: QImageH;
Context: TQtDeviceContext;
procedure RawImage_FromImage(AImage: QImageH);
begin
ARawImage.DataSize := QImage_numBytes(AImage);
ARawImage.Data := GetMem(ARawImage.DataSize);
Move(QImage_bits(AImage)^, ARawImage.Data^, ARawImage.DataSize);
ARawImage.Mask := nil;
end;
begin begin
{$ifdef VerboseQtWinAPI} {$ifdef VerboseCDWinAPI}
WriteLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC), DebugLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC),
' SrcWidth: ', dbgs(ARect.Right - ARect.Left), ' SrcWidth: ', dbgs(ARect.Right - ARect.Left),
' SrcHeight: ', dbgs(ARect.Bottom - ARect.Top)); ' SrcHeight: ', dbgs(ARect.Bottom - ARect.Top));
{$endif} {$endif}
@ -285,56 +267,7 @@ begin
Result := True; Result := True;
ARawImage.Init; ARawImage.Init;
FillStandardDescription(ARawImage.Description); end;
Context := TQtDeviceContext(ADC);
with DCSize, Context.getDeviceSize do
begin
cx := x;
cy := y;
end;
if Context.Parent <> nil then
begin
Pixmap := TQtPixmap.Create(@DCSize);
WinID := QWidget_winId(Context.Parent);
try
// if you have dual monitors then getDeviceSize return
// more width than screen width, but grabWindow will only grab one
// screen, so its width will be less
// Solution: we can either pass prefered size to grabWindow or
// correct Description size after. I see the first solution as more correct.
Pixmap.grabWindow(WinID, 0, 0, DCSize.cx, DCSize.cy);
Image := QImage_Create;
Pixmap.toImage(Image);
RawImage_FromImage(Image);
QImage_destroy(Image);
finally
Pixmap.Free;
end;
end else
begin
if Context.vImage <> nil then
RawImage_FromImage(Context.vImage.FHandle)
else
if Context.ParentPixmap <> nil then
begin
Image := QImage_create();
QPixmap_toImage(Context.ParentPixmap, Image);
RawImage_FromImage(Image);
QImage_destroy(Image);
end else
Result := False;
end;
// In this case we use the size of the context
Desc.Width := DCSize.cx;
Desc.Height := DCSize.cy;
{$ifdef VerboseQtWinAPI}
WriteLn('Trace:< [WinAPI GetRawImageFromDevice]');
{$endif}
end;*)
procedure TCDWidgetSet.ShowVirtualKeyboard; procedure TCDWidgetSet.ShowVirtualKeyboard;
begin begin

View File

@ -128,7 +128,7 @@ function TCDWidgetSet.PromptUser(const DialogCaption : string;
begin begin
end; end;
(*{------------------------------------------------------------------------------ {------------------------------------------------------------------------------
Function: RawImage_FromDevice Function: RawImage_FromDevice
Params: ADC: Params: ADC:
ARect: ARect:
@ -142,88 +142,64 @@ end;
MWE: exept for the desktop, there is always a bitmep selected in the DC. MWE: exept for the desktop, there is always a bitmep selected in the DC.
So get this internal bitmap and pass it to RawImage_FromBitmap So get this internal bitmap and pass it to RawImage_FromBitmap
Reference documentation:
Technical Q&A QA1509 Getting the pixel data from a CGImage object
http://developer.apple.com/library/mac/#qa/qa1509/_index.html
CGDisplayCreateImage
http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/Quartz_Services_Ref/Reference/reference.html
http://lists.apple.com/archives/cocoa-dev/2011/Feb/msg00704.html
CFDataRef
http://developer.apple.com/library/ios/#DOCUMENTATION/CoreFoundation/Reference/CFDataRef/Reference/reference.html
------------------------------------------------------------------------------} ------------------------------------------------------------------------------}
function TQtWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean; function TCDWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean;
var var
Desc: TRawImageDescription absolute ARawImage.Description; Desc: TRawImageDescription absolute ARawImage.Description;
screenshotImage: CGImageRef;
//SrcWidth, SrcHeight: Integer; imageDataProv: CGDataProviderRef;
WinID: Cardinal; imageData: CFDataRef;
DCSize: TSize; lBitsPerComponent, lBitsPerPixel, lBytesPerRow: size_t;
Pixmap: TQtPixmap; lDataPtr: UnivPtr;
Image: QImageH; lDataLength: CFIndex;
Context: TQtDeviceContext;
procedure RawImage_FromImage(AImage: QImageH);
begin
ARawImage.DataSize := QImage_numBytes(AImage);
ARawImage.Data := GetMem(ARawImage.DataSize);
Move(QImage_bits(AImage)^, ARawImage.Data^, ARawImage.DataSize);
ARawImage.Mask := nil;
end;
begin begin
{$ifdef VerboseQtWinAPI}
WriteLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC),
' SrcWidth: ', dbgs(ARect.Right - ARect.Left),
' SrcHeight: ', dbgs(ARect.Bottom - ARect.Top));
{$endif}
// todo: copy only passed rectangle
Result := True; Result := True;
ARawImage.Init; ARawImage.Init;
FillStandardDescription(ARawImage.Description); ARawImage.Description.Init_BPP32_B8G8R8A8_BIO_TTB(0, 0);
Context := TQtDeviceContext(ADC);
with DCSize, Context.getDeviceSize do // Take the screenshot and obtain the pixel data
begin screenshotImage := CGDisplayCreateImage(CGMainDisplayID()); // Requires 10.6+
cx := x; imageDataProv := CGImageGetDataProvider(screenshotImage); // Requires 10.5+
cy := y; imageData := CGDataProviderCopyData(imageDataProv);
end;
if Context.Parent <> nil then // Now read the image description and convert it to our own
begin lBitsPerComponent := CGImageGetBitsPerComponent(screenshotImage);
Pixmap := TQtPixmap.Create(@DCSize); ARawImage.Description.AlphaPrec := 0;
WinID := QWidget_winId(Context.Parent); ARawImage.Description.RedPrec := lBitsPerComponent;
try ARawImage.Description.GreenPrec := lBitsPerComponent;
// if you have dual monitors then getDeviceSize return ARawImage.Description.BluePrec := lBitsPerComponent;
// more width than screen width, but grabWindow will only grab one ARawImage.Description.RedShift := 0;
// screen, so its width will be less ARawImage.Description.GreenShift := 8;
// Solution: we can either pass prefered size to grabWindow or ARawImage.Description.BlueShift := 16;
// correct Description size after. I see the first solution as more correct.
Pixmap.grabWindow(WinID, 0, 0, DCSize.cx, DCSize.cy);
Image := QImage_Create;
Pixmap.toImage(Image);
RawImage_FromImage(Image);
QImage_destroy(Image);
finally
Pixmap.Free;
end;
end else
begin
if Context.vImage <> nil then
RawImage_FromImage(Context.vImage.FHandle)
else
if Context.ParentPixmap <> nil then
begin
Image := QImage_create();
QPixmap_toImage(Context.ParentPixmap, Image);
RawImage_FromImage(Image);
QImage_destroy(Image);
end else
Result := False;
end;
// In this case we use the size of the context ARawImage.Description.Width := CGImageGetWidth(screenshotImage);
Desc.Width := DCSize.cx; ARawImage.Description.Height := CGImageGetHeight(screenshotImage);
Desc.Height := DCSize.cy;
{$ifdef VerboseQtWinAPI} lBitsPerPixel := CGImageGetBitsPerPixel(screenshotImage); // For now support it will give us 32
WriteLn('Trace:< [WinAPI GetRawImageFromDevice]');
{$endif} lBytesPerRow := CGImageGetBytesPerRow(screenshotImage);
end;*)
// Now copy the data
lDataPtr := CFDataGetBytePtr(imageData);
lDataLength := CFDataGetLength(imageData);
ARawImage.CreateData(False);
lDataLength := Min(lDataLength, ARawImage.DataSize);
System.Move(lDataPtr^, ARawImage.Data^, lDataLength);
end;
procedure TCDWidgetset.ShowVirtualKeyboard(); procedure TCDWidgetset.ShowVirtualKeyboard();
begin begin

View File

@ -129,7 +129,7 @@ function TCDWidgetSet.PromptUser(const DialogCaption : string;
begin begin
end; end;
(*{------------------------------------------------------------------------------ {------------------------------------------------------------------------------
Function: RawImage_FromDevice Function: RawImage_FromDevice
Params: ADC: Params: ADC:
ARect: ARect:
@ -144,87 +144,12 @@ end;
MWE: exept for the desktop, there is always a bitmep selected in the DC. MWE: exept for the desktop, there is always a bitmep selected in the DC.
So get this internal bitmap and pass it to RawImage_FromBitmap So get this internal bitmap and pass it to RawImage_FromBitmap
------------------------------------------------------------------------------} ------------------------------------------------------------------------------}
function TQtWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean; function TCDWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean;
var
Desc: TRawImageDescription absolute ARawImage.Description;
//SrcWidth, SrcHeight: Integer;
WinID: Cardinal;
DCSize: TSize;
Pixmap: TQtPixmap;
Image: QImageH;
Context: TQtDeviceContext;
procedure RawImage_FromImage(AImage: QImageH);
begin
ARawImage.DataSize := QImage_numBytes(AImage);
ARawImage.Data := GetMem(ARawImage.DataSize);
Move(QImage_bits(AImage)^, ARawImage.Data^, ARawImage.DataSize);
ARawImage.Mask := nil;
end;
begin begin
{$ifdef VerboseQtWinAPI}
WriteLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC),
' SrcWidth: ', dbgs(ARect.Right - ARect.Left),
' SrcHeight: ', dbgs(ARect.Bottom - ARect.Top));
{$endif}
// todo: copy only passed rectangle
Result := True; Result := True;
ARawImage.Init; ARawImage.Init;
FillStandardDescription(ARawImage.Description); end;
Context := TQtDeviceContext(ADC);
with DCSize, Context.getDeviceSize do
begin
cx := x;
cy := y;
end;
if Context.Parent <> nil then
begin
Pixmap := TQtPixmap.Create(@DCSize);
WinID := QWidget_winId(Context.Parent);
try
// if you have dual monitors then getDeviceSize return
// more width than screen width, but grabWindow will only grab one
// screen, so its width will be less
// Solution: we can either pass prefered size to grabWindow or
// correct Description size after. I see the first solution as more correct.
Pixmap.grabWindow(WinID, 0, 0, DCSize.cx, DCSize.cy);
Image := QImage_Create;
Pixmap.toImage(Image);
RawImage_FromImage(Image);
QImage_destroy(Image);
finally
Pixmap.Free;
end;
end else
begin
if Context.vImage <> nil then
RawImage_FromImage(Context.vImage.FHandle)
else
if Context.ParentPixmap <> nil then
begin
Image := QImage_create();
QPixmap_toImage(Context.ParentPixmap, Image);
RawImage_FromImage(Image);
QImage_destroy(Image);
end else
Result := False;
end;
// In this case we use the size of the context
Desc.Width := DCSize.cx;
Desc.Height := DCSize.cy;
{$ifdef VerboseQtWinAPI}
WriteLn('Trace:< [WinAPI GetRawImageFromDevice]');
{$endif}
end;*)
procedure TCDWidgetset.ShowVirtualKeyboard(); procedure TCDWidgetset.ShowVirtualKeyboard();
begin begin

View File

@ -129,7 +129,7 @@ function TCDWidgetSet.PromptUser(const DialogCaption : string;
begin begin
end; end;
(*{------------------------------------------------------------------------------ {------------------------------------------------------------------------------
Function: RawImage_FromDevice Function: RawImage_FromDevice
Params: ADC: Params: ADC:
ARect: ARect:
@ -145,27 +145,9 @@ end;
So get this internal bitmap and pass it to RawImage_FromBitmap So get this internal bitmap and pass it to RawImage_FromBitmap
------------------------------------------------------------------------------} ------------------------------------------------------------------------------}
function TCDWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean; function TCDWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean;
var
Desc: TRawImageDescription absolute ARawImage.Description;
//SrcWidth, SrcHeight: Integer;
WinID: Cardinal;
DCSize: TSize;
Pixmap: TQtPixmap;
Image: QImageH;
Context: TQtDeviceContext;
procedure RawImage_FromImage(AImage: QImageH);
begin
ARawImage.DataSize := QImage_numBytes(AImage);
ARawImage.Data := GetMem(ARawImage.DataSize);
Move(QImage_bits(AImage)^, ARawImage.Data^, ARawImage.DataSize);
ARawImage.Mask := nil;
end;
begin begin
{$ifdef VerboseQtWinAPI} {$ifdef VerboseCDWinAPI}
WriteLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC), DebugLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC),
' SrcWidth: ', dbgs(ARect.Right - ARect.Left), ' SrcWidth: ', dbgs(ARect.Right - ARect.Left),
' SrcHeight: ', dbgs(ARect.Bottom - ARect.Top)); ' SrcHeight: ', dbgs(ARect.Bottom - ARect.Top));
{$endif} {$endif}
@ -175,56 +157,7 @@ begin
Result := True; Result := True;
ARawImage.Init; ARawImage.Init;
FillStandardDescription(ARawImage.Description); end;
Context := TQtDeviceContext(ADC);
with DCSize, Context.getDeviceSize do
begin
cx := x;
cy := y;
end;
if Context.Parent <> nil then
begin
Pixmap := TQtPixmap.Create(@DCSize);
WinID := QWidget_winId(Context.Parent);
try
// if you have dual monitors then getDeviceSize return
// more width than screen width, but grabWindow will only grab one
// screen, so its width will be less
// Solution: we can either pass prefered size to grabWindow or
// correct Description size after. I see the first solution as more correct.
Pixmap.grabWindow(WinID, 0, 0, DCSize.cx, DCSize.cy);
Image := QImage_Create;
Pixmap.toImage(Image);
RawImage_FromImage(Image);
QImage_destroy(Image);
finally
Pixmap.Free;
end;
end else
begin
if Context.vImage <> nil then
RawImage_FromImage(Context.vImage.FHandle)
else
if Context.ParentPixmap <> nil then
begin
Image := QImage_create();
QPixmap_toImage(Context.ParentPixmap, Image);
RawImage_FromImage(Image);
QImage_destroy(Image);
end else
Result := False;
end;
// In this case we use the size of the context
Desc.Width := DCSize.cx;
Desc.Height := DCSize.cy;
{$ifdef VerboseQtWinAPI}
WriteLn('Trace:< [WinAPI GetRawImageFromDevice]');
{$endif}
end;*)
procedure TCDWidgetset.ShowVirtualKeyboard(); procedure TCDWidgetset.ShowVirtualKeyboard();
begin begin

View File

@ -67,7 +67,7 @@ function RawImage_DescriptionFromBitmap(ABitmap: HBITMAP; out ADesc: TRawImageDe
function RawImage_DescriptionFromDevice(ADC: HDC; out ADesc: TRawImageDescription): Boolean; override; function RawImage_DescriptionFromDevice(ADC: HDC; out ADesc: TRawImageDescription): Boolean; override;
function RawImage_FromBitmap(out ARawImage: TRawImage; ABitmap, AMask: HBITMAP; ARect: PRect = nil): Boolean; override; function RawImage_FromBitmap(out ARawImage: TRawImage; ABitmap, AMask: HBITMAP; ARect: PRect = nil): Boolean; override;
//function RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean; override; function RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean; override;
function RawImage_QueryDescription(AFlags: TRawImageQueryFlags; var ADesc: TRawImageDescription): Boolean; override; function RawImage_QueryDescription(AFlags: TRawImageQueryFlags; var ADesc: TRawImageDescription): Boolean; override;
(*function ReleaseDesignerDC(Window: HWND; DC: HDC): Integer; override; (*function ReleaseDesignerDC(Window: HWND; DC: HDC): Integer; override;

View File

@ -114,7 +114,7 @@ end;"/>
<License Value="modified LGPL-2 <License Value="modified LGPL-2
"/> "/>
<Version Major="1" Release="1"/> <Version Major="1" Release="1"/>
<Files Count="384"> <Files Count="388">
<Item1> <Item1>
<Filename Value="carbon/agl.pp"/> <Filename Value="carbon/agl.pp"/>
<AddToUsesPkgSection Value="False"/> <AddToUsesPkgSection Value="False"/>
@ -1908,6 +1908,22 @@ end;"/>
<AddToUsesPkgSection Value="False"/> <AddToUsesPkgSection Value="False"/>
<UnitName Value="customdrawnprivate"/> <UnitName Value="customdrawnprivate"/>
</Item384> </Item384>
<Item385>
<Filename Value="customdrawn/customdrawnlclintf_android.inc"/>
<Type Value="Include"/>
</Item385>
<Item386>
<Filename Value="customdrawn/customdrawnlclintf_cocoa.inc"/>
<Type Value="Include"/>
</Item386>
<Item387>
<Filename Value="customdrawn/customdrawnlclintf_win.inc"/>
<Type Value="Include"/>
</Item387>
<Item388>
<Filename Value="customdrawn/customdrawnlclintf_x11.inc"/>
<Type Value="Include"/>
</Item388>
</Files> </Files>
<LazDoc Paths="../../docs/xml/lcl"/> <LazDoc Paths="../../docs/xml/lcl"/>
<i18n> <i18n>