To reply to a blog post, email me at Daniel_Burrows@alumni.brown.edu. Please let me know whether I should post your reply on the blog page.
Late last year, I spent some time disentangling aptitude's internal UI library and packaging it as a separate library, which I named cwidget. This article is the first in what will hopefully become a series describing the basic concepts and APIs of cwidget. It applies to the versions of cwidget currently available in Debian sid and lenny, 0.5.11-1 and 0.5.12-1. Autogenerated documentation of cwidget can be found here (but beware that as of this writing it is somewhat incomplete).
In this tutorial, I will walk through a simple program (hello.cc) that initializes cwidget, displays a simple message box, and then terminates the program when the user confirms the message. I assume a basic familiarity with C++.

The first thing to do is to include the portions of cwidget that our
program will use. Most importantly, we need the top level
cwidget routines. These are the global routines
that initialize cwidget, shut it down, and control its main loop
(among other things).
#include <cwidget/toplevel.h>
cwidget comes with a collection of stock dialog
boxes
for things like displaying messages to the user. To access
the routines that build these dialogs, we write:
#include <cwidget/dialogs.h>
All the symbols provided by the cwidget library are in the cwidget
namespace. Using the full library name means that there's a
reasonable chance that its names will not conflict with the names
provided by other libraries; however, it's a real pain to type
cwidget over and over. Since this is the only namespaced library we
are using in this program, it's handy to define cw as an alias for
cwidget:
namespace cw = cwidget;
Now we're ready to write the main routine. The first interaction of client code with the cwidget library is to initialize it. This will initialize the ncurses library and put the terminal into a mode suitable for a full-screen curses program.
cw::toplevel::init();
Next, we create a dialog box that will be displayed to the user. There are two things to note about this code:
cwidget is Unicode-aware and the
ok()routine expects the message string to be a wide-character string. In this case, that means that we need to pass in a wide-character string (indicated by typing
in front of the string).LThe second argument tells cwidget what to do when the
ok
button is pressed. The expressionsigc::ptr_fun(cw::toplevel::exitmain);creates a slot using libsigc++. Briefly, a slot is a reference to a function or to a method of a class instance. When invoked, this particular slot will call
cwidget::toplevel::exitmain(), which causes the main cwidget loop to exit. The slot is wrapped incwidget::util::arg, a utility function that handles passing slots as optional arguments.
cw::widgets::widget_ref dialog = cw::dialogs::ok(L"Hello, world!", cw::util::arg(sigc::ptr_fun(cw::toplevel::exitmain)));
Now that we have a widget, the next step is to arrange for it to
appear on the terminal. In cwidget, control of the terminal is
assigned to a single top-level
widget: whatever it displays is
what gets displayed on the terminal, and all user input is passed
directly to it. In a real program this widget will typically manage a
collection of sub-widgets and assign each one a screen region, but for
now let's just display the dialog box we created:
cw::toplevel::settoplevel(dialog);
With everything initialized, we're ready to start the main loop.
mainloop() will keep the display up-to-date and dispatch incoming
events (for instance, keystrokes and mouse presses) until exitmain()
is invoked.
cw::toplevel::mainloop();
When the user presses Enter or clicks on the Ok button in the dialog,
exitmain() will be invoked by the binding that we set up earlier.
Once this happens, we need to shut down cwidget in order to restore
the terminal to its original state. If you skip this step, the
terminal will be garbled and will not work properly when your program
exits.
cw::toplevel::shutdown();
And that's it! To compile the program, change to the directory containing hello.cc and run:
$ g++ -o hello hello.cc $(pkg-config --cflags --libs cwidget)
Of course, you'll need to have the g++ and libcwidget-dev packages installed for this to work!
Posted Fri Jul 4 13:03:00 2008So I've been inexcusably tardy in announcing this, but Obey Arthur Liu is working on aptitude for Google's Summer of Code program. His goal is to write a third interface to the program, using GTK+ to produce the UI; as the abstract for his project states:
I will create a GTK+ GUI for Aptitude that will work alongside improved current ncurses and command-line interfaces. This will offer an alternative to Synaptic with an interface design geared toward usability and advanced functionality.
I'm looking forward to seeing what he comes up with! I think there are a lot of interesting possibilities in the design space of GUI package managers; hopefully he'll have time to explore at least a few of them. At the moment he's focusing on figuring out the care and feeding of the apt library backend and learning some of the quirks you have to deal with when writing a frontend against it.
Arthur's blog can be found at http://www.milliways.fr and on Planet Debian. The Mercurial repository for his work can currently be found at http://dev.graffit.net/aptitude/hg/.
Posted Thu Jun 19 07:22:00 2008I've released version 0.4.11.4 of the aptitude
package manager (release
notes). The
main motivation for this release is bug #483920, which would
cause the resolver to choose solutions badly (e.g., it might prefer
downgrading a bunch of packages to keeping them at their current
versions). It also includes a simple fix for bug #136874, the
fact that the output of aptitude search is badly suited for scripts
(it still is, but now there's a command-line option that will make it
better).
Regarding the OpenSSL debacle, Julien Blache writes:
Worst Debian day ever since the 2003 compromise. And that was a BAD one.
I disagree. This is far, far worse than the 2003 compromise. The compromise was scary, but the key updates for users were straightforward and as far as we know, user security was never actually compromised. In contrast, every single user who uses Debian or Ubuntu for anything serious is now (Update: and has been for two years) vulnerable to attacks on their supposedly secure cryptography [0] unless they perform a labor-intensive and error-prone series of steps to regenerate all their cryptographic keys -- not to mention finding a secure way to distribute their public keys to everyone who needs them!
[0]: Update: I should perhaps make it clear that I mean anyone who generated a key on such a system. But in a way this makes things worse: unless you're willing to regenerate every key in sight, you need to check each key manually, which means that there's a nontrivial chance that you'll overlook one and leave yourself vulnerable...
Posted Wed May 14 08:10:00 2008We've spent the last week and a half moving out of the bizarre twilight zone known as Redmond into the city of Seattle proper. This cuts down on my commute tremendously (although poor Kate has to do the opposite of what I used to do each day), and it's great to be able to walk to the grocery store whenever I want. It may also mean that I'll cut back a bit on my Debian work in favor of actually having a life.
Half my stuff is still in boxes, so I'll be busy with this move for a while longer, but at least I have Internet and email access again now.
Posted Fri May 9 22:30:00 2008I talked to my mother last week about the upcoming Pennsylvania
primary (scheduled for tomorrow, April 22nd). She lives in the
semi-rural Pennsylvania town where I grew up, and so I asked her what
her impression was of how the locals felt about the campaign.
Well,
she said, they think the war is a disaster and they
don't want to vote for McCain because they think he'll continue it
forever. And of course they don't want to vote for a black man. And
they all hate Hillary and think she's evil. So they're having some
trouble trying to decide who to vote for; they can't figure out which
candidate they despise the least.
I've released version 0.4.11.2 of the aptitude package manager
(release
notes).
This is basically a bugfix release to clean out some problems that
were introduced in the previous release (most notably a nasty
problem in safe-upgrade).
Last weekend, I released version 0.4.11.1 of the aptitude package
manager (release
notes).
This is a minor release focusing mostly on bug-fixes and on a few
features that I've been meaning to add but that didn't make it into
0.4.11. I think the most interesting addition is --show-why, which
is like --show-deps but traces back to the closest manually
installed package.
In some wide-character locales, the fix for bug #472625 in this
upload of aptitude triggers bug #473874 and bug #474065
in apt; the symptoms are an error message about
on start-up, and messages saying that line N too long
(max 1024)
when you try to update the package lists
or install new packages. I've written patches to fix these bugs in
apt, and once they're reviewed by the other apt maintainers they
should be fixed in the next upload of apt (version 0.7.12). Until
then, if you're bitten by this bug, you can work around it by
diverting method http
has died unexpectedly!/usr/share/aptitude/aptitude-defaults.$LANG and replacing
it with an empty file. For instance, for Russian (ru):
# dpkg-divert --rename --local --divert /usr/share/aptitude/aptitude-defaults.ru.real --add /usr/share/aptitude/aptitude-defaults.ru
# echo > /usr/share/aptitude/aptitude-defaults.ru
Once a fixed apt is uploaded, you can remove the diversion like this:
# rm /usr/share/aptitude/aptitude-defaults.ru
# dpkg-divert --rename --local --remove /usr/share/aptitude/aptitude-defaults.ru
Posted Sat Apr 5 08:00:00 2008
On the Seattle Underground tour, they tell you about Seattle
spirit
, which boils down to:
If you've got a bad idea, stick with it!
A while back, I posted about how I had created a T-shirt with a cute little graph showing the decrease in Suck over time. I have yet to sell a single one, but I've had a similar graphic pinned up in my cubicle at work for a while, and several people there have told me they think it should go on a coffee mug. So what the heck, I spent some time today resizing the picture, and now you can get it on a mug, large mug, or stein.
Posted Sun Mar 16 14:39:51 2008I just happened to take a look at the output of a Web log analyzer and noticed a huge increase in traffic yesterday. I thought that was odd, since I hadn't written any new blog posts recently or published new stuff on my Web page. So I took a look at the logs themselves and noticed that a whole bunch of my recent hits listed their referer as planet.debian.net. This is where you start getting a sinking feeling...and yes, when I checked the Planet in a Web browser, sure enough, it looks like my whole blog got dumped out on the Planet. For some reason my own RSS reader didn't pick it up, so I wouldn't even have noticed if I hadn't been checking on my Web server stats.
I'm not sure why, but I bet it has to do with the fact that I upgraded ikiwiki yesterday. So if you've seen the new ikiwiki version that came out recently, take a little care when you update and make sure it doesn't impact your RSS feed.
Posted Sun Mar 16 12:08:00 2008I've released version 0.4.11 of the aptitude package manager (release notes). Due to ongoing work by the installer team, I uploaded this release to experimental rather than unstable; once things are clear I will upload a build to unstable (probably promoting the experimental cwidget to unstable at the same time). The initial upload accidentally left out libept support, so I'm preparing a new upload as I write this.
The aptitude search language and its documentation have gotten
particular attention in this release. The most visible change is the
introduction of a new syntax for search expressions: in addition to
the old style of
, you can now type ~i
.
Not only is this more readable and more memorable, it means that I'll
be much more able to expand the breadth of the query language: it was
becoming rather difficult to select new single-character flags for
search terms, so expanding the namespace is nice. On this note, a
number of search terms have been added to the language; see the
release notes or the
aptitude user's manual for details.?installed
PS: if you're wondering about the quote in the release notes: I just needed to vent a little about that incident in a way that I found amusing and harmless; I'm over it now, and hopefully this will be the last time I mention it in public.
Posted Sun Mar 16 11:54:00 2008Groklaw has a link up to an interesting interview regarding
behavioral economics
. I haven't listened to the
podcast, but the posted text is quite interesting. This line, in
particular, struck a chord with me:
Feeling that your work is useful, even if you know it's an illusion, has motivational power with respect to that work.
This resonates with some thoughts I've been turning over in my head lately. Back when I was in college, I thought my work in Debian was useful and I was really excited to work on it. I'd sit around thinking up new ways to improve the system and spend all my spare time hacking code to implement my ideas.
Then I graduated, and went into the real world, and got a job, and suddenly I discovered that working on Debian was not so much useful as it was worthless self-indulgence with no value to anyone but a small and marginal group of individuals. This sent me into a funk for a good year or so, during which time I released a few bugfix uploads for aptitude but didn't do much else free-software-related. I spent my time on the bus reading science fiction novels and computer science textbooks.
However, at some point last year I realized a couple things:
- In the grand scheme of things, the work I do for pay is no more important than the work I do for free. It might be more important to the people who pay for it, but to most of the world I simply don't matter no matter what hat I'm wearing, and I need to learn to live with it.
- At the end of your life, you're dead and no-one asks you whether you made yourself miserable enough by doing useful stuff, so you might as well do things you enjoy instead.
- The only practical effect of my delusions regarding Debian was that I spent my spare time hacking code and enjoying it, instead of playing video games and feeling like a loser.
- If there's any chance that I might ever have a kid, I certainly want to write free software now, while I don't have one. Based on observing my coworkers who have kids, it's pretty much impossible to be both a free software hacker and a parent: after the paid job and the kid, there isn't much time left over for writing code.
So, I decided to try deliberately believing a false thing: namely that my Debian work is valuable and worthwhile. And hey, it worked! I still know that what I'm doing is worthless, but I can convince myself otherwise for stretches of time, and I have enough fun while I'm working on the project that I consider it worth a small amount of unreality. It sure beats the heck out of computer games (which I still spend a distressingly large amount of time on). The doublethink aspect of it creeps me out, but I can't argue with the results.
The one problem is that this state of deluded motivation seems to be a bit fragile and is vulnerable to being popped by rude shocks. In December, I found myself mentally composing a letter in which I resigned from Debian to go spend my free time on stuff that was more gratifying, or at least where the expectations and (more importantly) level of abuse were commensurate with the pay and hours. As usual, I had enough sense to not follow through, and everything seemed less dire in the morning, but it was still weeks before I could bring myself to begin to think about spending my free time working on Debian.
Presumably the only way to avoid this is to find something to do in my spare time that I enjoy and that is actually meaningful to the world. But since I don't know of any activity that meets these criteria, I'll keep my self-delusion for the time being, thank you very much. At least I know I'm doing it -- I suspect that most people don't.
Posted Fri Mar 7 21:17:00 2008
The difference between the right word and the almost-right word is like the difference between the lightning and a lightning bug.-- Mark Twain
The Seattle Times recently ran an article on autism in which they mentioned that:
... a theory that thimerosal is to blame has been repeatedly discounted in scientific studies. (my emphasis)
I'm pretty sure from context that the journalist meant to say that the thimerosal link was unsupported, disproved, or possibly even debunked by scientific studies. But the one thing those studies didn't do was discount it, since that would indicate that they had dismissed it out of hand without considering the evidence!
Posted Thu Jan 31 06:14:00 2008I recently read a description for a 2.5-inch hard drive enclosure that said that it
comes with all the important features that are required in a portable hard drive – rugged anodized aluminum housing, shock proof, light weight, compact size, and choice of enclosure that includes bullet proof hardware encryption to protect your sensitive data.
(my emphasis)
So if someone puts a bullet through the hard drive, my data will be fine? Or are they just guaranteeing that no number of bullets shot at the drive will reveal the data stored on it?
Posted Sat Jan 19 22:06:00 2008A few months ago, I registered my first domain name ever. When you
want to register a domain, the first step is generally to enter the
domain you are interested in into a box; the registrar will then check
to see if the domain is not registered yet, and allow you to register
it if it's available. When I saw this, I thought to myself: huh, I
bet that if I were a registrar and I were evil, I would take domain
names that people ask about but don't register and register them
myself.
So I used the normal DNS lookup process to check hostnames
until I came up with one I liked, on the theory that they can't
possibly be registering every single lookup failure.
I really hoped that I was just being excessively paranoid, so it makes
me sad to learn that apparently my cynicism in this particular case
was entirely well-founded. Someday I want to
believe bad things about humanity and have them turn out to be
false. 