Scripting the BeOSScot Hacker, 10/99
I'm caught in a double-bind. I have no real programming experience, but lots of itches to scratch. Fortunately, I've found scripting possibilities galore in BeOS, and have approached dozens of small computing problems with home-brew shell and perl scripts. I've also discovered ways to control and automate BeOS applications in ways that are difficult -- if not impossible -- on other operating systems.
The BeOS Scripting ArchitectureOne of the great things about scripting (on any platform) is that it gives non-programmers the ability to solve a specific problem quickly, with little training. Scripting for BeOS is both identical to and very different from scripting for other platforms. In the sense that it's identical, you've got your standard languages -- bash (BeOS is POSIX-compliant), perl, Python, Tcl, REXX, Squirrel, etc. Scripts written in any of these languages will typically work in BeOS just by changing a path or two. If existing scripts call on system tools that lay outside of the scripting language itself, one must either make sure those tools are installed, or create similar functions using similar tools (nearly all bash tools common to the UNIX world are also available on BeOS, so this usually isn't much of a problem).
But there's another sense of scripting that's quite unique to BeOS, and this involves automating or controlling the behavior of GUI applications, rather than command-line tools. Yes, certainly it's possible to script the behavior of some GUI applications on most operating systems with some languages. But if you want to control a MacOS application via AppleScript, the application in question must be AppleScript-enabled. If you want to control that same application with another language, you're out of luck. Similarly, if you want to control a Linux application via a certain language, that application must be constructed specifically to receive messages from that language. If you later want to switch to another language, you'll probably be out of luck. In all cases, a scriptable GUI application must be constructed with scripting in mind, and even then, with a particular scripting language in mind.
Things work differently in BeOS. Behind the scenes, a flurry of "BMessages" are being continually passed, bounced around between applications and the OS, and between applications and each other. Whereas a Windows programmer might need to learn different parts of the API to implement drag-and-drop, cut-and-paste, or to intercept information regarding some current state of the OS or another app, the BeOS programmer just learns to work with the relatively simple BMessage object, which gives her control over all of these behaviors and more.
Meanwhile, all BeOS GUI applications automatically include a suite of scriptable "hooks" -- application objects that can be controlled by incoming BMessages, whether they originate from within the application itself or from another application or script. Of course, applications don't automatically expose every possible function to the outside world -- that could be dangerous. However, developers are free to publish a suite consisting of any range of application behaviors. The important thing to note here is that this suite of application hooks is language-neutral. The applicaton doesn't give a tinker's cuss whether it receives a BMessage that originated from a Perl, Python, or Tcl script. The BeOS GUI scripting model is language-neutral by definition.
Because both the BMessage object and the application hooks are exposed to the BeOS scripter as well as to the C++ programmer, boundaries that typically separate programmers from scripters on other operating systems are somewhat blurred for BeOS users.
Hey, Do SomethingOf course, cross-platform scripting languages don't know jack about BMessages by default. To speak to hooks in BeOS GUI apps from within bash scripts, all you have to do is invoke a command-line utility called hey, by Hungarian programmer Attila Mazei. With hey in your path, you can learn a given application's scriptable hooks by typing:
hey ApplicationName getsuiteshey will return a catalog of named scriptable suites. Digging through hey's documentation a little, and asking hey to tell you what you can do with the application's window frame, you find that you can change its position on-screen. So let's say you have a StyledEdit window open on a document called "lee" and you want that window to "walk" diagonally down across your screen (which might be useful for creating self-running BeOS demos). You'd use something like this:
#!/bin/sh # Starting coordinates for top left and bottom right # corners of StyledEdit window: TopLeft=50 TopDown=50 BottomRight=300 BottomDown=300 # Loop until the bottom of the window is at the bottom of the screen while [ $BottomDown -lt 768 ]; do # Send a BMessage via hey. hey StyledEdit set Frame of Window "lee" to \ "BRect($TopLeft, $TopDown, $BottomRight, $BottomDown)" # Add ten pixels to value of each variable TopLeft=$(expr $TopLeft + 10) TopDown=$(expr $TopDown + 10) BottomRight=$(expr $BottomRight + 10) BottomDown=$(expr $BottomDown + 10) doneA very simple bash construct is all it takes -- a "while" loop that continues until the window has reached the bottom of the screen (for a monitor set to 1024x768 resolution). And right smack in the middle of the loop, you shoot a BMessage off through the OS, to be intercepted by the StyledEdit application.
And if you want to use Perl rather than bash? No problem. You just invoke hey via Perl's built-in ability to send messages to the system. I'm currently in the process of writing a Perl-based system for controlling the BeOS audio application SoundPlay remotely. I use calls like this:
system "hey SoundPlay set pitch of track 0 to $pitch" if ($pitch ne "");Where $pitch is a value trapped in the URL of a web page after selecting a pitch from a Web-based interface. Yes, of course you can do similar things on other OSes by sending system commands to command-line tools. But the cool thing is, SoundPlay is a GUI application without any kind of command-line interface. The possibilities are pretty inspiring.
Database ExtractionSome of the coolest BeOS scripts I've seen involve the use of filesystem attributes, which (as you recall) can be used to associate any type or amount of meta-data" to given filetypes. This data can, in turn, be queried through the system's Find panel or from the command line, essentially treating the filesystem like a database. BeOS People files store name, address, telephone number, and other information in attributes. BeOS bookmark files store URLs, titles, and keywords in attributes. BeMail messages store subject, sender, status, and other data in attributes. And of course users have their own collections of custom filetypes with custom attributes.
By querying for or extracting this data from within BeOS scripts, users are able to develop Web-based Rolodexes on their BeOS machines at home that can be accessed from anywhere on the planet. Similarly, people are developing web-based systems for reading e-mail on a remote BeOS machine with more sifting and sorting capabilities than are possible on other OSes. The remote MP3 playback system mentioned above lets users create custom playlists by running BeOS filesystem queries from a browser interface. And as I've discussed here before, the BeOS Tip Server generates tip pages on-the-fly by extracting attributes into Web pages via Perl. Users can add the Be::Query module from CPAN to enable their Perl installations for this functionality. Meanwhile, Chris Herborth is about to release a set of attribute modules for his BeOS Python port. A forthcoming version of the increasingly popular cross-platform REBOL scripting language is also about to gain attribute support.