Skip to content

Commit

Permalink
Added support for getScreenInfo() which is required to support retina.
Browse files Browse the repository at this point in the history
  • Loading branch information
shannah committed Jul 10, 2020
1 parent 715f040 commit f338679
Show file tree
Hide file tree
Showing 11 changed files with 277 additions and 0 deletions.
34 changes: 34 additions & 0 deletions build-for-cn1.sh
@@ -0,0 +1,34 @@
#!/bin/sh
# Based on build instructions at https://bitbucket.org/chromiumembedded/java-cef/wiki/BranchesAndBuilding
# Based on bundle structure described here https://bitbucket.org/chromiumembedded/java-cef/issues/109/linux-mac-fix-discovery-of-icudtldat

set -e
if [ ! -d jcef_build ]; then
mkdir jcef_build
fi
cd jcef_build
cmake -G "Xcode" -DPROJECT_ARCH="x86_64" ..

if [ "$1" == "clean" ]; then
xcodebuild -project jcef.xcodeproj -configuration Release clean
fi
xcodebuild -project jcef.xcodeproj -configuration Release
cd native/Release
CEFROOT=~/.codenameone/cef
if [ -d $CEFROOT ]; then
echo "$CEFROOT already exists.\n"
exit 1
fi

mkdir $CEFROOT
if [ ! -d $CEFROOT/macos64 ]; then
mkdir $CEFROOT/macos64;
fi
cp -r "jcef_app.app/Contents/Frameworks/Chromium Embedded Framework.framework" $CEFROOT/macos64/
cp -r "jcef Helper.app" $CEFROOT/macos64/
cp -r "jcef Helper (GPU).app" $CEFROOT/macos64/
cp -r "jcef Helper (Plugin).app" $CEFROOT/macos64/
cp -r "jcef Helper (Renderer).app" $CEFROOT/macos64/
cp *.dylib $CEFROOT/macos64/
cp *.jar $CEFROOT/

6 changes: 6 additions & 0 deletions java/org/cef/CefClient.java
Expand Up @@ -57,6 +57,7 @@
import java.util.Vector;

import javax.swing.SwingUtilities;
import org.cef.handler.CefScreenInfo;

/**
* Client that owns a browser and renderer.
Expand Down Expand Up @@ -784,4 +785,9 @@ public void onMouseEvent(
if (realHandler != null)
realHandler.onMouseEvent(browser, event, screenX, screenY, modifier, button);
}

@Override
public boolean getScreenInfo(CefBrowser arg0, CefScreenInfo arg1) {
return false;
}
}
6 changes: 6 additions & 0 deletions java/org/cef/browser/CefBrowserOsr.java
Expand Up @@ -35,6 +35,7 @@

import javax.swing.MenuSelectionManager;
import javax.swing.SwingUtilities;
import org.cef.handler.CefScreenInfo;

/**
* This class represents an off-screen rendered browser.
Expand Down Expand Up @@ -307,4 +308,9 @@ private void createBrowserIfRequired(boolean hasParent) {
setFocus(true);
}
}

@Override
public boolean getScreenInfo(CefBrowser browser, CefScreenInfo screenInfo) {
return false;
}
}
9 changes: 9 additions & 0 deletions java/org/cef/handler/CefRenderHandler.java
Expand Up @@ -22,6 +22,15 @@ public interface CefRenderHandler {
* @return The view rectangle.
*/
public Rectangle getViewRect(CefBrowser browser);

/**
* Retrieve the screen info.
* @param browser The browser generating the event.
* @param screenInfo The screenInfo
* @return True if this callback was handled. False to fallback to defaults.
*/
public boolean getScreenInfo(CefBrowser browser, CefScreenInfo screenInfo);

/**
* Retrieve the screen point for the specified view point.
* @param browser The browser generating the event.
Expand Down
5 changes: 5 additions & 0 deletions java/org/cef/handler/CefRenderHandlerAdapter.java
Expand Up @@ -27,6 +27,11 @@ public Rectangle getViewRect(CefBrowser browser) {
return new Rectangle(0, 0, 0, 0);
}

@Override
public boolean getScreenInfo(CefBrowser browser, CefScreenInfo screenInfo) {
return false;
}

@Override
public Point getScreenPoint(CefBrowser browser, Point viewPoint) {
return new Point(0, 0);
Expand Down
43 changes: 43 additions & 0 deletions java/org/cef/handler/CefScreenInfo.java
@@ -0,0 +1,43 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.cef.handler;

import java.awt.Rectangle;

/**
*
* @author shannah
*/
public class CefScreenInfo {
public double device_scale_factor;
public int depth;
public int depth_per_component;
public boolean is_monochrome;
public int x, y, width, height;
public int available_x, available_y, available_width, available_height;


public void Set(double device_scale_factor,
int depth,
int depth_per_component,
boolean is_monochrome,
Rectangle rect,
Rectangle availableRect) {
this.device_scale_factor = device_scale_factor;
this.depth= depth;
this.depth_per_component = depth_per_component;
this.is_monochrome = is_monochrome;
this.x = rect.x;
this.y = rect.y;
this.width = rect.width;
this.height = rect.height;
this.available_x = availableRect.x;
this.available_y = availableRect.y;
this.available_width = availableRect.width;
this.available_height = availableRect.height;
}

}
15 changes: 15 additions & 0 deletions native/jni_scoped_helpers.h
Expand Up @@ -882,6 +882,21 @@ class ScopedJNIStringRef : public ScopedJNIBase<jobject> {
} \
}

#define JNI_CALL_BOOLEAN_METHOD(out, env, obj, method, sig, ...) \
{ \
if (env && obj) { \
ScopedJNIClass _cls(env, env->GetObjectClass(obj)); \
jmethodID _methodId = env->GetMethodID(_cls, method, sig); \
if (_methodId != NULL) { \
out = env->CallBooleanMethod(obj, _methodId, ##__VA_ARGS__); \
} \
if (env->ExceptionOccurred()) { \
env->ExceptionDescribe(); \
env->ExceptionClear(); \
} \
} \
}

// Set the CEF base object for an existing JNI object. A reference will be
// added to the base object. If a previous base object existed a reference
// will be removed from that object.
Expand Down
30 changes: 30 additions & 0 deletions native/jni_util.cpp
Expand Up @@ -846,6 +846,8 @@ bool GetJNIFieldInt(JNIEnv* env,
return false;
}



bool GetJNIFieldLong(JNIEnv* env,
jclass cls,
jobject obj,
Expand Down Expand Up @@ -874,6 +876,34 @@ bool SetJNIFieldInt(JNIEnv* env,
return false;
}

bool SetJNIFieldDouble(JNIEnv* env,
jclass cls,
jobject obj,
const char* field_name,
double value) {
jfieldID field = env->GetFieldID(cls, field_name, "D");
if (field) {
env->SetDoubleField(obj, field, value);
return true;
}
env->ExceptionClear();
return false;
}

bool SetJNIFieldBoolean(JNIEnv* env,
jclass cls,
jobject obj,
const char* field_name,
int value) {
jfieldID field = env->GetFieldID(cls, field_name, "Z");
if (field) {
env->SetBooleanField(obj, field, value == 0 ? 0 : 1);
return true;
}
env->ExceptionClear();
return false;
}

bool GetJNIFieldStaticInt(JNIEnv* env,
jclass cls,
const char* field_name,
Expand Down
16 changes: 16 additions & 0 deletions native/jni_util.h
Expand Up @@ -125,6 +125,12 @@ bool GetJNIFieldInt(JNIEnv* env,
const char* field_name,
int* value);

bool GetJNIFieldDouble(JNIEnv* env,
jclass cls,
jobject obj,
const char* field_name,
double* value);

// Retrieve the long value stored in the |field_name| field of |cls|.
bool GetJNIFieldLong(JNIEnv* env,
jclass cls,
Expand All @@ -138,6 +144,16 @@ bool SetJNIFieldInt(JNIEnv* env,
jobject obj,
const char* field_name,
int value);
bool SetJNIFieldDouble(JNIEnv* env,
jclass cls,
jobject obj,
const char* field_name,
double value);
bool SetJNIFieldBoolean(JNIEnv* env,
jclass cls,
jobject obj,
const char* field_name,
int value);

// Retrieve the static int value stored in the |field_name| field of |cls|.
bool GetJNIFieldStaticInt(JNIEnv* env,
Expand Down
109 changes: 109 additions & 0 deletions native/render_handler.cpp
Expand Up @@ -28,6 +28,73 @@ jobject NewJNIRect(JNIEnv* env, const CefRect& rect) {

return NULL;
}

jobject NewJNIScreenInfo(JNIEnv* env, CefScreenInfo& screenInfo) {
ScopedJNIClass cls(env, "org/cef/handler/CefScreenInfo");
if (!cls) {
return NULL;
}

ScopedJNIObjectLocal obj(env, NewJNIObject(env, cls));
if (!obj) {
return NULL;
}


if (SetJNIFieldDouble(env, cls, obj, "device_scale_factor", (double)screenInfo.device_scale_factor) &&
SetJNIFieldInt(env, cls, obj, "depth", screenInfo.depth) &&
SetJNIFieldInt(env, cls, obj, "depth_per_component", screenInfo.depth_per_component) &&
SetJNIFieldBoolean(env, cls, obj, "is_monochrome", screenInfo.is_monochrome) &&
SetJNIFieldInt(env, cls, obj, "x", screenInfo.rect.x) &&
SetJNIFieldInt(env, cls, obj, "y", screenInfo.rect.y) &&
SetJNIFieldInt(env, cls, obj, "width", screenInfo.rect.width) &&
SetJNIFieldInt(env, cls, obj, "height", screenInfo.rect.height) &&
SetJNIFieldInt(env, cls, obj, "available_x", screenInfo.available_rect.x) &&
SetJNIFieldInt(env, cls, obj, "available_y", screenInfo.available_rect.y) &&
SetJNIFieldInt(env, cls, obj, "available_width", screenInfo.available_rect.width) &&
SetJNIFieldInt(env, cls, obj, "available_height", screenInfo.available_rect.height)) {
return obj.Release();
}

return NULL;

}

bool GetJNIScreenInfo(JNIEnv* env, jobject jScreenInfo, CefScreenInfo& dest) {
ScopedJNIClass cls(env, "org/cef/handler/CefScreenInfo");
if (!cls) {
return false;
}

ScopedJNIObjectLocal obj(env, jScreenInfo);
if (!obj) {
return false;
}
double tmp;
if (!GetJNIFieldDouble(env, cls, obj, "device_scale_factor", &tmp)) {
return false;
}
dest.device_scale_factor = (float)tmp;

if (GetJNIFieldInt(env, cls, obj, "depth", &(dest.depth)) &&
GetJNIFieldInt(env, cls, obj, "depth_per_component", &(dest.depth_per_component)) &&
GetJNIFieldBoolean(env, cls, obj, "is_monochrome", &(dest.is_monochrome)) &&
GetJNIFieldInt(env, cls, obj, "x", &(dest.rect.x)) &&
GetJNIFieldInt(env, cls, obj, "y", &(dest.rect.y)) &&
GetJNIFieldInt(env, cls, obj, "width", &(dest.rect.width)) &&
GetJNIFieldInt(env, cls, obj, "height", &(dest.rect.height)) &&
GetJNIFieldInt(env, cls, obj, "available_x", &(dest.available_rect.x)) &&
GetJNIFieldInt(env, cls, obj, "available_y", &(dest.available_rect.y)) &&
GetJNIFieldInt(env, cls, obj, "available_width", &(dest.available_rect.width)) &&
GetJNIFieldInt(env, cls, obj, "available_height", &(dest.available_rect.height))

) {
return true;
} else {
return false;
}

}

// create a new array of java.awt.Rectangle.
jobjectArray NewJNIRectArray(JNIEnv* env, const std::vector<CefRect>& vals) {
Expand Down Expand Up @@ -150,6 +217,48 @@ void RenderHandler::GetViewRect(CefRefPtr<CefBrowser> browser, CefRect& rect) {
}
}

///
// Called to allow the client to fill in the CefScreenInfo object with
// appropriate values. Return true if the |screen_info| structure has been
// modified.
//
// If the screen info rectangle is left empty the rectangle from GetViewRect
// will be used. If the rectangle is still empty or invalid popups may not be
// drawn correctly.
///
/*--cef()--*/
bool RenderHandler::GetScreenInfo(CefRefPtr<CefBrowser> browser,
CefScreenInfo& screen_info) {

ScopedJNIEnv env;
if (!env) {

return false;
}

ScopedJNIObjectLocal jScreenInfo(env, NewJNIScreenInfo(env, screen_info));
if (!jScreenInfo) {

return false;
}
ScopedJNIBrowser jbrowser(env, browser);
jboolean jresult=0;


JNI_CALL_BOOLEAN_METHOD(jresult, env, jbrowser.get(), "getScreenInfo", "(Lorg/cef/browser/CefBrowser;Lorg/cef/handler/CefScreenInfo;)Z",
jbrowser.get(),
jScreenInfo.get());

if (jresult) {
if (GetJNIScreenInfo(env, jScreenInfo.get(), screen_info)) {
return true;
}
}

return false;

}

bool RenderHandler::GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewX,
int viewY,
Expand Down
4 changes: 4 additions & 0 deletions native/render_handler.h
Expand Up @@ -22,6 +22,10 @@ class RenderHandler : public CefRenderHandler {
CefRect& rect) OVERRIDE;
virtual void GetViewRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) OVERRIDE;

virtual bool GetScreenInfo(CefRefPtr<CefBrowser> browser,
CefScreenInfo& screen_info) OVERRIDE;

virtual bool GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewX,
int viewY,
Expand Down

0 comments on commit f338679

Please sign in to comment.