customdrawn-android: Implements DebugLn/DebugOut and advances the painting code, painting already works inside Pascal, but not yet when using TLazCanvas

git-svn-id: trunk@33819 -
This commit is contained in:
sekelsenmat 2011-11-28 10:17:58 +00:00
parent fb4a6b3045
commit fa4d4ca971
5 changed files with 198 additions and 25 deletions

View File

@ -149,6 +149,13 @@ type
function FindWindowByXID(XWindowID: X.TWindow; out AWindowInfo: TX11WindowInfo): TWinControl;
{$endif}
{$ifdef CD_Android}
procedure AndroidDebugLn(AStr: string);
{$endif}
// For unusual implementations of DebugLn/DebugOut
public
AccumulatedStr: string;
procedure AccumulatingDebugOut(AStr: string);
protected
{function CreateThemeServices: TThemeServices; override;}
{function GetAppHandle: THandle; override;
@ -203,9 +210,9 @@ function WindowProc(Window: HWnd; Msg: UInt; WParam: Windows.WParam;
{$endif}
{$ifndef CD_Android_NATIVEAPP}
function Java_com_pascal_jnitest_AndroidJNITest_stringFromJNI(env:PJNIEnv;this:jobject):jstring; cdecl;
function Java_com_pascal_jnitest_AndroidJNITest_intFromJNI(env:PJNIEnv;this:jobject): jint; cdecl;
function Java_com_pascal_jnitest_AndroidJNITest_LCLDrawToBitmap(
function Java_com_pascal_lclproject_LCLActivity_stringFromJNI(env:PJNIEnv;this:jobject):jstring; cdecl;
function Java_com_pascal_lclproject_LCLActivity_intFromJNI(env:PJNIEnv;this:jobject): jint; cdecl;
function Java_com_pascal_lclproject_LCLActivity_LCLDrawToBitmap(
env:PJNIEnv;this:jobject; width, height: jint; abitmap: jobject): jint; cdecl;
function JNI_OnLoad(vm:PJavaVM;reserved:pointer):jint; cdecl;
procedure JNI_OnUnload(vm:PJavaVM;reserved:pointer); cdecl;

View File

@ -29,6 +29,10 @@ begin
CDWidgetSet := Self;
FTerminating := False;
// Setup DebugLn
DebugLnProc := @AndroidDebugLn;
DebugOutProc := @AccumulatingDebugOut;
BackendCreate;
end;

View File

@ -395,7 +395,7 @@ end;
const curClass:JClass=nil;
nativeCodeLoaded:JfieldID=nil;
function Java_com_pascal_jnitest_AndroidJNITest_stringFromJNI(env:PJNIEnv;this:jobject):jstring; cdecl;
function Java_com_pascal_lclproject_LCLActivity_stringFromJNI(env:PJNIEnv;this:jobject):jstring; cdecl;
var x:single;
begin
{ __android_log_write(ANDROID_LOG_INFO,'nativetest','Java_com_bero_nativetest_Main_stringFromJNI entered');
@ -405,37 +405,85 @@ begin
__android_log_write(ANDROID_LOG_INFO,'nativetest','Java_com_bero_nativetest_Main_stringFromJNI exited');}
end;
function Java_com_pascal_jnitest_AndroidJNITest_intFromJNI(env:PJNIEnv;this:jobject): jint; cdecl;
function Java_com_pascal_lclproject_LCLActivity_intFromJNI(env:PJNIEnv;this:jobject): jint; cdecl;
begin
Result := 8;
end;
function Java_com_pascal_jnitest_AndroidJNITest_LCLDrawToBitmap(
function Java_com_pascal_lclproject_LCLActivity_LCLDrawToBitmap(
env:PJNIEnv;this:jobject; width, height: jint; abitmap: jobject): jint; cdecl;
var
pixels: PCardinal;
lCurForm: TCDNonNativeForm;
struct : TPaintStruct;
lWidth, lHeight: Integer;
lBitmap, lMask: HBITMAP;
lRawImage: TRawImage;
{$IFDEF VerboseCDPaintProfiler}
lTimeStart: TDateTime;
{$ENDIF}
begin
Result := 0;
AndroidBitmap_lockPixels(env, abitmap, @pixels);
// debug info to check if we are painting
pixels[30*width+30] := $FFFFFFFF;
pixels[30*width+31] := $FFFFFFFF;
pixels[30*width+32] := $FFFFFFFF;
pixels[30*width+33] := $FFFFFFFF;
pixels[30*width+34] := $FFFFFFFF;
pixels[30*width+35] := $FFFFFFFF;
lCurForm := GetCurrentForm();
if lCurForm <> nil then
begin
{$IFDEF VerboseCDPaintProfiler}
//lTimeStart := NowUTC();
{$ENDIF}
{$IFDEF VerboseCDWindow}
//DebugLn(Format('[TCDWSCustomForm.EvPaint] AWindowInfo: %x', [PtrInt(AWindowInfo)]));
{$ENDIF}
//if (AWinControl = nil) or (AWindowInfo = nil) then Exit;
lWidth := 200;//Round(AWinControl.width);
lHeight := 200;//Round(AWinControl.height);
FillChar(struct, SizeOf(TPaintStruct), 0);
// Prepare the non-native image and canvas
UpdateControlLazImageAndCanvas(lCurForm.Image, lCurForm.Canvas, lWidth, lHeight, clfBGRA32, pixels);
struct.hdc := HDC(lCurForm.Canvas);
// Send the paint message to the LCL
{$IFDEF VerboseCDWindow}
//DebugLn(Format('[TCDWSCustomForm.EvPaint] OnPaint event started context: %x', [struct.hdc]));
{$ENDIF}
LCLSendPaintMsg(lCurForm.LCLForm, struct.hdc, @struct);
{$IFDEF VerboseCDWindow}
//DebugLn('[TCDWSCustomForm.EvPaint] OnPaint event ended');
{$ENDIF}
// Now paint all child win controls
//RenderChildWinControls(AWindowInfo.Image, AWindowInfo.Canvas,
//BackendGetCDWinControlList(TCustomForm(AWinControl)));
end;
// Now returns the bitmap buffer to LCLActivity so that it can render it
AndroidBitmap_unlockPixels(env, abitmap);
end;
const NativeMethods: array[0..2] of JNINativeMethod=
((name:'stringFromJNI';
signature:'()Ljava/lang/String;';
fnPtr:@Java_com_pascal_jnitest_AndroidJNITest_stringFromJNI;),
fnPtr:@Java_com_pascal_lclproject_LCLActivity_stringFromJNI;),
(name:'intFromJNI';
signature:'()I';
fnPtr:@Java_com_pascal_jnitest_AndroidJNITest_intFromJNI;),
fnPtr:@Java_com_pascal_lclproject_LCLActivity_intFromJNI;),
(name:'LCLDrawToBitmap';
signature:'(IILandroid/graphics/Bitmap;)I';
fnPtr:@Java_com_pascal_jnitest_AndroidJNITest_LCLDrawToBitmap;)
fnPtr:@Java_com_pascal_lclproject_LCLActivity_LCLDrawToBitmap;)
);
function JNI_OnLoad(vm:PJavaVM;reserved:pointer):jint; cdecl;
@ -449,7 +497,7 @@ begin
__android_log_write(ANDROID_LOG_INFO,'nativetest',PChar(Format('CurVM^=%x', [PtrInt(CurVM^)])));
__android_log_write(ANDROID_LOG_INFO,'nativetest',PChar(Format('CurVM^^.reserved0=%x', [PtrInt(CurVM^^.reserved0)])));
__android_log_write(ANDROID_LOG_INFO,'nativetest',PChar(Format('CurVM^^.GetEnv=%x', [PtrInt(Pointer(@CurVM^^.GetEnv))])));
if curVM^^.GetEnv(curVM,@curEnv,JNI_VERSION_1_4)<>JNI_OK then begin //<<<--- THIS CRASHES
{ if curVM^^.GetEnv(curVM,@curEnv,JNI_VERSION_1_4)<>JNI_OK then begin //<<<--- THIS CRASHES
__android_log_write(ANDROID_LOG_INFO{FATAL},'nativetest','curVM^.GetEnv failed');
// result:=JNI_ERR;
// exit;
@ -473,7 +521,7 @@ begin
__android_log_write(ANDROID_LOG_FATAL,'nativetest','curEnv^.GetFieldID failed');
result:=JNI_ERR;
exit;
end;
end; }
result:=JNI_VERSION_1_4;// 1_6?
end;
@ -484,6 +532,17 @@ end;
{$endif}
procedure TCDWidgetSet.AndroidDebugLn(AStr: string);
begin
__android_log_write(ANDROID_LOG_INFO, 'lclproject', PChar(AccumulatedStr+AStr));
AccumulatedStr := '';
end;
procedure TCDWidgetSet.AccumulatingDebugOut(AStr: string);
begin
AccumulatedStr := AccumulatedStr + AStr;
end;
{------------------------------------------------------------------------------
Method: TCDWidgetSet.Create
Params: None
@ -517,9 +576,9 @@ end;
------------------------------------------------------------------------------}
procedure TCDWidgetSet.AppInit(var ScreenInfo: TScreenInfo);
begin
{$ifdef VerboseCDApplication}
//DebugLn('TCDWidgetSet.AppInit');
{$endif}
{$ifdef VerboseCDApplication}
DebugLn('TCDWidgetSet.AppInit');
{$endif}
end;
procedure TCDWidgetSet.AppRun(const ALoop: TApplicationMainLoop);

View File

@ -26,24 +26,109 @@ type
//CDControl: TCDControl;
end;
TCDNonNativeForm = class
public
LCLForm: TCustomForm;
Children: TFPList; // of TCDWinControl;
// painting objects
Image: TLazIntfImage;
Canvas: TLazCanvas;
end;
// Routines for non-native form
procedure InitNonNativeForms();
function GetCurrentForm(): TCDNonNativeForm;
function AddNewForm(AForm: TCustomForm): TCDNonNativeForm;
procedure ShowForm(ACDForm: TCDNonNativeForm);
procedure HideForm(ACDForm: TCDNonNativeForm);
// Routines for non-native wincontrol
procedure UpdateControlLazImageAndCanvas(var AImage: TLazIntfImage;
var ACanvas: TLazCanvas; AWidth, AHeight: Integer; AFormat: TUpdateLazImageFormat);
var ACanvas: TLazCanvas; AWidth, AHeight: Integer; AFormat: TUpdateLazImageFormat;
AData: Pointer = nil);
procedure RenderChildWinControls(var AImage: TLazIntfImage;
var ACanvas: TLazCanvas; ACDControlsList: TFPList);
//procedure RenderWinControl(var AImage: TLazIntfImage;
// var ACanvas: TLazCanvas; ACDControlsList: TFPList);
function FindControlWhichReceivedEvent(AForm: TCustomForm;
AControlsList: TFPList; AX, AY: Integer): TWinControl;
// Other routines
function DateTimeToMilliseconds(aDateTime: TDateTime): Int64;
function IsValidDC(ADC: HDC): Boolean;
function IsValidGDIObject(AGDIObj: HGDIOBJ): Boolean;
implementation
// List with the Z-order of non-native forms, index=0 is the bottom-most form
var
NonNativeForms: TFPList = nil;
procedure InitNonNativeForms();
begin
if NonNativeForms <> nil then Exit;
NonNativeForms := TFPList.Create;
end;
function GetCurrentForm(): TCDNonNativeForm;
var
lCount: Integer;
begin
{$IFDEF VerboseWinAPI}
DebugLn('GetCurrentForm');
{$ENDIF}
InitNonNativeForms();
lCount := NonNativeForms.Count;
if lCount = 0 then Result := nil
else Result := TCDNonNativeForm(NonNativeForms.Items[lCount-1]);
end;
function AddNewForm(AForm: TCustomForm): TCDNonNativeForm;
var
lFormInfo: TCDNonNativeForm;
begin
{$IFDEF VerboseWinAPI}
DebugLn('AddNewForm');
{$ENDIF}
InitNonNativeForms();
lFormInfo := TCDNonNativeForm.Create;
lFormInfo.LCLForm := AForm;
lFormInfo.Children := TFPList.Create;
NonNativeForms.Insert(0, lFormInfo);
end;
procedure ShowForm(ACDForm: TCDNonNativeForm);
var
lCount, lCurIndex: Integer;
begin
{$IFDEF VerboseWinAPI}
DebugLn('ShowForm');
{$ENDIF}
InitNonNativeForms();
lCount := NonNativeForms.Count;
lCurIndex := NonNativeForms.IndexOf(ACDForm);
NonNativeForms.Move(lCurIndex, lCount-1);
end;
procedure HideForm(ACDForm: TCDNonNativeForm);
var
lCount, lCurIndex: Integer;
begin
InitNonNativeForms();
lCount := NonNativeForms.Count;
lCurIndex := NonNativeForms.IndexOf(ACDForm);
NonNativeForms.Move(lCurIndex, 0);
end;
procedure UpdateControlLazImageAndCanvas(var AImage: TLazIntfImage;
var ACanvas: TLazCanvas; AWidth, AHeight: Integer; AFormat: TUpdateLazImageFormat);
var ACanvas: TLazCanvas; AWidth, AHeight: Integer; AFormat: TUpdateLazImageFormat;
AData: Pointer = nil);
var
lRawImage: TRawImage;
lPixelSize: Byte;
begin
{$IFDEF VerboseWinAPI}
DebugLn(Format(':>[UpdateControlLazImageAndCanvas] Input Image: %x Canvas: %x',
@ -62,7 +147,22 @@ begin
clfBGR24: lRawImage.Description.Init_BPP24_B8G8R8_BIO_TTB(AWidth, AHeight);
clfBGRA32: lRawImage.Description.Init_BPP32_B8G8R8A8_BIO_TTB(AWidth, AHeight);
end;
lRawImage.CreateData(True);
// Now connect the pixel buffer or create one
if AData = nil then lRawImage.CreateData(True)
else
begin
case AFormat of
clfRGB16_R5G6B5: lPixelSize := 2;
clfRGB24: lPixelSize := 3;
clfRGB24UpsideDown: lPixelSize := 3;
clfBGR24: lPixelSize := 3;
clfBGRA32: lPixelSize := 4;
end;
lRawImage.Data := AData;
lRawImage.DataSize := AWidth * lPixelSize * AHeight;
end;
AImage := TLazIntfImage.Create(AWidth, AHeight);
AImage.SetRawImage(lRawImage);

View File

@ -33,16 +33,17 @@ var
lWindowInfo: TAndroidWindowInfo;
AForm: TCustomForm absolute AWinControl;
begin
{$ifdef VerboseCDWindow}
(* {$ifdef VerboseCDWindow}
DebugLn(Format(':>[TCDWSCustomForm.CreateHandle] AWinControl=%x Name=%s: %s',
[PtrInt(AWinControl), AWinControl.Name, AWinControl.ClassName]));
{$endif}
{$endif}*)
Result := TLCLIntfhandle(AddNewForm(TCustomForm(AWinControl)));
{$ifdef VerboseCDWindow}
(* {$ifdef VerboseCDWindow}
DebugLn(Format(':<[TCDWSCustomForm.CreateHandle] Result=%x',
[Result]));
{$endif}
{$endif}*)
end;
class procedure TCDWSCustomForm.DestroyHandle(const AWinControl: TWinControl);
@ -90,16 +91,18 @@ begin
if AWinControl.Visible then
begin
{$ifdef VerboseCDWindow}
ShowForm(TCDNonNativeForm(AWinControl.Handle));
(* {$ifdef VerboseCDWindow}
DebugLn(Format('[TCDWSCustomForm.ShowHide] Visible=True AWinControl=%x Handle=%x',
[PtrInt(AWinControl), PtrInt(AWinControl.Handle)]));
{$endif}
{$endif}*)
end
else
begin
{$ifdef VerboseCDWindow}
HideForm(TCDNonNativeForm(AWinControl.Handle));
(* {$ifdef VerboseCDWindow}
DebugLn(Format('[TCDWSCustomForm.ShowHide] Visible=False AWinControl=%x', [PtrInt(AWinControl)]));
{$endif}
{$endif}*)
end;
end;