How do I add a css class to body from a page callback function? I have a module that produces a lot of pages. A set of these are handled by a particular part of my application, and I would like all these to have a class added to either html or body. I'd settle for #block-system-main.

The existing answers point to a template preprocess hooks e.g. hook_preprocess_html() but this feels wrong.

I'd have to create that hook and then tell it to go somewhere else to determine which page call back was used and which class to apply - it's all backwards. Drupal's already selected the right callback, so a 2nd lookup is another thing to maintain and an inefficiency.

I could of course do something like set a global $extra_page_classes variable and then implement the hook to add these classes to the page, which is more efficient but it's still messy. Or I could add (yet another) wrapping &lt;div&gt; to my callback output, but that's not going to give a themer chance to adapt the rest of the page elements outside of the main content.

Seems odd that a page callback, responsible for the substantial content of the page, can't set page-level attributes. A page callback can, for example, choose to call drupal_add_css(), but it (apparently) can't do something as simple as add a class to the page.

As it seems odd and Drupal usually has some (often hidden) elegance, I thought I'd ask specifically if there was a better way.
Well, I think your confusion comes from the D7/D6 fact that a "page" has little clue whats going on around it. As you've said the page callback function tells drupal "what goes in the $content" but not what adornments happen on the page HTML DOM around $content.

To my knowledge unless your using Panels, Context or something else to share "page state" through components of your site -- this is simply how D7 simply works.

Without using context, panels, etc. I usually end up looking for url paths or NIDs or custom content array attributes #project-add-body-classes in hook functions to fire off my logic.

For what you describe I would use hook_html_alter() and look for a page path to alter the body_classes array as needed.