I use thunderbird 1.5 as my mail reader, and it is always bugged me that clicks on
file:// links in emails are ignored - these are frequently used internally within Sun, for example code reviews are usually done with a tool called webrev which builds a tree of HTML pages containing the diffs, and the
file:// links are usually mailed out to reviewers. A spot of light googling revealed this page on the topic for firefox, and although the page implied the same configuration settings were also used by thunderbird, it wasn't quite clear how to apply the technique to mails read from an IMAP server. Hmm.
So I surmised that what I needed to do was to tell thunderbird to trust links from my IMAP server, so I added the following to my user.js file:
// Allow file:// links user_pref("capability.policy.policynames", "localfilelinks"); user_pref("capability.policy.localfilelinks.sites", "imap://mailserver.uk.sun.com:143"); user_pref("capability.policy.localfilelinks.checkloaduri.enabled", "allAccess");
restarted thunderbird, and clicking on
file:// links now worked. Note that there are a number of good security-related reasons as to why this isn't enabled by default, so use it at your own risk!
I previously documented my problems getting my Java/JNI wrapper for OziAPI to work. As I said in my previous post, some of my problems were down to the OziAPI DLL not getting a chance to clean up properly when the application exited. Over the Xmas break I continued hacking away and wrapping more of the interface, but when I got to the OziExplorer callback hooks I hit another showstopper. The hooks allow you to trap mouse clicks on the map displayed in OziExplorer, but every time I activated one of the callback hooks and then clicked on a map the application hung, and it stayed hung until I quit the Java application. My initial thought was that I was falling afoul of the awful mess of calling convention types on Win32 and that something was barfing on a malformed stack frame somewhere on the round trip from my Java app to OziExplorer and back. I was particularly suspicious because I was using the MinGW tools to build the DLL containing my JNI code rather than the Microsoft tools.
To try to track down the root cause I hacked together a console-only C program and DLL to mimic my Java/JNI setup, and whilst that worked fine with the non-callback OziAPI functions (as did the Java/JNI version), any callback functions hung in just the same way as the Java/JNI version. I noticed that the Visual C++ example included with the OziAPI DLL contained a Windows GetMessage loop, so I added one to my toy program and hey presto, it worked! This implied that OziAPI uses windows messages to implement the callback mechanism, and an email to Des Newman, the OziExplorer developer, confirmed that was in fact the case.
That didn't really help explain what was wrong with the Java/JNI setup - the Java code was a Swing application, so it had to contain a Windows dispatch loop anyway - right? What on earth was going on? I was more more less ready to admit defeat when I stumbled across an old JavaWorld article that contained the following:
Messages are not sent directly to windows, but put on an event queue owned by a thread. The thread must occasionally check for messages on its queue, and choose to either deal with them or delegate them to other callbacks ... we cannot be sure that these threads (which are owned by the VM process) check their Win32 message queues and delegate messages. In this case, in fact, they don't. Because of this, we will create our own thread, with our own message queue handling, and make sure all our windows are created within its context. It is simple to asynchronously delegate work to our worker thread by posting custom messages to its message queue.
Ahah! So it appeared that it is necessary to have a custom dispatch loop to handle the Windows messages dispatched by the OziAPI callback hooks. However, because this thread has in turn got to be able to dispatch the callbacks to Java methods, we have to play nicely with the JVM as well. We also have to make sure that the events from the OziAPI DLL get dispatched to our dispatch thread - some experimentation revealed that OziAPI sends them to the first thread that makes a callback-related OziAPI call. Putting this all together, here's what is necessary to get it to work:
- Create a native Windows thread.
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE)to force creation of a new Windows message queue.
- Make a dummmy
oziMapSingleClickOFF()call so OziAPI routes the callbacks to the new thread.
- Attach the new thread to the JVM with a call to
- Enter a message dispatch loop to handle the callback events.
The various OziAPI calls necessary to enable and disable the callback hooks are also made from inside the new thread - the event loop responds to custom
WM_APP messages and enables or disables the callbacks as required. The callbacks themselves are handled by C routines that vector the events to the appropriate Java method calls. I've left out all details of the necessary inter-thread synchronisation that's needed, but that's an overview of how it all hangs together.
I'm still working on wrapping the rest of the API - it's rather large so it is going to take a while, but once I have it knocked into shape I'm intending to release the code here on SourceForge.
Just taken the kids to see "King Kong" at the cinema. What a over-long, self-indulgent pile of crap it is. Although it is undoubtedly a masterpiece of CGI, the story line is far too flimsy to sustain this 3+ hour epic of cinematic navel gazing. Peter Jackson has stuck very close to the original plot line, and that's the problem - the original film ran for 1:40, this version runs for a interminable 3:07. The action sequences are utterly preposterous as well as being far too long, and CGI characters are more three-dimensional than the human ones.
By half way through I just wanted them to get on with it and shoot the goddam monkey so I could go home for my tea. I'm not the only one who thinks this - see this, this and this review at IMDB, for example - all of them hit the nail on the head - its a bloody awful movie.
My advice? Avoid.