Glad to hear it, thanks.Btw: I just want to say thanks again for an excellent job with the vlcj project. It was tremendously helpful.
Well, it is platform related. I can mix heavy and lightweight components just fine (just make sure they don't overlap) without any problems and get all the events on Linux.@erwan10: I've tried keyboard listeners, but unfortunately they don't work. (something like videoSurface.addKeyListener(new KeyboardListener.....). I think this has to do with the java.awt.Canvas object, and it being a heavyweight component (I could be mixing this up with other details I've read about Canvas objects).
Code: Select all
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
@Override
public void eventDispatched(AWTEvent event) {
if(event instanceof KeyEvent) {
KeyEvent keyEvent = (KeyEvent)event;
// ...do whatever
}
}
}, AWTEvent.KEY_EVENT_MASK);
I think it can be done if the Java can set up a global message hook in Windows. This would require some more native Win32 calls and may require elevated privileges for all I know. I'm not a Win32 programmer so I don't know how to do this.However, in my opinion, the platform-specific code is best put in the bindings, not in the application using them. So I'd consider it a vlcj bug if it cannot hide this.
I have hardly any clue about Java or Win32, and it might be impossible - but then there is no point in trying to solve it at the application level either.
Thanks. That makes complete sense. I was looking at it too much from the pampered portable-language perspective.From the LibVLC perspective, platform-specific code is unavoidable for video embedding. This stems from the fact that native window handles are required.
I took a look and it works great. I made a few additions on my side. Please feel free to modify and incorporate.With the newest version of the vlcj bindings, mouse events (move, press, release) via a native message hook works for me when playing video on Vista.
Code: Select all
java.awt.Window applicationWindow = null;
@Override
public LRESULT callback(int nCode, WPARAM wParam, MOUSEHOOKSTRUCT lParam) {
if (applicationWindow == null) {
Component parent = relativeTo.getParent();
while (parent != null) {
if (parent instanceof java.awt.Window) {
applicationWindow = (java.awt.Window)parent;
break;
}
parent = parent.getParent();
}
}
if(nCode >= 0) {
// Is the component visible...
if(relativeTo.isVisible() && relativeTo.isValid()
&& applicationWindow != null && applicationWindow.isActive() // isActive should mean that it is the active window in the windowing system
Code: Select all
private java.util.ArrayList<WindowsKeyListener> keyListeners = new java.util.ArrayList<WindowsKeyListener>();
@Override
public synchronized void addKeyListener(KeyListener l) {
WindowsKeyListener wkl = new WindowsKeyListener(this, l);
Toolkit.getDefaultToolkit().addAWTEventListener(wkl, AWTEvent.KEY_EVENT_MASK);
keyListeners.add(wkl);
}
@Override
public synchronized void removeKeyListener(KeyListener l) {
int index = keyListeners.indexOf(l);
WindowsKeyListener wkl = (WindowsKeyListener)keyListeners.get(index);
Toolkit.getDefaultToolkit().removeAWTEventListener(wkl);
}
class WindowsKeyListener implements java.awt.event.AWTEventListener {
java.awt.Component component;
java.awt.event.KeyListener keyListener;
public WindowsKeyListener(java.awt.Component component, java.awt.event.KeyListener keyListener) {
this.component = component;
this.keyListener = keyListener;
}
@Override public void eventDispatched(AWTEvent event) {
KeyEvent keyEvent = (KeyEvent)event;
if (keyEvent.getComponent() != component) return;
int id = keyEvent.getID();
switch (id) {
case KeyEvent.KEY_TYPED: keyListener.keyTyped(keyEvent); break;
case KeyEvent.KEY_PRESSED: keyListener.keyPressed(keyEvent); break;
case KeyEvent.KEY_RELEASED: keyListener.keyReleased(keyEvent); break;
}
}
}
Code: Select all
package uk.co.caprica.vlcj.runtime.windows.internal;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.User32.POINT;
import com.sun.jna.platform.win32.W32API.HWND;
import com.sun.jna.platform.win32.W32API.ULONG_PTR;
import com.sun.jna.platform.win32.W32API.DWORD;
public class MSLLHOOKSTRUCT extends Structure {
public static class ByReference extends MSLLHOOKSTRUCT implements Structure.ByReference {};
public POINT pt;
public DWORD mouseData;
public DWORD flags;
public DWORD time;
public ULONG_PTR dwExtraInfo;
}
Code: Select all
/*LRESULT callback(int nCode, WPARAM wParam, MOUSEHOOKSTRUCT lParam);*/
LRESULT callback(int nCode, WPARAM wParam, MSLLHOOKSTRUCT lParam);
Code: Select all
case WM_MOUSEWHEEL: // 522
long delta = (lParam.mouseData.longValue() >> 16); // >> 16 HighOrder Word (GET_WHEEL_DELTA_WPARAM).
System.out.println(delta == 120 ? "wheel up" : "wheel down"); // TODO: call listener
break;
Nice, thanks. I've incorporated this with a few minor differences.I took a look and it works great. I made a few additions on my side. Please feel free to modify and incorporate.
This is one reason why I didn't bother with this at first, the more native calls that are made the more unstable things seem to become - especially on Windows. Tracing those problems can be very difficult.I had the app lock up a few times -- usually within 15 or so minutes of playback
Code: Select all
Exception in thread "Thread-6" java.lang.NoSuchMethodError: com.sun.jna.Pointer.createConstant(I)Lcom/sun/jna/Pointer;
at com.sun.jna.platform.win32.W32API.<clinit>(W32API.java:93)
at com.sun.jna.platform.win32.W32API$HANDLE.fromNative(W32API.java:38)
at com.sun.jna.NativeMappedConverter.fromNative(NativeMappedConverter.java:61)
at com.sun.jna.Function.invoke(Function.java:234)
at com.sun.jna.Library$Handler.invoke(Library.java:204)
at $Proxy3.GetModuleHandle(Unknown Source)
at com.delcan.decoder.runtime.windows.WindowsMouseHook$MouseHookThread.run(WindowsMouseHook.java:459)
You have a mismatch on your classpath between the JNA platform.jar and the JNA jna.jar.@sherington
Exception in thread "Thread-6" java.lang.NoSuchMethodError: com.sun.jna.Pointer.createConstant(I)Lcom/sun/jna/Pointer;
I'm using JNA 3.2.5.
Indeed you are correct. I had the correct combination of JNA jar and platform jar but the main project was referencing other projects (within Eclipse) that had older JNA jars on their classpath. Upgraded all to the same version of JNA and now it's working.You have a mismatch on your classpath between the JNA platform.jar and the JNA jna.jar.@sherington
Exception in thread "Thread-6" java.lang.NoSuchMethodError: com.sun.jna.Pointer.createConstant(I)Lcom/sun/jna/Pointer;
I'm using JNA 3.2.5.
Hi,Hi all,
First, thanks to all you awesome folks for all the great work. I am a newbie so excuse me if I sound naive.
I recently downloaded vlcj which I think is a Java 6 skin around libvlc. vlcj has several i/fs to control the video. I am wondering, should it not be easy to take vlcj source code and replace the event handlers with logic we want executed in response to the mouse events? That way, at least some mouse events can be processed, if not all mouse/keyboard events.
Chirantan
Return to “Development around libVLC”
Users browsing this forum: No registered users and 6 guests