2005/08/06

Passing arguments to Mac applications

I'm building a suite of cooperating, cross-platform GUI applications. They're written in C++, using Qt. I'd like to be able to pass command-line arguments from one app to another, but on OS X I've had trouble doing so.

Mac GUI applications typically are launched via NSWorkspace (or, for non-Cocoa apps like the ones I'm building, via the underlying CoreFoundation functions). They're launched with no argv entries. Arguments typically consist only of pathnames to open or print, etc. Accessing them is no picnic.

The simplest solution I've found uses environment variables to pass the arguments around. It works on Unixes including OS X. It should work on Windows.

One gotcha is that you have to explicitly retrieve the environment arguments when your GUI app starts up, instead of having them initialized for you by the C/C++ runtime.

Another gotcha is namespace collisions. The names of the environment variables conveying the arguments must be chosen carefully to prevent them being used/modified by unrelated applications. Maybe some sort of Java-like "com.dmoonc.my_app_suite..." convention would be appropriate.

Anyway, this is probably good enough for now:

envargs.h


#ifndef ENVARGS_H
#define ENVARGS_H

#include <string>
#include <vector>

typedef std::vector< std::string > ArgList;

// Retrieve and clear the environment arguments
// passed to this process.
// Should be done as soon as possible
// after application launch.
void getEnvArgs(ArgList& args);
ArgList envArgs();

// Set environment arguments for passing
// to a process about to be launched.
void setEnvArgs(ArgList& newArgs);

#endif // ENVARGS_H


envargs.cpp


#include "envargs.h"
#include <iostream>
#include <sstream>
#include <stdlib.h>

using namespace std;

static const string C_NumArgsName("_appsuite_numargs");
static const string C_ArgPrefix("_appsuite_arg_");

void getEnvArgs(ArgList& args)
{
args.clear();

char *numArgsCStr = getenv(C_NumArgsName.c_str());
if (numArgsCStr)
{
istringstream ins(numArgsCStr);
int numArgs;
if (ins >> numArgs)
{
for (int i = 0; i < numArgs; ++i)
{
ostringstream argname;
argname << C_ArgPrefix << i;

const char *argnameCStr = argname.str().c_str();
char *argCStr = getenv(argnameCStr);
if (argCStr)
{
string arg(argCStr);
args.push_back(arg);
}
else
{
args.push_back("");
}
}
}
}
}

ArgList envArgs()
{
ArgList result;
getEnvArgs(result);
return result;
}

static bool cppsetenv(string name, string value)
{
bool result = true;
ostringstream spec;
spec << name << "=" << value;

result = (0 == putenv((char *)(spec.str().c_str())));
if (!result)
{
cerr << "Could not set environment variable:" << spec << endl;
// TO DO: Ditch the bool return value and throw an exception
}
return result;
}

static bool cppsetenv(string name, unsigned int ivalue)
{
ostringstream svalue;
svalue << ivalue;
return cppsetenv(name, svalue.str());
}

void setEnvArgs(ArgList& newArgs)
{
if (cppsetenv(C_NumArgsName, newArgs.size()))
{
for (unsigned int i = 0; i < newArgs.size(); ++i)
{
ostringstream name;
name << C_ArgPrefix << i;
cppsetenv(name.str(), newArgs[i]);
}
}
}

2005/08/03

RSS News Readers: Extrapolation

This claim is false:

"When people get an RSS feed, they need not go through standard Web site navigation patterns that we are accustomed to tracking. They look at just what they want, when they want."

The same claim could be made for the early web. The problem is not looking at what you want. The problem is finding what you want to look at.

What (I Hope) Is Next For RSS News Readers


RSS news readers help you find and read content which is of interest to you. They face challenges.

RSS Advertisements


News readers will become less useful if they cannot help you filter out RSS advertisements.

Redundant Articles


I already wish news readers could perform higher-order aggregation. My subscriptions reflect my interests, so they have significant content overlap. Just this morning, for example, I must have seen about ten different news items all providing roughly the same information about Mighty Mouse.

I wish my news reader could at least identify and group together "duplicate" articles such as these, so I could deal with them all at once. Click on one to read it, mark the others en masse as having been read, move on.

I wish I could use my system's standard search tools (Spotlight for me, who knows what for Longhorn^WVista users) to search through old feed articles.

Not to be a shill for Brent Simmons, but the full version of NetNewsWire seems to have begun to address these wishes.

It's nice that my most original ideas have already been had by others.

Soldier's Grove: Energy efficient public policy

WorldChanging: Another World Is Here: Disaster Recovery Done Right

"
Rather than rush to get buildings up and running as quickly as possible, the villagers took their time...

The village passed ordinances stipulating that new buildings be built to specific thermal performance standards and obtain at least 50 percent of their heating needs with solar systems...
"

2005/08/02

Eco-friendly foam increases shuttle foam shedding

Shuttle Foam Loss Linked to EPA Regs

'"NASA chose to stick with non-Freon-based foam insulation on the booster rockets, despite evidence that this type of foam causes up to 11 times as much damage to thermal tiles as the older, Freon-based foam," warned space expert Robert Garmong just nine months ago."'

2005/08/01

Successor to the Shuttle?

SafeSimpleSoon.Com

Seems pretty retro: a crew capsule sitting atop a booster, designed for automatic stability during re-entry and equipped with an escape rocket during departure. But it's supposed to be all new...

[update 2005/08/18]

Wired has a related article this morning, describing the progress of tSpace in their development of a new Crew Transfer Vehicle. They've used $6 million in NASA funding and have actually developed working hardware.

My favorite bit concerns new NASA administrator Michael Griffin, who according to the article said he "would buy rides for NASA astronauts on privately owned spaceships."

Inside Kyoto

Wired News: U.S. Spearheads New Climate Pact

"However, Kyoto excludes developing nations such as China and India, home to a third of humanity, from a first period of targets to 2012. Both have ratified Kyoto and promised to take part in talks to widen the pact beyond 2012."

2005/07/28

Behind Kyoto

New Scientist Breaking News - US-led emissions pact seen as Kyoto rival

"The world’s four largest coal-consuming countries have announced a pact to share technology for limiting emissions of greenhouse gases."

"The new pact ... allows the countries to set their own goals for emissions of greenhouse gases, with no enforcement measures."

According to the article, Australia pulled out of Kyoto even though the protocol would have allowed Australia increase its emissions by 8% between 1990 and 2010.

"[The signatory nations'] companies will now hope for increased access to Asian markets for their technologies."

"There is speculation that the new group will seek to reach a formal agreement with the signatories to the Kyoto Protocol. Such an agreement might allow companies from the new group who sell clean technologies to developing countries to gain carbon permits that could be traded with companies operating under the Kyoto Protocol."

2005/07/27

Beyond Kyoto

U.S. to announce 'Beyond Kyoto' greenhouse pact - Yahoo! News

"...the United States and Australia have never ratified the [Kyoto] protocol because it excluded major developing nations such China and India."

"Australian Environment Minister Ian Campbell said on Wednesday that the five countries had been quietly working on the pact for months.

'It's quite clear the Kyoto protocol won't get the world to where it wants to go ... We have got to find something that works better[...],' Campbell told reporters on Wednesday."

"...analysts say the protocol is of limited use because many signatories are already above their emission targets."

Nations as a whole may be exceeding their targets, but – just as there are pockets of low entropy in the universe – some places are producing lower emissions than others:

"Greenhouse gas emissions last year in Multnomah County, which includes Portland, dropped below the level of 1990, and per capita emissions were down 13 percent.

The city has also built 750 miles of bicycle paths, and the number of people commuting by foot or on bicycle has increased 10 percent."

2005/07/03

Sweden, Subobia, Kuwait: Civic Lessons

Treehugger: Biogas-Powered Train in Sweden

I worked in Linköping in the early 1990s. This small city in southeastern Sweden was remarkably different from my home of the time, Huber Heights, Ohio.


Miljö Vänlighet

Many of my coworkers in Linköping rode bicycles to work, even in the wintertime. They'd emerge from their offices in the afternoon darkness to stretch dry, warm cloth covers over the frozen bicycle seats. Then they'd strap their briefcases onto the cargo racks and disappear into the streets of hard-packed snow, trench coats tucked tight around them.

Those who didn't ride bicycles complained about their government's inconsistent social engineering efforts. "They have raised the price of bensin to encourage the use of public transportation. And now they have raised the price of public transportation."

We consultants, of course, had a rental Saab 900. In the summertime we might walk to work along the local canal, but in the winter we'd hustle a block to the parking lot, pile into the Saab, and enjoy the electrically heated seats during our ten-minute commute.


Outer Subobia

Back in the States my neighborhood was designed for cars, clotted with automobiles. It could take 20 minutes to get to the supermarket 2 miles away. Walking or bicycling anywhere seemed foolishly dangerous. Biking to work was out of the question. Far better to join the rush of semis and GM boatmobiles on the local highways.


Warped

Popular Science and the 1973 energy crisis had made a strong impression on me. So I had been delighted when my parents bought a 1976 Honda Civic, touted for its efficient CVCC engine (two combustion chambers per cylinder!) and top-notch engineering.

A few months later, after several blown head gaskets, a heat-warped aluminum head and a complete engine overhaul, my parents sensibly traded the Honda for a 1978 Ford Granada.

Unlike my parents I hadn't much regard for reality. And I had only contempt for the Granada, its hideous 3-box design and its crappy fuel economy. The car was disgusting then, and for the nearly fifteen years afterwards in which it ran without failure.

The CRX

Our family's experience with Honda automobiles had been bad. But I continued to admire Honda's efforts to produce fuel-efficient designs.

In 1983 rumors started circulating about a two-seat Honda design which would deliver 50 mpg on the highway and reach speeds of over 90 mph. The rumors proved true when the CRX HF appeared on the market. If I ever managed to buy a brand-new car, this would be the model.

In 1990 I got my chance. Lots of overtime and per diem from the Swedish contract had filled the bank account. In July I pulled out the yellow pages and called the local Honda dealerships.

It didn't take long to find a dealer with a CRX HF in stock. Within a few days the deal was done, and I started getting to know my new car.

Unlike the first Honda our family had owned this one lived up to its promise -- and then some: The EPA said the HF would get 52 mpg on the highway. It sometimes topped 60 mpg. It accelerated as well as my previous car, and had much better handling.

The CRX was all I'd hoped for. It fed my appreciation for design optimization. And, against the backdrop of continued visits to Sweden, it amplified my growing environmentalist-consumer smugness.

Kuwait

About a week after I bought the CRX, Saddam Hussein invaded Kuwait. Driving to work, I saw no signs of awareness. Hadn't anyone heard President Bush's warnings about the implications of the invasion for the U.S. oil supply? Vans and trucks and semis rammed the air aside, 10-15 mph above the speed limit, carrying only their drivers, blithely ignoring the cubic increase in power required to reach higher speeds.

You can imagine how smug I felt as they barreled past me :)

2005/06/18

Managing Finder Workflows

With the new Automator in Mac OS X 10.4 it's easy to add contextual menu items to the Finder. Just edit your workflow in Automator, Select "File->Save As Plug-in...", enter a name for the plug-in, and specify that the plug-in is for Finder. (Apple has posted some examples of how to create plug-ins.)

It's easy to add a workflow menu item. How do you remove one?

Intuition says that your personal workflows might be represented as files somewhere in your home directory. Finder's new Smart Folders should tell whether that's really the case.

Create a dummy workflow named "DeleteMe" and save it as a Finder Plug-in. Then switch to the finder and select "File->New Smart Folder". In the little brushed-metal "toolbar" which appears, select the "Home" folder. In the criteria list add the following criteria:

"Kind", "Any", "+"
"Last Modified", "Today"

Somewhere in the list of search results a Folder named "Finder" should appear. Hitting the info icon on that item doesn't tell much, but the "More Info..." button reveals that it's located in /Users/YourUsername/Library/Workflows/Applications/Finder. And lo, opening the folder shows an Automator Workflow named "DeleteMe".

Drag the workflow to the trash, right click anywhere in a Finder window, and select the "Automator" cascading menu item. The "DeleteMe" menu item should be gone.

The Short Form

Workflow menu items live in your ~/Library/Workflows/Applications/ folders. They can be removed from your context menus by dragging them to the trash.

There's probably a better way to discover all of this...

2005/06/16

Birds and wind farms

New Scientist News - Wind turbines a breeze for migrating birds

Migratory birds learn to avoid wind farms, at least in Denmark. But resident birds may not fare so well. For example, the wind farm in the Altamont pass in California has killed a lot of raptors.

The subsections in the reports on the Wind Power and Bird Studies page suggest there may be other environmental factors, e.g. grassland vs. desert vs. prey populations.

2005/06/12

Godfather of the Hybrid

According to TreeHugger, Victor Wouk has passed on.

I wasn't familiar with the name. Caltech, where he attended graduate school, provides more details. This year they hosted the inaugural Victor Wouk Lecture.

A Rich Life


The American Institute of Physics gives some idea of all the things Wouk accomplished.

He picked Caltech, in part, because they had open book exams. During WWII he worked on the separation of uranium isotopes. For the founder of Motorola, Russell Feldman, in the early 1960s he worked on designing a practical electric car. He eventually concluded that a hybrid vehicle would be more practical.

In 1970 the Clean Air Act was passed, following studies which showed the negative effects of smog. Wouk got a federal grant to build a hybrid electric vehicle. He built a Buick Skylark which got 30 mpg and could hit 85 mph. (But it didn't run on water. [1])

The EPA's Eric Stork opposed the hybrid approach. (I wonder why?) Only one car was built by Wouk and his company, Petro-Electric Motors.

Scientific American, Oct. 1997, pg. 71 makes reference to the Skylark.

The rest of his family has done alright, as well. His brother is author Herman Wouk.

[1] From the first season of "That 70's Show".
Hyde: "I heard about a car that runs on water, man."
Fez: "You mean a boat?"

2005/06/11

Dr. Sarah's Sum of Two Cubes Activity Sheet

Dr. Sarah's Sum of Two Cubes Activity Sheet

Obscure mathematics references may explain the demise of Futurama.

Installing PyOpenGL on Mac OS X 10.4.1

Update 2007/02/26



Mike Fletcher has been working on PyOpenGL 3, which uses ctypes instead of swig. As a result, installation and updating are a lot easier. See the SourceForge project page for more info, but here's a quick summary:

$ sudo easy_install PyOpenGL
Password:
Searching for PyOpenGL
Reading http://cheeseshop.python.org/pypi/PyOpenGL/
Reading http://pyopengl.sourceforge.net/ctypes/
Reading http://sourceforge.net/project/showfiles.php?group_id=5988
Reading http://cheeseshop.python.org/pypi/PyOpenGL/3.0.0a5
Best match: PyOpenGL 3.0.0a6
Downloading http://downloads.sourceforge.net/pyopengl/PyOpenGL-3.0.0a6.zip?modtime=1171556482&big_mirror=0
Processing PyOpenGL-3.0.0a6.zip
Running PyOpenGL-3.0.0a6/setup.py -q bdist_egg --dist-dir /tmp/easy_install-9bs-Ie/PyOpenGL-3.0.0a6/egg-dist-tmp-1Y8vWy
Adding PyOpenGL 3.0.0a6 to easy-install.pth file

Installed /Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/PyOpenGL-3.0.0a6-py2.5.egg
Processing dependencies for PyOpenGL


You can also install and run the demos:
$ sudo easy_install PyOpenGL-Demo


Once they're installed, how do you get at them?

$ cd /Library/Frameworks/Python.framework/Versions/Current/lib/python2.5/site-packages/PyOpenGL_Demo-3.0.0a6-py2.5.egg/PyOpenGL-Demo/
$ cd redbook
$ python movelight.py


Each demo pops up in its own lovely, top-level window.

Original Post



After upgrading to Mac OS X 10.4.1 I decided to install Python 2.4.1. Python made a framework install with no problem. But I ran into a small problem trying to install PyOpenGL-2.0.1.09.


I kept getting compile errors complaining about an incomplete definition for st_atimespec, et al. (Here comes another batch of extremely long lines...)





In file included from /Library/Frameworks/Python.framework/Versions/2.4/include/python2.4/pyport.h:155,
from /Library/Frameworks/Python.framework/Versions/2.4/include/python2.4/Python.h:55,
from src/config.h:1,
from _configtest.c:6:
/System/Library/Frameworks/Kernel.framework/Headers/sys/stat.h:225: error: field 'st_atimespec' has incomplete type
/System/Library/Frameworks/Kernel.framework/Headers/sys/stat.h:226: error: field 'st_mtimespec' has incomplete type
/System/Library/Frameworks/Kernel.framework/Headers/sys/stat.h:227: error: field 'st_ctimespec' has incomplete type





What was odd was that the build process was trying to include sys/stat.h from .../Kernel.framework/Headers, instead of from /usr/include.


I modified config/darwin.cfg and removed /System/Library/Frameworks/Kernel.framework/Headers from the list of include directories, and thereafter PyOpenGL built and installed without error.


The examples ran, too :)


Here's the context diff for config/darwin.cfg. Apologies, again, for the long lines -- I've tried to escape them using trailing backslashes.





*** darwin.cfg.orig Sat Jun 11 12:09:35 2005
--- darwin.cfg.new Sat Jun 11 12:19:42 2005
***************
*** 11,17 ****
[General]
build_togl=0
gl_platform=CGL
! include_dirs=/System/Library/Frameworks/OpenGL.framework/Headers:/System/Library/Frameworks/GLUT.framework/Headers:/System/Library/Frameworks/Kernel.framework/Headers
# Bob's OSX patch, comments out the library directories, adds -framework:GLUT
# for the *general* build parameters? Is that actually needed?
; Should make a 'frameworks= ' option!
--- 11,17 ----
[General]
build_togl=0
gl_platform=CGL
! include_dirs=/System/Library/Frameworks/OpenGL.framework/Headers:/System/Library/Frameworks/GLUT.framework/Headers
# Bob's OSX patch, comments out the library directories, adds -framework:GLUT
# for the *general* build parameters? Is that actually needed?
; Should make a 'frameworks= ' option!



2005/06/10

Trac, clearsilver and Python 2.4.1

Trac is an excellent web-based issue tracking system. It depends on clearsilver.

Clearsilver 0.9.14 doesn't like to configure with Python 2.4, due to changes in the internals of Python's site module.

The fix is easy enough, but for some reason it's hard to find via Google. (You can find it by searching for Python 2.4 within clearsilver's Yahoo Groups discussion forum.) Here's a context diff for clearsilver's configure script, showing the fix that worked for me. Apologies for the long lines...


*** configure Tue May 24 16:28:58 2005
--- configure.orig Tue May 24 16:24:45 2005
***************
*** 3084,3091 ****
PYTHON=$python_bin
PYTHON_INC="-I$python_inc"
PYTHON_LIB=$python_lib
! PYTHON_SITE=`$python_bin -c "import sys, os; print os.path.join(sys.prefix, 'lib', 'python%s' % sys.version[:3], 'site-packages')"`
! # PYTHON_SITE=`$python_bin -c "import site; print site.sitedirs[0]"`
BUILD_WRAPPERS="$BUILD_WRAPPERS python"
fi
fi
--- 3084,3090 ----
PYTHON=$python_bin
PYTHON_INC="-I$python_inc"
PYTHON_LIB=$python_lib
! PYTHON_SITE=`$python_bin -c "import site; print site.sitedirs[0]"`
BUILD_WRAPPERS="$BUILD_WRAPPERS python"
fi
fi


Here is the relevant discussion thread.

2005/06/09

Wired News: Tiger Tweaks Could Kill Folders

Wired News: Tiger Tweaks Could Kill Folders

A mantra from the late '90s: It's better to search than to browse.

"...he used Spotlight to find all the bulky QuickTime movie files scattered across many different folders. Then he created a Smart Folder for them so he'd always be able to quickly see which little-used files he could delete."

2005/06/07

WebObjects 5.3 is bundled with XCode

WebObjects 5.3 Release Notes

See previous post -- too much to learn.

Among others, Aaron Hillegass has praised WebObjects. He has held it up as a standard against which to measure recent changes to Cocoa (and its Controller layer), and has sometimes found the latter lacking.

Haven't yet had a chance to do much with CoreData and the modeling tools in XCode 2.0. Now XCode 2.1 may help me understand what the fuss was all about.

Fun times.

Webkit is wide-open

Surfin' Safari

My list of things to learn was big enough before reading this...