Skip to content
Commits on Source (3)
2019-??-??: Version 1.2.0
- Add functions to list and read BD-ROM files.
- Add support for separate key pressed / typed / released user input events.
- Add support for AWT mouse events (BD-J).
2019-06-07: Version 1.1.2
- Add libxml version to pkg-config Requires.private.
......
......@@ -486,7 +486,7 @@ static int _can_read_file(const char *fn)
return 0;
}
void bdj_storage_cleanup(BDJ_STORAGE *p)
void bdj_config_cleanup(BDJ_CONFIG *p)
{
X_FREE(p->cache_root);
X_FREE(p->persistent_root);
......@@ -587,7 +587,7 @@ static char *_find_libbluray_jar1(const char *jar0)
return jar1;
}
static int _find_libbluray_jar(BDJ_STORAGE *storage)
static int _find_libbluray_jar(BDJ_CONFIG *storage)
{
if (!storage->classpath[0]) {
storage->classpath[0] = _find_libbluray_jar0();
......@@ -607,7 +607,7 @@ static int _find_libbluray_jar(BDJ_STORAGE *storage)
return !!storage->classpath[0];
}
static const char *_bdj_persistent_root(BDJ_STORAGE *storage)
static const char *_bdj_persistent_root(BDJ_CONFIG *storage)
{
const char *root;
char *data_home;
......@@ -638,7 +638,7 @@ static const char *_bdj_persistent_root(BDJ_STORAGE *storage)
return storage->persistent_root;
}
static const char *_bdj_buda_root(BDJ_STORAGE *storage)
static const char *_bdj_buda_root(BDJ_CONFIG *storage)
{
const char *root;
char *cache_home;
......@@ -696,7 +696,7 @@ static int _get_method(JNIEnv *env, jclass *cls, jmethodID *method_id,
}
static int _bdj_init(JNIEnv *env, struct bluray *bd, const char *disc_root, const char *bdj_disc_id,
BDJ_STORAGE *storage)
BDJ_CONFIG *storage)
{
if (!bdj_register_native_methods(env)) {
BD_DEBUG(DBG_BDJ | DBG_CRIT, "Couldn't register native methods.\n");
......@@ -738,7 +738,7 @@ static int _bdj_init(JNIEnv *env, struct bluray *bd, const char *disc_root, cons
return 1;
}
int bdj_jvm_available(BDJ_STORAGE *storage)
int bdj_jvm_available(BDJ_CONFIG *storage)
{
const char *java_home;
void* jvm_lib = _load_jvm(&java_home);
......@@ -964,11 +964,11 @@ static int _create_jvm(void *jvm_lib, const char *java_home, const char *jar_fil
}
BDJAVA* bdj_open(const char *path, struct bluray *bd,
const char *bdj_disc_id, BDJ_STORAGE *storage)
const char *bdj_disc_id, BDJ_CONFIG *cfg)
{
BD_DEBUG(DBG_BDJ, "bdj_open()\n");
if (!_find_libbluray_jar(storage)) {
if (!_find_libbluray_jar(cfg)) {
BD_DEBUG(DBG_BDJ | DBG_CRIT, "BD-J start failed: " BDJ_JARFILE " not found.\n");
return NULL;
}
......@@ -1000,7 +1000,7 @@ BDJAVA* bdj_open(const char *path, struct bluray *bd,
JNIEnv* env = NULL;
JavaVM *jvm = NULL;
const char *jar[2] = { storage->classpath[0], storage->classpath[1] };
const char *jar[2] = { cfg->classpath[0], cfg->classpath[1] };
if (!_find_jvm(jvm_lib, &env, &jvm) &&
!_create_jvm(jvm_lib, java_home, jar, &env, &jvm)) {
......@@ -1020,7 +1020,7 @@ BDJAVA* bdj_open(const char *path, struct bluray *bd,
BD_DEBUG(DBG_BDJ, "Java version: %d.%d\n", version >> 16, version & 0xffff);
}
if (!_bdj_init(env, bd, path, bdj_disc_id, storage)) {
if (!_bdj_init(env, bd, path, bdj_disc_id, cfg)) {
bdj_close(bdjava);
return NULL;
}
......
......@@ -70,14 +70,14 @@ typedef struct {
char *classpath[2]; /* BD-J implementation class path (location of libbluray.jar) */
uint8_t no_persistent_storage; /* disable persistent storage (remove files at close) */
} BDJ_STORAGE;
} BDJ_CONFIG;
typedef struct bdjava_s BDJAVA;
struct bluray;
BD_PRIVATE BDJAVA* bdj_open(const char *path, struct bluray *bd,
const char *bdj_disc_id, BDJ_STORAGE *storage);
const char *bdj_disc_id, BDJ_CONFIG *storage);
BD_PRIVATE void bdj_close(BDJAVA *bdjava);
BD_PRIVATE int bdj_process_event(BDJAVA *bdjava, unsigned ev, unsigned param);
......@@ -87,8 +87,8 @@ enum {
BDJ_CHECK_NO_JAR = 2,
};
BD_PRIVATE int bdj_jvm_available(BDJ_STORAGE *storage); /* rreturn: BDJ_CHECK_* */
BD_PRIVATE int bdj_jvm_available(BDJ_CONFIG *storage); /* rreturn: BDJ_CHECK_* */
BD_PRIVATE void bdj_storage_cleanup(BDJ_STORAGE *);
BD_PRIVATE void bdj_config_cleanup(BDJ_CONFIG *);
#endif
......@@ -22,6 +22,9 @@ package java.awt;
import java.awt.event.InvocationEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import org.videolan.Logger;
public class BDJHelper {
......@@ -62,20 +65,60 @@ public class BDJHelper {
} catch (InterruptedException e) {
}
if (t.isAlive()) {
org.videolan.Logger.getLogger("BDRootWindow").error("stopEventQueue() failed for " + t);
logger.error("stopEventQueue() failed for " + t);
org.videolan.PortingHelper.stopThread(t);
}
}
}
/*
* Mouse events
*/
private static int mouseX = 0, mouseY = 0, mouseMask = 0;
public static boolean postMouseEvent(int x, int y) {
return false;
mouseX = x;
mouseY = y;
return postMouseEventImpl(MouseEvent.MOUSE_MOVED, MouseEvent.NOBUTTON);
}
public static boolean postMouseEvent(int id) {
boolean r;
if (id == MouseEvent.MOUSE_PRESSED)
mouseMask = MouseEvent.BUTTON1_MASK;
r = postMouseEventImpl(id, MouseEvent.BUTTON1);
if (id == MouseEvent.MOUSE_RELEASED)
mouseMask = 0;
return r;
}
public static boolean postMouseEvent(int button) {
private static boolean postMouseEventImpl(int id, int button) {
Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getGlobalFocusOwner();
if (focusOwner != null) {
EventQueue eq = BDToolkit.getEventQueue(focusOwner);
if (eq != null) {
long when = System.currentTimeMillis();
try {
eq.postEvent(new MouseEvent(focusOwner, id, when, mouseMask, mouseX, mouseY,
(id == MouseEvent.MOUSE_CLICKED) ? 1 : 0, false, button));
return true;
} catch (Exception e) {
logger.error("postMouseEvent failed: " + e);
}
}
}
return false;
}
/*
* Key events
*/
public static boolean postKeyEvent(int id, int modifiers, int keyCode) {
Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getGlobalFocusOwner();
if (focusOwner != null) {
......@@ -93,12 +136,14 @@ public class BDJHelper {
return true;
}
} catch (Exception e) {
org.videolan.Logger.getLogger("BDJHelper").error("postKeyEvent failed: " + e);
logger.error("postKeyEvent failed: " + e);
}
} else {
org.videolan.Logger.getLogger("BDJHelper").error("*** KEY event dropped ***");
logger.error("KEY event dropped (no focus owner)");
}
return false;
}
private static final Logger logger = Logger.getLogger(BDJHelper.class.getName());
}
......@@ -23,6 +23,7 @@ package org.videolan;
import java.awt.BDFontMetrics;
import java.awt.BDToolkit;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
......@@ -724,7 +725,16 @@ public class Libbluray {
case 405: key = HRcEvent.VK_COLORED_KEY_2; break;
case 406: key = HRcEvent.VK_COLORED_KEY_3; break;
case 17:
result = java.awt.BDJHelper.postMouseEvent(0);
result = false;
if ((param & 0x80000000) != 0) {
result = java.awt.BDJHelper.postMouseEvent(MouseEvent.MOUSE_PRESSED) || result;
}
if ((param & 0x40000000) != 0) {
result = java.awt.BDJHelper.postMouseEvent(MouseEvent.MOUSE_CLICKED) || result;
}
if ((param & 0x20000000) != 0) {
result = java.awt.BDJHelper.postMouseEvent(MouseEvent.MOUSE_RELEASED) || result;
}
key = -1;
break;
default:
......
......@@ -150,7 +150,7 @@ struct bluray {
/* BD-J */
BDJAVA *bdjava;
BDJ_STORAGE bdjstorage;
BDJ_CONFIG bdj_config;
uint8_t bdj_wait_start; /* BD-J has selected playlist (prefetch) but not yet started playback */
/* HDMV graphics */
......@@ -914,7 +914,7 @@ static void _check_bdj(BLURAY *bd)
if (!bd->disc || bd->disc_info.bdj_detected) {
/* Check if jvm + jar can be loaded ? */
switch (bdj_jvm_available(&bd->bdjstorage)) {
switch (bdj_jvm_available(&bd->bdj_config)) {
case BDJ_CHECK_OK:
bd->disc_info.bdj_handled = 1;
/* fall thru */
......@@ -1368,7 +1368,7 @@ static int _start_bdj(BLURAY *bd, unsigned title)
{
if (bd->bdjava == NULL) {
const char *root = disc_root(bd->disc);
bd->bdjava = bdj_open(root, bd, bd->disc_info.bdj_disc_id, &bd->bdjstorage);
bd->bdjava = bdj_open(root, bd, bd->disc_info.bdj_disc_id, &bd->bdj_config);
if (!bd->bdjava) {
return 0;
}
......@@ -1432,7 +1432,7 @@ BLURAY *bd_init(void)
env = getenv("LIBBLURAY_PERSISTENT_STORAGE");
if (env) {
int v = (!strcmp(env, "yes")) ? 1 : (!strcmp(env, "no")) ? 0 : atoi(env);
bd->bdjstorage.no_persistent_storage = !v;
bd->bdj_config.no_persistent_storage = !v;
}
BD_DEBUG(DBG_BLURAY, "BLURAY initialized!\n");
......@@ -1543,7 +1543,7 @@ void bd_close(BLURAY *bd)
event_queue_destroy(&bd->event_queue);
array_free((void**)&bd->titles);
bdj_storage_cleanup(&bd->bdjstorage);
bdj_config_cleanup(&bd->bdj_config);
disc_close(&bd->disc);
......@@ -2851,7 +2851,7 @@ int bd_set_player_setting(BLURAY *bd, uint32_t idx, uint32_t value)
BD_DEBUG(DBG_BLURAY | DBG_CRIT, "Can't disable persistent storage during playback\n");
return 0;
}
bd->bdjstorage.no_persistent_storage = !value;
bd->bdj_config.no_persistent_storage = !value;
return 1;
}
......@@ -2880,18 +2880,18 @@ int bd_set_player_setting_str(BLURAY *bd, uint32_t idx, const char *s)
case BLURAY_PLAYER_CACHE_ROOT:
bd_mutex_lock(&bd->mutex);
X_FREE(bd->bdjstorage.cache_root);
bd->bdjstorage.cache_root = str_dup(s);
X_FREE(bd->bdj_config.cache_root);
bd->bdj_config.cache_root = str_dup(s);
bd_mutex_unlock(&bd->mutex);
BD_DEBUG(DBG_BDJ, "Cache root dir set to %s\n", bd->bdjstorage.cache_root);
BD_DEBUG(DBG_BDJ, "Cache root dir set to %s\n", bd->bdj_config.cache_root);
return 1;
case BLURAY_PLAYER_PERSISTENT_ROOT:
bd_mutex_lock(&bd->mutex);
X_FREE(bd->bdjstorage.persistent_root);
bd->bdjstorage.persistent_root = str_dup(s);
X_FREE(bd->bdj_config.persistent_root);
bd->bdj_config.persistent_root = str_dup(s);
bd_mutex_unlock(&bd->mutex);
BD_DEBUG(DBG_BDJ, "Persistent root dir set to %s\n", bd->bdjstorage.persistent_root);
BD_DEBUG(DBG_BDJ, "Persistent root dir set to %s\n", bd->bdj_config.persistent_root);
return 1;
default:
......