The Incrementalist

8/21/2005

Building LuaJava on Mac OS X

Filed under: — Joe @ 1:48 pm

In my previous post about coroutines, I mentioned that I’d be looking into LuaJava (a bridge between Java and the Lua language) as a way to get coroutine behavior in a Java environment. Since I had some time this afternoon, I decided to get LuaJava up and running on my PowerBook. Here are some steps that you can follow to build LuaJava on Mac OS X 10.4.2 Tiger. (I’ve also successfully tested these instructions on Mac OS X 10.3.9 Panther.)

LuaJava requires Lua 5.0, so first we need to download the Lua 5.0 source and build it:

% tar xzvf lua-5.0.tar.gz
% cd lua-5.0
% make
% sudo make install

Next, we need to build LuaJava. Download LuaJava 1.0, then extract it and switch to its directory:

% tar xzvf luajava-1.0.tar.gz
% cd luajava-1.0

Since LuaJava’s config file comes set up for Linux by default, we need to edit it to Mac OS X-friendly settings. Comment the following lines:

#JDK= $(JAVA_HOME)
#LIB_EXT= .so
#LIB_OPTION= -shared
#DLLIB= -ldl

and uncomment the corresponding ones:

JDK=/Library/Java/Home
LIB_EXT= .jnilib
LIB_OPTION= -dynamiclib -all_load

We also need to change the LIB_LUA line to read:

LIB_LUA=/usr/local/lib/liblua.a /usr/local/lib/liblualib.a

With those changes in place, we can just type

% make

and apart from a few JavaDoc warnings, everything should go smoothly. To test it, we can fire up the LuaJava Console:

% java -cp "luajava-1.0.jar" org.keplerproject.luajava.Console
API Lua Java - console mode.
> print('Hello, world!')
Hello, world!
> exit

OK, that looks good. How about the included tests?

% cd test
% ./runawttest.sh
% ./runswingtest.sh

Again, working fine. There are a couple of other Lua test files in the test directory that we can run like so:

% java -cp "../luajava-1.0.jar" -Djava.library.path=.. 
    org.keplerproject.luajava.Console testMemory.lua

(replace testMemory.lua with the name of the file you want to run)

OK, let’s try creating a program of our own. There’s a decent Hello World on the LuaJava examples page, so (after switching back to the luajava-1.0 directory), create the Hello.java and hello.lua files depicted on the examples page. You’ll need to add an import line to the top of Hello.java so that Java knows where to find all the LuaJava objects:

import org.keplerproject.luajava.*;

Once you have the files, compile the Java class:

% javac -classpath luajava-1.0.jar Hello.java

Now run it:

% java -cp luajava-1.0.jar:. Hello

If everything is working correctly, you should see:

Hello World from Lua!
Hello World from Java!

Huzzah! Now we have all the pieces we need to start embedding Lua functionality in Java code.

8/16/2005

Teleport

Filed under: — Joe @ 9:05 am

The typical setup in my office is that I have my G5 powering two monitors front and center, and the powerbook beside them, on a (modified) iCurve for ergonomic viewing. While this is great for the displays, it leaves the problem of controlling the laptop. At one point I had a KVM switch set up, but the hassle of plugging in a USB cable and flipping the switch led me to just type un-ergonomically on the laptop’s keyboard.

Then I came across Synergy. It’s a cross-platform tool that lets you send your keyboard and mouse commands to other machines on your network–sort of like VNC without the screen-sharing (since the other screen is right in front of you). The Synergy team’s most brilliant innovation, though, is the interface for switching machines. Basically, you can configure your machines so that when you roll your mouse pointer off the edge of one machine’s screen, it magically appears on the corresponding edge of a different machine’s screen. You can roll your mouse from your Linux box across your Windows box over to your Mac in one smooth motion. It’s like the way that multi-monitor setups work, except that under the hood it’s seamlessly switching to sending your input to another machine over the network.

I’ve been using Synergy for a few months now, but it’s not without its rough edges. Last time I did it, configuration was a text-editing affair, though the SynergyKM preference pane add-on for Mac OS X makes things much more automatic. I also tended to experience general glitchiness on OS X. A vestigial mouse pointer would often remain on my main monitor, twitching distractingly, as I controlled the laptop. It also didn’t handle modifier and function keys, meaning I still had to press the function keys on the laptop directly to trigger Exposé.

Enter Teleport. While (or perhaps because) it’s Mac-only, it solves most of the problems I had with Synergy. The configuration is a breeze (using Rendezvous AKA Bonjour), and input forwarding is smooth and comprehensive. It also seems to automatically sync clipboards well, something that I was using Erik Lagercrantz’s ClipboardSharing utility for until he failed to update it for Tiger.

So far, I only have a few minor critiques. First, it doesn’t appear to allow you to put two remote screens side-by-side–the remote screens must be adjacent to the main computer’s screens. Also, it seems to hit the disk every time I roll over the boundary between two machines, which is audibly distracting and causes an annoying delay in which mouse motion isn’t counted on the new screen. Even so, I think it will be a part of my desktop setup from now on. Thanks Julien!

5/2/2005

Tiger Dashboard: First Impressions

Filed under: — Joe @ 11:10 am

When people install a new operating system, one of the first things they do is go poking around to see what’s different. With Tiger, one of the first things that they’re going to notice is Dashboard.

Pedigree

While Dashboard was immediately compared to Konfabulator because of its visual, technical, and “widget” naming similarities, it also owes much to Apple’s old Desk Accessories, as John Gruber and others have pointed out. I think of them as a new version of the old Terminate and Stay Resident programs popular on MS-DOS. Generally, those programs didn’t live on the same screen as the main program you were using. Instead, they popped up when you pressed a keyboard combination. Apple’s design decision to put Dashboard widgets on a separate “layer” that you can call up makes them much more useful to me than Konfabulator, because there truly is never enough screen real estate, and the Konfabulator widgets immediately got smothered under other windows when I tried to use them. (I should note that it’s also possible to keep Dashboard widgets on your desktop.)

Development Simplicity

Apple’s decision to make HTML/CSS/Javascript the lingua franca is Dashboard’s most interesting feature to me. Konfabulator’s XML/Javascript environment came close, but Apple’s “lazy” decision to use their Safari WebKit engine means that many widgets can actually be developed and viewed in a browser. (Many of the early posters on the Dashboard Widgets site were clearly developing their widgets without any access to Tiger.)

Using standard technologies means that their developer population is the large set of people who already know how to develop using web standards. Furthermore, given the recent buzz around “Ajax” web applications, Dashboard gives people like me another excuse teach myself data-driven Javascript programming.

By effectively turning Ajax into a GUI library for desktop apps, Dashboard almost fulfills the plan that Netscape appeared to be working towards in the late 1990s. While many widgets will be little more than borderless self-refreshing web pages, it’s also possible to hook up a Dashboard interface to native code. In Apple’s first Dashboard widget contest at WWDC 2004, the top prize went to a widget which put an HTML face on the GNU Go game engine.

Constency

Dashboard isn’t all roses though. For one, going to HTML-based interfaces makes it even easier for Apple to continue their recent trend of ignoring their own interface conventions whenever it suits their fancy. (See brushed metal vs. aqua, the woodgrain GarageBand window, the non-standard sets of widgets in the new iPhoto.) In several of the sample widgets that ship with Dashboard, they go to great lengths in Javascript to create properly-behaving milky-white scroll bars rather than simply using the standard ones:

Even so, the initial set of widgets that Apple shares largely consistent features: the aforementioned white scroll bars, a circled i which fades in to trigger a flip to the preferences side, rounded square widget icons, and a dark textured flip side with a large “Done” button. It’ll be interesting to which, if any, of these features get adopted by the third-party widget community.

What is it good for?

In the initial burst of activity following Tiger’s release, there’s a lot of experimentation going on in the Dashboard world. The best place to watch this happen is the Dashboard Widgets Showcase, which seems to have captured the, uh, Tiger’s share of widget-writing activity. From what I’ve seen so far, widgets generally fall into the following categories (from most to least useful):

  • Status Displays — These display some piece of information which changes relatively frequently, and which you want to see at a moment’s notice. Examples include Apple’s weather and stock displays, the iTunes Connection Monitor, and my Bloglines Notifier.
  • Handy Controls — These are small bits of functionality that people want to have ready access to–good examples here are Apple’s iTunes widget, Panic’s Transmit FTP widget, and the Capture screenshot tool.
  • Games and Geegaws — Games and toys like miniPatience, Hula Girl, and MAYA Cards. These don’t necessarily benefit from being on Dashboard, other than not crowding up your desktop, and being quickly dismissable when your boss walks by.

Baby Steps

As first experiments with Dashboard, I’ve put together a few widgets of my own. The first is Bloglines Notifier, featuring a gorgeous visual design by Jeremy Koempel:

It’s very simple, showing you the unread posts in your Bloglines online RSS reader account, and giving you a button to go read them. The other is a little promotional widget that I cooked up with some of my co-workers at MAYA Design:

This one’s a virtual version of our customized playing cards that we give out as promo schwag. Each one features a different pithy design quote which reflects our design philosophy. This one came about when I realized that Dashboard’s flipping functionality would be a good match for playing cards.

I’ve got a couple others in the works, so keep watching this space…

1/31/2005

Multi-Pointer Gestures

Filed under: — Joe @ 10:30 am

Apple released another bump in the Powerbook line this morning. Typical weekday release, still no G5, no big deal—right? Well, there was one thing that caught my eye:

Trackpad Scroll

So what? We’ve had things like SideTrack to set aside sections of the trackpad for scrolling for some time now.

Two Arrows

Wait, two fingers, you say?

For the past 15 years or so, we’ve pretty much been stuck with a single cursor with a couple buttons as our narrow pipeline into the world behind the screen. A few niche products and research projects have demonstrated the potential of multiple-pointer interaction. For instance, a SIGGRAPH video that I once saw showed a user holding a virtual tool palette with one hand, and clicking through it with the other hand’s cursor. It also made rectangular selection more fluid, with each pointer getting one opposite corner. A company called FingerWorks has been selling keyboards and touchpads that can detect multiple fingers. I’ve been curious, but they’re pricey and I’ve never found a demo unit that I could try for myself. With such a tiny market, developers and OS makers have had little incentive to investigate the possibilities of multi-pointer interaction.

That’s why Apple’s addition, if I’m guessing correctly and they’re not just using some capacitance trick, stirs my imagination. If they eventually move to multi-finger touchpads across their entire portable line, it’d be the first wide-scale deployment of a multi-pointer input device. (Nintendo blew their chance with the DS—it’s disappointing that its touchscreen can only detect one finger at a time, since it would otherwise serve as a great reconfigurable controller.)

The operating system could still be a bottleneck. I have no idea whether OS X can support multiple pointers under the hood—their initial use of the multi-finger gestures for things like scrolling is easy enough to do at the driver level. But I hope that if they expand the use of the multi-finger trackpads, they’ll eventually expose it at the OS level. I would love to have the additional expressiveness in my work. For example, I could use it to solve the ambiguity of whether the user wants to drag a frame or something inside of it—in the latter case, you could just pin down the frame with one finger and grab the contained element to yank it off. You could zoom in or out by grabbing a map at two points and bringing your fingers further apart or closer together (Hiroshi Ishii prototyped this behavior with phycons on a projection table). Or you might express the difference between “move” and “copy” operations by whether the user grabbed the item with one or two fingers.

Who knows, maybe Apple could end up doing for multi-pointer input what they did for USB and WiFi. Well, I can dream…

Update: As it turns out, some earlier Powerbooks and iBooks (though, sadly, none in my household) have trackpads that support this feature. On those machines, you can install a driver mod to enable two-finger scrolling capabilities.

Update: Looks like I missed another interesting feature of the new Powerbooks: an accelerometer! Enterprising hackers have already found ways to tap into it from software, yielding a “tilt”-control iTunes interface. I think it’s an unwritten law of Mac software development that every Mac I/O device must eventually be hooked up to iTunes.

12/24/2004

Mac OS X Graphic Performance Tidbits

Filed under: — Joe @ 9:46 am

Quartz Debug

Lately I’ve been digging into the details of the Mac OS X graphics subsystem, both because a lot of my (Java) code exercises it, and partly because I might be building something similar at some point.

OS X owes its renowned visual stability to the fact that every single window is buffered; to be exact, drawing commands from programs are executed into offscreen buffers, which are flushed to the screen (with an eye to where the CRT beam is!) when WaitNextEvent or QDFlushPortBuffer are called. Keeping a bitmap for each window is what allows OS X to sling windows around without visual glitching, even when applications are frozen up compeletely. It is, of course, a very expensive proposition in terms of the system RAM that it consumes. It hadn’t sunk in for me before that every single open window, visible or not, eats up significant RAM—maybe that’ll convince me to close old windows a little more often, especially on my poor 640MB iBook.

The other thing that I had heard about before but hadn’t tried before is the Quartz Debug utility, which you’ll find in /Developer/Applications/Performance Tools/Quartz Debug if you have the Developer Tools installed on your machine. If you run that and check off Flash screen updates (yellow) and No delay after flash, you’ll get a nice view into the workings of the graphics system, because any area of the screen buffer that changes will flash yellow. One interesting thing that this makes apparent is an advantage that Safari has over Firefox: when scrolling, Safari updates only the newly-exposed area of the window, making for smoother scrolling than Firefox, which always redraws the whole content pane. Another thing that it made obvious to me is how horribly inefficient some parts of the Geobrowser are in terms of redrawing things which haven’t changed visually—I need to be more conscientious about calling repaint() with an affected area and minding the clip rectangle in paintComponent(). (It actually makes me happy to discover clear-cut avenues for optimization like that.)

I’m still looking for real nuts-and-bolts details on what happens during screen updates. Here’s the mental model that I’ve pieced together so far:

  1. An application performs some drawing operations, which modify an offscreen window buffer #1
  2. The application calls QDFlushPortBuffer with an affected region rectangle, which blocks while…
  3. The affected region of the application window is blitted from buffer #1 to buffer #2 (the Window Server’s buffer for that window)
  4. The affected region of the screen is re-composited by Quartz Compositor (Extreme or otherwise) and blitted to the frame buffer when the CRT beam or LCD refresh point is elsewhere

If you know better and I’m getting some details wrong, don’t hesitate to comment.