Archive for August, 2006

Things that make my life that little bit more annoying…

Tuesday, August 22nd, 2006

Visual Studio 2005 has this irritating habit of moving itself to the top of the window order when it gains the focus. “Hang on a minute”, you might be saying, “surely clicking on an application should bring it to the front”. Of course that is the usual model but I run blackbox on my Windows box at work so I can have, amongst other things, a half-size task bar, virtual desktops and — most importantly — sloppy point to focus[1].

So I’m merrily browsing away in Firefox when my pointer slips from the window onto Visual Studio and *poof* Visual Studio now fills my screen. Even more annoyingly if I go down to the task bar to bring another window to the front, as I move the pointer towards it VS steals my screen again. So far the only solution I’ve found is to have VS on its own desktop and have it be the only window on that desktop which makes the compile, test, debug cycle painful.

My question is this: why on earth did MS feel the need to code ‘move to top on focus’ into VS? No other Win32 app I have here needs to do this.

[1] I’m too old to change my neurons now. That is the model I used when I was twelve, that is the model I use now.

Apple rant

Monday, August 21st, 2006

OK so this is a slightly poorly titled post. It isn’t completely Apple’s fault that this weekend was such a pain :). Also this a hacker post mostly for my own therepy so it is probably terribly boring…

Update: Of course now I see that xine-lib CVS already has had some Darwin love applied… Grr.

This weekend I found a little time to try to move a little further in making XinePlayer a Universal application[1]. This isn’t as trivial as it might at first sound since, of course, XinePlayer uses xine as its media playback engine and xine a) doesn’t have a build chain that plays nice with Universal binaries — in fact it is autotools which doesn’t play nice generally, b) isn’t primarily developed on OSX and especially not Intel OSX and c) has lots of processor specific parts.

Carry on reading for the pain that was involved but, to cut a long story short, I can now build a standalone Universal XineKit which contains all the plugins one might expect and can be embedded in your apps. It can be embedded so easily in fact that I wrote a really quick Universal XineKit-based DVD player with which I successfully watched my brand new Matrix DVDs. Amazingly it even worked when run under Rosetta!

Before I talk about XineKit I should just note that the nasty hacky way I was displaying video with previous XinePlayer versions just didn’t work under Intel OS X. Consequently I took the plunge and made a generic video output system the first thing that will be implemented by my, to be GPLd, utility framework RWUtilityKit. Ultimately I’m going to roll all the stuff I wrote for handling global hotkeys, preferences dialogues, etc into it. The output system I wrote is now based on OpenGL and performs colourspace conversion in hardware. For some planar formats it even uses a little fragment program[2] which does this using the magic of modern GPUs.

The API (1, 2) for this video renderer is pretty easy to use. Just create as many video frames as you want. Fill in the buffers and call setCurrentFrame: on a RWVideoView plonked somewhere in your window. Under the covers it uses the new CoreVideo framework to provide synchonisation with refresh rate, etc.

The first hurdle was getting xine to compile on Intel OS X at all. Luckily there has been some OS X love shown to xine independant of any of my efforts but almost none of this was to Intel bits. Mostly I had to workaround bugs in Apple’s Intel gcc C compiler, especially when using its inline assembler. Once that was sorted there were a few little endian fixups and some Darwin specific fixes for byte swapping etc. The patch set ended up quite small but was an effort to obtain. Some of them are suitable submission to xine though (especially the trivial endian patches) so it might be easier compiling xine in the future.

The second hurdle was making libxine and all of its plugins Universal. I took the sledgehammer approach and decided to cross-compile a complete libxine for both x86 and PPC and then merge them together with lipo. The build script is nasty but it does result (on my MacBook at least) in a Universal build of xine.

Lastly I wanted to separate out XineKit from XinePlayer to make it useful as a standalone framework. Making that easy for the application writer was hindered by the nastiness in the OSX linker. Basically all libraries are linked into objects using the full path and the concept of a ’search path’ is somewhat different from that of the ELF loader. Consequently one has to work inside a small box relative to the final binary which loads the framework. Unfortunately there is no such box when one trys to link shared libraries with Frameworks. After a lot of effort I eventually gave up on getting the XineKit framework to play nice with an embedded libxine.dylib and decided to just use static linking. It bloats the binary a little but it does at least work.

[1] For the non-OSXers out there a Universal binary is what used to be called a fat binary :). It contains, in this case, both x86 and PPC object code so the same binary can be used on both versions of OSX.

[2] A fragment program is a small bit of assembler you can upload to the GPU which gets run once for each pixel you render. In this case it reads the planar video texture created by xine and does the requisite YUV to RGB magic. This might be the subject of a future rant where I explain exaxtly why DirectX is nicer to code for than OpenGL.