2006-08-28

Book: "Mac OS X Internals: A Systems Approach"

The advertising blurb on the back of the book claims that "Mac OS X Internals: A Systems Approach is the first book that dissects the internals of the system, presenting a detailed picture that grows incrementally as you read". In a sense this is true, but the picture doesn't grow in a way that suggests the author started with a map or itinerary. "A Brownian Motion Tour" would seem an equally apt title. I'm not sure that the lack of a plan was the cause of the book's weakness, though, or just a symptom. I've a hunch that the real disease was the attempt to serve too many masters.

I'll come back to that, but speaking of growth, this book is gigantic. It has 1641 numbered pages, is printed on reasonably thick paper, and has a hard cover. It's too heavy to comfortably hold while reading. Really, you need to rest it on a table or lap. The book's bulk would be annoying in and of itself, but the fact that so much of the book's content seems like filler makes it all the more annoying.

The first couple of chapters give an overview of where Mac OS X came from, and its major components. There's some interesting stuff for the newcomer to Mac OS in the second chapter, "An Overview of Mac OS X", such as dyld interposing, Mac OS' equivalent of LD_PRELOAD (see Apple's Dynamic Library Programming Topics and Dave Dribin's recent blog entry Tracing Objective-C Messages), but I'd have liked a quicker introduction and to have left the good bits for later, where they could be presented a little less out of the blue.

If you need an overview of Mac OS X technologies, you're better off with Apple's Mac OS X Technology Overview.

If you want to know about Mac OS debugging, see TN2124: Mac OS X Debugging Magic (and some of the documents it links to) and Performance Overview.

Chapter 3 "Inside an Apple" is a 100-page introduction to Apple's PowerPC architecture. That is, the architecture Apple's just completed its transition away from. Appendix A, "Mac OS X on x86-Based Macintosh Computers", says that it's beyond the appendix's scope to detail the hardware differences, so if you're primarily interested in the future, you're out of luck. Chapter 3's probably not a bad introduction to PowerPC Macs. I didn't know before reading it that the G5 has no BAT registers, for example, and I'd not previously heard of the processor's softpatch facility. There was also a nice overview of the PowerPC ABI. Again, though, Appendix A has no overview of the x86 ABI, which for most current Mac programmers would be more useful. PowerPC may be something of an oddity in the wider world, but for Mac programmers, x86 is the strange new world. For those Linux/Windows programmers who're used to x86 but don't know PowerPC, this might be of some use, but even then: PowerPC is over for Apple, and the future is in the far more familiar shape of x86. I couldn't help but feel that this chapter was mainly written as nerd porn. A better editor would have cut most of it and left us with PowerPC and x86 ABI overviews.

As it is, you can read Apple's own perfectly good Mac OS X ABI documentation (for all Mac OS X architectures).

The next chapter, "The Firmware and the Bootloader", is worse. In the increasingly unlikely event you need to know more about Open Firmware, you can find plenty on the web. Likewise if you want to write Towers of Hanoi in Forth, seemingly a special interest of the author's that he couldn't resist sharing. I look forward to another author showing me how to knock up a train-spotting database in Z80 assembler some day. I'm not sure many readers will gain anything from 100 pages about this legacy technology. The last 10 pages of this chapter talk about Intel's EFI, which replaces Open Firmware in x86 Apple hardware, and there's some discussion of the bootloader, but my dream editor would still have cut most of this chapter, or possibly have asked for an EFI rewrite with a 10-page addendum on Open Firmware.

Chapters 5 and 6 ("Kernel and User-Level Startup", and "The xnu Kernel") are fairly tedious walk-throughs of parts of the kernel. This is nothing like as clear or directed as "Lion's Commentary on Unix, Sixth Edition", because the book doesn't claim to be an introductory text. That's one of the big problems for me with this book: it's not clear who it's really suited for. The preface's "Who This Book Is For" suggests it's useful to application programmers, system programmers, users, system administrators, technical support staff, experts in other OSes who want to know how Mac OS differs from their OS, and students in advanced OS courses. Phew! If only he could have slipped in a section for the third-world children who assemble computers, then there would have been something for everyone. The trouble is, in attempting to serve all these masters, the book flounders. Application and system programmers are not well served because although the book takes you on a long tour of Mac OS facilities, it makes little or no attempt to motivate the different choices. A lot of what's here but not in standard Unix texts like "Advanced Programming in the Unix Environment" is obviously harmful to portability, and often restricted to Mac OS on PowerPC (though rarely to the Intel variant, because coverage of that is mostly restricted to a 10-page appendix). There would need to be good reason to use this stuff instead of traditional Unix facilities, but we're not helped out on that front. Writers of kernel extensions would probably be better served by a more focused book. For experts in other OSes, the book is limited by its huge size and the paucity of direct comparison. Also lacking is the kind of comparison that motivates the trade-offs between different systems. As for sysadmins and support staff (other than those who'd rather be kernel hackers), I'm mystified. There are occasional mentions of things like launchd(8), but this is no "Mac OS for Unix Geeks".

Another failing of this book is that it's very heavy on implementation, very heavy on history, and very light on design. If you're used to books such as Bach's "The Design of the UNIX Operating System", McKusik et al's "The Design and Implementation of the 4.4 BSD Operating System", or Tanenbaum's books, you'll be disappointed. I don't know if the author isn't interested in design, or just doesn't understand the difference between history and design, but this book is let down either way.

The most interesting parts of these kernel chapters for me were the description of the commpage and the description of the kernel support for the Mac OS 9 emulation (the "Classic environment"), and the virtual machine monitor. I hadn't realized that Classic support was so deeply ingrained, or so seemingly general-purpose, but then I've never had cause to think about it: I've owned several Macs since 2001, and I've never once run the Classic environment. (Yes, I'm a Unix snob. Here's a nickel, kid.) Moreover, none of this exists on Mac OS X for Intel, so it's at best only of historical interest. The modern "Rosetta" system for running PowerPC Mac OS X binaries on Intel Macs does get a mention, taking two pages of the 10-page Intel appendix, but I'd have liked to have seen much more concentration on that.

Apple's meager Rosetta documentation is better, and their Universal Binary Programming Guidelines is a better guide to the differences between Mac OS on Intel and on PowerPC than this book's appendix.

Chapter 7, "Processes", which actually covers all kinds of processes, threads, and tasks, has a good example of the kind of worthless filler that keeps cropping up in the book: the section "Java Threads". There are several interesting things to be said about Java threading on Mac OS. For one thing, there's the fact that although Sun explicitly tell you never to create your UI other than on the Java event dispatch thread, it's easy to screw up because you can usually get away with it on systems other than Mac OS. Many Java programs that ignore Sun's rule work fine on other systems and deadlock on Mac OS. (Sun's own installer for the JDK 6 source had this problem at one point, for example.) The other interesting thing about Java threading on Mac OS is the difference between the thread that Java's main method runs on, the Java event dispatch thread, and the AppKit "main thread". Confusion between these threads seems to be a common cause of deadlocks and crashes in Java programs using JNI to access Cocoa on Mac OS. What does "Mac OS X Internals" give us? A short Java program that starts three Java Threads with three different priorities. That's about as instructive as it sounds. The author even explicitly states that the example code isn't useful in conjunction with the tool he uses to list Mach threads.

I don't know why there's no mention of Java's Runtime.exec, because the next example is a Cocoa program using NSTask. This is followed by an equally uninstructive example of NSThread before the author wanders off to present alternative Carbon threading mechanisms, with the usual lack of explanation of what advantages and disadvantages they have. The chapter finishes with a walk-through of the execve implementation that fails to mention Rosetta, and fails to detail the exact interpretation of "#!" lines (one of the things that varies quite a bit from one Unix to another).

Chapter 8, "Memory", has a good example of the book collapsing under its own weight. The implementation of prebinding is described, with a note that prebinding is deprecated as of Mac OS 10.4, but if you want to know why it's deprecated, you have to go back to chapter 2, "An Overview of Mac OS X", where there's more information on prebinding than in the "Memory" chapter itself. This despite the fact that prebinding has long been deprecated, and so is probably not essential for an "overview". Presumably the information in chapter 2 was written while Mac OS 10.3 was still current, and only lightly fixed up afterwards, rather than being merged in chapter 8. Of course, the book is too large for this kind of error to be easily spotted.

There's a decent look at the implementation of malloc(3) in the section "Memory Allocation in User Space", though it would have been better if Mac OS' heap implementation had been contrasted with at least the Doug Lea heap-based implementation in glibc. There's also a quick overview of Mac OS' 64-bit support, but since most libraries won't be 64-bit until 10.5, there's not much to say there. (It would have been a good idea to at least mention the Apple-suggested work-around of having a 32-bit process for any UI and a 64-bit process for number crunching, though.)

Chapter 9 is "Interprocess Communication", another apparent failure of the book's "systems approach". It starts with a tour of Mach ports and messages, switches to Unix signals with quick detours into asynchronous I/O and ptrace(2), touches on pipes and FIFOs, briefly mentions POSIX semaphores and shared memory, veers abruptly into Cocoa's Distributed Objects, moves on to AppleEvents, then back to Cocoa for mention of NSNotificationCenter, back to Mac OS' notify(3), across to BSD's kqueue(2), loops back through Cocoa to CFNotificationCenter and Core Foundation run loops, and ends with a section that mentions spin locks, Mach mutexes, Mach locks/lock groups/lock sets, Mach semaphores, and ends somewhat jarringly on advisory file locks. This is pretty much as bewildering as it sounds, being quite a hack through the jungle with little overall plan. Worst of all, there's the usual lack of comparison of the alternatives or discussion of their strengths and weaknesses. Sometimes there is obviously only one choice for what you're trying to accomplish, but often there are choices that might seem like they'll work but don't, and always there are choices that will lead to less portability, worse performance, or more complexity. This is ignored.

It's not a direct replacement for this chapter, but if you want a good book on the portable user-space subset of this chapter, Bill Gallmeister's "POSIX.4 Programmers Guide" from O'Reilly is one of the finest technical books I've ever read. If you're interested in kernel mechanisms, I actually think Apple's Kernel Programming Guide is better than this. (Apple's documentation quality is wildly variable. Some bits are perfunctory, others detailed and well-written. You never know which you're going to get. Sadly, there are few references to Apple's documentation in this book.)

The last few chapters are better than the rest. "Extending the Kernel" is the first time you feel you're benefitting from any kind of insight from the author, rather than just listening to someone list the order of functions called during some operation, something you could instrument the compiler to do if you cared. Apple's IOKit documentation is pretty good, but example code is always welcome, and semi-useful examples especially so. This is where the source to several of the author's various slashdotted examples appears. It's hard to shake off the feeling that you're really holding a two or three hundred page book on these articles, with a thousand pages of filler in front. Despite the C masquerading as C++ (the use of #define instead of typedef had me spluttering), these chapters are the best in the book. The "File Systems" chapter is good if you have an interest in Spotlight and its implementation, and even covers an alternative way in which it could have been implemented. The final chapter, "The HFS Plus File System" is along the lines of Apple's TN1150: HFS Plus Volume Format. The book is on the whole a little less detailed than the technote, but it does use a companion hfsdebug program (available from the author's web site) to show the various features in action.

The quality of the book's diagrams varied. Some were clear enough, but others would give Tufte a fatal apoplexy and start him spinning in his grave. If you like ten different sizes and styles of text per diagram, five different sizes and styles of arrowed lines, and text at a bewildering number of different angles, you'll love some of the examples in this book. I don't know what software the author used for this task, but it wasn't well suited to it. It certainly increased my appreciation of the usually very clear diagrams I've seen in O'Reilly books. Addison-Wesley need to pay more attention to this; the quality of the diagrams in their recent "File System Forensic Analysis" was exemplary.

The use of large numbers of short footnotes was also distracting. A more careful editor would have pressed for them to be eliminated or worked in to the text. The information content per footnote was very low; they served mainly as interruptions.

I realize that I'm something of a dissenter here. The book's web site currently has 5 glowing reviews, from Dominic Giampaolo, Jim Mauro, David Butenhof, Marc Rochkind, and Ulfar Erlingsson. I'm not convinced. In his praise, David Butenhof says "I've read just a few sections in detail, but skimmed through many". Rochkind's review admits "I'm only up to page 50". Page 50 is less than 10 pages in to chapter 2. What kind of a review is it, that doesn't involve actually reading the book? Giampaolo extrapolates from having read the file system and Spotlight stuff, but wasn't to know that they're the high points of the book. Erlingsson's "much of this information is not available anywhere else in a accessible form for an OSX audience, as far as I know" is probably because he's a Microsoft guy who doesn't spend a lot of time reading Apple documentation. Butenhof's "excellent comparison of HFS+ and NTFS"? Maybe he read a different book to me, because in my copy there's just a two-page table that might better be described as "superficial".

There are nuggets of gold in this book, but they're hidden in a wrist-breakingly dense forest of dead tree. This is neither a good introductory work nor a good reference work. There are several good books still to be written on Mac OS, but this is none of them, though it might be the beginnings of a good book on Mac OS kernel extensions and/or file systems.

2006-08-16

More universal binary joy with Xcode 2.4

I've said before how Apple's universal (fat) binaries have won me over. Xcode 2.4 adds support for x86_64. So given this trivial program:

$ cat test.cpp
#include <iostream>
int main() {
std::cout << "hello, world!" << std::endl;
return 0;
}

I can now build for four different architectures, from any of those architectures, as easily as I can build for just one of the architectures:

$ g++ -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch ppc -arch ppc64 -arch i386 -arch x86_64 test.cpp -o test

Even when my OS isn't sufficiently modern to recognize one of them (Mac OS/x86_64):

$ file test
test: Mach-O fat file with 4 architectures
test (for architecture ppc): Mach-O executable ppc
test (for architecture ppc64): Mach-O 64-bit executable ppc64
test (for architecture i386): Mach-O executable i386
test (for architecture cputype (16777223) cpusubtype (3)): data

If I try hard to find something to be sad about, it's probably the familiarity of the magic number:

$ hexdump -C test | head -1
00000000 ca fe ba be 00 00 00 04 00 00 00 12 00 00 00 00 |????............|
$ hexdump -C JavaTest.class | head -1
00000000 ca fe ba be 00 00 00 31 02 0f 0a 00 99 00 ff 07 |????...1......?.|

Shhh... I think I hear the world's smallest violin, playing just for me.

Ignoring Java for the moment, because Java side-steps the issue by making you rely on a JVM vendor to solve your architecture problems, and still sometimes leaves you needing to write multi-architecture JNI or stand-alone helper programs anyway, the last time I had multi-architecture support anything like this good was Plan 9.

Plan 9 had a separate compiler for each architecture, and used union mounts so that /bin/ was the union of architecture-independent executables (scripts) and executables for your current architecture. Your ~/bin/ had a subdirectory for each architecture you supported and you'd union mount other directories containing executables rather than adding them to your shell's path as you would on Unix. Distributing multi-architecture Plan 9 applications wasn't really an issue. Assuming you knew anyone else running Plan 9, you'd let them build from source.

Back to the present, Plan 9 is mostly forgotten and we're all using Linux. Compared to Linux, Mac OS' multi-architecture support is like a dream of the distant future. I can understand the Linux distributions' reluctance to go with fat binaries: I wouldn't like to have to pay Debian's bandwidth bill either, and I assume that's why the Debian Policy Manual states that all installed binaries should be stripped. The lintian(1) package-checking utility even complains if you have non-stripped binaries in a package (as we do). Apple ships binaries with debugging information, but they ship those binaries on DVDs that cost $120/year. Ubuntu's (not yet implemented) idea of having symbols downloaded as needed to make up for the distribution of stripped binaries is pretty cunning, but having to install your OS twice and mess about with chroot just to build for x86 and x86_64 is a pain. Having to build separate packages is a pain too, and I don't really get the argument about saving bandwidth and disk space here (as opposed to with debugging symbols) because in the short term you're just forcing the 64-bit users to download two whole distributions, and in the long run, everyone's just running 64-bit anyway.

Until the next big shift.

2006-08-05

Wacom Graphire 4x5

As a programmer, you perhaps wouldn't expect me to have much interest in graphics tablets. And it's not that I lead a secret double life: programmer by day, cartoonist by night. I haven't drawn or painted since they stopped making me do so at school, and my skill is about what you'd expect from someone who's never been trained or practiced. My drawing skills are limited to visual aids for solving geometry problems, and I have no particular interest in getting better until it becomes as easy as the "I know kung-fu" scene in The Matrix.

Although I do own a digital camera, I don't want to "have fun with [my] digital photos", which was another suggestion on the box. And I can type far faster than I can write, so the promise of being able to "annotate Microsoft Office documents" wouldn't be very tempting even if I had a Windows machine to run the Windows version of Microsoft Office (which is what they mean).

So why did I buy the bottom of the range Wacom tablet the other week?

One reason is because I've long been curious. I played with light pens in the 1980s, in the days when you built your own because it was interesting rather than because there was anything very useful I could do with one. I also owned a Newton in the mid 1990s. (Again, because it was interesting rather than because there was anything very useful I could do with one.)

The other reason is that I've never been entirely happy or comfortable with the mouse, but I've never found anything that was good enough to replace it.

The first thing I did was unclip the plastic cover and pull out the semi-transparent insert with the pictures of smiling children. Seriously. They deface their own product, but at least have the sense to make the mess removable. I don't know why they include it at all, and the thought of having something that ugly on my desk right in front of me almost lost them a sale.

Without the insert, the tablet looks odd, like it's not sure what generation it belongs to. It's obviously supposed to go with a Mac, but it's not clear which kind. The main body of the tablet is iPod/iBook/iMac shiny white. The stylus is a similar white with iPod-wheel-gray rubber areas, and similar colored plastic buttons. The scroll wheel on the tablet body is likewise click-wheel gray, but the two buttons either side are like the button on an Aluminium PowerBook. The USB cable is the ugly transparent kind with the metallic weave inside that Apple used for G3 desktop keyboards (I believe; that's before my time), and don't ask about the USB connector. It's transparent like the cheap PC knock-off peripherals at the time of the original CRT iMac.

Setting up

I connected the tablet to my PowerMac first, because I wanted to check it worked. I plugged it in, and everything just worked. I didn't try the accompanying CD because I don't like to install third-party crapware if I can avoid it. I still have 15 crappy applications lying around unused since the Canon MP500 printer needed me to install drivers for it. I'm perfectly capable of making a mess of my desktop by myself, thanks.

Really, though, I wanted the tablet on my Ubuntu box. That's been seeing more use lately. I plugged it in, and nothing worked. I asked Google, and found that I had to:

sudo apt-get install wacom-tools

Then I had to reboot. That gave me a /dev/input/wacom device. Necessary, but not sufficient.

I also had to make these changes to /etc/X11/xorg.conf:

--- /etc/X11/xorg.conf.20060731 2006-08-05 15:57:47.000000000 -0700
+++ /etc/X11/xorg.conf 2006-08-05 17:18:14.000000000 -0700
@@ -61,6 +61,41 @@
Option "ZAxisMapping" "4 5"
EndSection

+Section "InputDevice"
+ Driver "wacom"
+ Identifier "Wacom Stylus"
+ Option "Device" "/dev/input/wacom"
+ Option "Type" "stylus"
+ Option "USB" "on"
+EndSection
+
+Section "InputDevice"
+ Driver "wacom"
+ Identifier "Wacom Eraser"
+ Option "Device" "/dev/input/wacom"
+ Option "Type" "eraser"
+ Option "USB" "on"
+EndSection
+
+Section "InputDevice"
+ Driver "wacom"
+ Identifier "Wacom Cursor"
+ Option "Device" "/dev/input/wacom"
+ Option "Type" "cursor"
+ Option "USB" "on"
+EndSection
+
+Section "InputDevice"
+ Driver "wacom"
+ Identifier "Wacom Pad"
+ Option "ButtonsOnly" "on"
+ Option "Button9" "1"
+ Option "Button13" "3"
+ Option "Device" "/dev/input/wacom"
+ Option "Type" "pad"
+ Option "USB" "on"
+EndSection
+
Section "Device"
Identifier "NVIDIA Corporation NV37GL [Quadro FX 330]"
Driver "nvidia"
@@ -88,6 +123,10 @@
Screen "Default Screen"
InputDevice "Generic Keyboard"
InputDevice "Configured Mouse"
+ InputDevice "Wacom Stylus" "SendCoreEvents"
+ InputDevice "Wacom Eraser" "SendCoreEvents"
+ InputDevice "Wacom Cursor" "SendCoreEvents"
+ InputDevice "Wacom Pad" "SendCoreEvents"
EndSection

Section "DRI"

This isn't exactly like any of the suggestions I found on the web, which had a tendency to include stuff they didn't explain. You can find out a lot (but not everything) from the wacom(4) man page, which is seemingly only available on the web (and which I don't want to link to because I couldn't find a convincingly up-to-date source; search for yourself).

You seemingly add three input devices. The "stylus" type is for the sharp end of the stylus. The "eraser" type is for the "wrong" end of the stylus. The "cursor" type is for the "wireless mouse" that comes with the tablet. It doesn't require batteries because it's effectively just another stylus. It's a typical Windows mouse with two distinct buttons (without a seam, so what Apple's crappy "mighty" mouse could have been) plus a scroll wheel that acts as a middle button.

The "Mode" can be set to "absolute" or "relative", which aren't explained on the man page, but which seem to choose between modes where the tablet area corresponds exactly to the screen ("absolute") and a more mouse-like mode ("relative" where you can lift the stylus off and come back to any point without moving the cursor. In the latter mode, each quadrant of the tablet seems to correspond to the entire display. I'm honestly not sure which I prefer, so you might want to experiment. I have a suspicion that "absolute" might work better, but only if you can train your brain out of the "relative" mouse-like behavior.

Anyway, with a modified xorg.conf I restarted the X server and all was well. It's pretty sad this doesn't just work, though. Not quite as sad as the fact that the X server won't start without any input device connected (and in such cases produces so much output that it's not immediately obvious what the problem is), but it's sad all the same. Hopefully hotswapping of X11 input devices is something that will be fixed. Linux is still years behind Mac OS and Windows in this.

The most interesting part above is the "pad" input device. That corresponds to the tablet's scroll wheel and two surrounding buttons. I didn't manage to find working magic anywhere on the net, and what I show above doesn't work exactly right. The scroll wheel is inverted compared to a mouse scroll wheel, and that can't be fixed by mapping button 4 to 5 and vice versa, strangely. But having click and right-click on those big flat stable tablet buttons is much better than having them on the stylus. If I used the middle button more, I might map button 9 (the left tablet button) to button 2 (the middle mouse button) instead.

In use

So what's it like to use?

As a pointing device, it's pretty good. It has a much higher resolution than the light pens of the 1980s, and it doesn't suffer from the same sluggishness of the Newton. It's every bit as accurate and responsive as a mouse. I won't say it's as fast as a mouse, though, because I can't point as fast as I can with a mouse. ("Absolute" mode is faster, but only if I can remember I'm not in "relative" mode, which years of mouse-diddling makes difficult.)

I find I have to drag the stylus across the surface because if I aim while not in contact with the surface, I move the cursor too much as I come down to perform the click. This seems especially true of "relative" mode, for some reason. The buttons on the stylus (a large "middle" button and a small "right" button) are pretty hard to use, especially the "right" button, which for me is far the more useful. I hardly ever use the middle button, and still look forward to the day when X11's selection behavior curls up and dies. I find it almost impossible to right-click with the stylus button while the stylus is in contact with the tablet, and if I lift the stylus there's the drift problem I mentioned. There's also the fact that if you lift the stylus too far above the tablet, the stylus buttons don't work at all. So you can't aim while in contact with the tablet, lift, and then fire. The two big buttons on the tablet itself are a good workaround for this problem.

The stylus is also less than great for scrolling. It's pretty much like a non-wheel mouse. I'd rather use the page up and page down keys. I haven't managed to stop the built-in scroll wheel from behaving inverted, and it's also quite deeply recessed, and it's also centered on the top of the tablet. It would be better for me (as a right-hander) to have the wheel less recessed and on the left hand side of the tablet.

Speaking of hands, it's sometimes annoying that you have to use the stylus. It looks like a MacBook touchpad, so it's a shame it doesn't work like one. I find I spend a lot of time with the stylus balanced between my first and second fingers while I type, but it does hinder typing somewhat. And it takes a long time to pick up the stylus if you do give up and put it down.

The modern MacBook trick of letting you scroll with your fingers would be a major improvement. Scrolling is something I do a lot of, and the best and most comfortable way I've found of doing that is by stroking my thumb (oriented as if I were about to hit the space bar) across a touchpad.

As a text selection device, the tablet is a mixed bag. Even if you're one of those freaks who can stand drag-and-drop text editing when using a mouse, you'll be rushing to join the sane people who turn it off, should you try to use a tablet.

As a drawing device in GIMP, the tablet is pretty good. I can draw and write much better than I can with a mouse. I was a little surprised that the eraser is actually any tool I choose, but I guess that works well if you're actually doing real work (though surely the eraser tool would be a good default choice?). It's pretty weird to actually use the pressure sensitivity: it's quite an unnatural idea that pressing harder on a computer's input device actually makes a difference, because for the devices we grow up with that just isn't true. I'll admit I don't know what I'm talking about, but I reckon you can't live without one of these if you do any drawing.

But back to terminals, text editors, and web browsers, where I spend 99% of my time...

Using a tablet is a great way to find out where the applications you use are weak in terms of keyboard support or require excessively fine mousing skills. As long as I stick this experiment out, you can expect the applications I'm responsible for to improve in this regard. Where a poor choice of focus motion, say, is a minor annoyance for a mouse user, you really feel it when you have to fiddle about to find a pen.

Conclusion

Neither of us really liked the tablet as a general-purpose input device. After a month or so, we gave up and went back to mice.