diff --git a/lcl/interfaces/customdrawn/customdrawnlclintf_android.inc b/lcl/interfaces/customdrawn/customdrawnlclintf_android.inc
index f12fa6c474..df71f632cf 100644
--- a/lcl/interfaces/customdrawn/customdrawnlclintf_android.inc
+++ b/lcl/interfaces/customdrawn/customdrawnlclintf_android.inc
@@ -239,7 +239,7 @@ begin
javaEnvRef^^.CallVoidMethod(javaEnvRef, javaActivityObject, javaMethod_LCLDoShowMessageBox);
end;
-(*{------------------------------------------------------------------------------
+{------------------------------------------------------------------------------
Function: RawImage_FromDevice
Params: ADC:
ARect:
@@ -255,27 +255,9 @@ end;
So get this internal bitmap and pass it to RawImage_FromBitmap
------------------------------------------------------------------------------}
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
- {$ifdef VerboseQtWinAPI}
- WriteLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC),
+ {$ifdef VerboseCDWinAPI}
+ DebugLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC),
' SrcWidth: ', dbgs(ARect.Right - ARect.Left),
' SrcHeight: ', dbgs(ARect.Bottom - ARect.Top));
{$endif}
@@ -285,56 +267,7 @@ begin
Result := True;
ARawImage.Init;
- FillStandardDescription(ARawImage.Description);
- 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;*)
+end;
procedure TCDWidgetSet.ShowVirtualKeyboard;
begin
diff --git a/lcl/interfaces/customdrawn/customdrawnlclintf_cocoa.inc b/lcl/interfaces/customdrawn/customdrawnlclintf_cocoa.inc
index e237cb7193..240cef5377 100644
--- a/lcl/interfaces/customdrawn/customdrawnlclintf_cocoa.inc
+++ b/lcl/interfaces/customdrawn/customdrawnlclintf_cocoa.inc
@@ -128,7 +128,7 @@ function TCDWidgetSet.PromptUser(const DialogCaption : string;
begin
end;
-(*{------------------------------------------------------------------------------
+{------------------------------------------------------------------------------
Function: RawImage_FromDevice
Params: ADC:
ARect:
@@ -142,88 +142,64 @@ end;
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
+
+ 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
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;
-
+ screenshotImage: CGImageRef;
+ imageDataProv: CGDataProviderRef;
+ imageData: CFDataRef;
+ lBitsPerComponent, lBitsPerPixel, lBytesPerRow: size_t;
+ lDataPtr: UnivPtr;
+ lDataLength: CFIndex;
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;
ARawImage.Init;
- FillStandardDescription(ARawImage.Description);
- Context := TQtDeviceContext(ADC);
+ ARawImage.Description.Init_BPP32_B8G8R8A8_BIO_TTB(0, 0);
- with DCSize, Context.getDeviceSize do
- begin
- cx := x;
- cy := y;
- end;
+ // Take the screenshot and obtain the pixel data
+ screenshotImage := CGDisplayCreateImage(CGMainDisplayID()); // Requires 10.6+
+ imageDataProv := CGImageGetDataProvider(screenshotImage); // Requires 10.5+
+ imageData := CGDataProviderCopyData(imageDataProv);
- 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;
+ // Now read the image description and convert it to our own
+ lBitsPerComponent := CGImageGetBitsPerComponent(screenshotImage);
+ ARawImage.Description.AlphaPrec := 0;
+ ARawImage.Description.RedPrec := lBitsPerComponent;
+ ARawImage.Description.GreenPrec := lBitsPerComponent;
+ ARawImage.Description.BluePrec := lBitsPerComponent;
+ ARawImage.Description.RedShift := 0;
+ ARawImage.Description.GreenShift := 8;
+ ARawImage.Description.BlueShift := 16;
- // In this case we use the size of the context
- Desc.Width := DCSize.cx;
- Desc.Height := DCSize.cy;
+ ARawImage.Description.Width := CGImageGetWidth(screenshotImage);
+ ARawImage.Description.Height := CGImageGetHeight(screenshotImage);
- {$ifdef VerboseQtWinAPI}
- WriteLn('Trace:< [WinAPI GetRawImageFromDevice]');
- {$endif}
-end;*)
+ lBitsPerPixel := CGImageGetBitsPerPixel(screenshotImage); // For now support it will give us 32
+
+ lBytesPerRow := CGImageGetBytesPerRow(screenshotImage);
+
+ // 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();
begin
diff --git a/lcl/interfaces/customdrawn/customdrawnlclintf_win.inc b/lcl/interfaces/customdrawn/customdrawnlclintf_win.inc
index 7090ab1bb5..51cf56761c 100644
--- a/lcl/interfaces/customdrawn/customdrawnlclintf_win.inc
+++ b/lcl/interfaces/customdrawn/customdrawnlclintf_win.inc
@@ -129,7 +129,7 @@ function TCDWidgetSet.PromptUser(const DialogCaption : string;
begin
end;
-(*{------------------------------------------------------------------------------
+{------------------------------------------------------------------------------
Function: RawImage_FromDevice
Params: ADC:
ARect:
@@ -144,87 +144,12 @@ end;
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
------------------------------------------------------------------------------}
-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;
-
+function TCDWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean;
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;
ARawImage.Init;
- FillStandardDescription(ARawImage.Description);
- 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;*)
+end;
procedure TCDWidgetset.ShowVirtualKeyboard();
begin
diff --git a/lcl/interfaces/customdrawn/customdrawnlclintf_x11.inc b/lcl/interfaces/customdrawn/customdrawnlclintf_x11.inc
index c666c8d9ab..c0f8863f57 100644
--- a/lcl/interfaces/customdrawn/customdrawnlclintf_x11.inc
+++ b/lcl/interfaces/customdrawn/customdrawnlclintf_x11.inc
@@ -129,7 +129,7 @@ function TCDWidgetSet.PromptUser(const DialogCaption : string;
begin
end;
-(*{------------------------------------------------------------------------------
+{------------------------------------------------------------------------------
Function: RawImage_FromDevice
Params: ADC:
ARect:
@@ -145,27 +145,9 @@ end;
So get this internal bitmap and pass it to RawImage_FromBitmap
------------------------------------------------------------------------------}
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
- {$ifdef VerboseQtWinAPI}
- WriteLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC),
+ {$ifdef VerboseCDWinAPI}
+ DebugLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC),
' SrcWidth: ', dbgs(ARect.Right - ARect.Left),
' SrcHeight: ', dbgs(ARect.Bottom - ARect.Top));
{$endif}
@@ -175,56 +157,7 @@ begin
Result := True;
ARawImage.Init;
- FillStandardDescription(ARawImage.Description);
- 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;*)
+end;
procedure TCDWidgetset.ShowVirtualKeyboard();
begin
diff --git a/lcl/interfaces/customdrawn/customdrawnlclintfh.inc b/lcl/interfaces/customdrawn/customdrawnlclintfh.inc
index ac70b7c28a..8b7a097472 100644
--- a/lcl/interfaces/customdrawn/customdrawnlclintfh.inc
+++ b/lcl/interfaces/customdrawn/customdrawnlclintfh.inc
@@ -67,7 +67,7 @@ function RawImage_DescriptionFromBitmap(ABitmap: HBITMAP; out ADesc: TRawImageDe
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_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 ReleaseDesignerDC(Window: HWND; DC: HDC): Integer; override;
diff --git a/lcl/interfaces/lcl.lpk b/lcl/interfaces/lcl.lpk
index cb848960a6..9204d5b77f 100644
--- a/lcl/interfaces/lcl.lpk
+++ b/lcl/interfaces/lcl.lpk
@@ -114,7 +114,7 @@ end;"/>
-
+
@@ -1908,6 +1908,22 @@ end;"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+