\subsubsection{Idea}

This recipe is very simple. We build an application with a single window that
contains a color well. There are two entries on the application's menu: one to
quit the application, and another to pick a color. The cursor changes to a red
target cursor when the user clicks the latter, and she may then copy the color
of any pixel on the screen to the color well by clicking on the pixel. The
color picker code is isolated in a function that is called {\tt
GSReadPixelFromScreen.} There is a controller class that acts as a delegate to
the application and responds to the action {\tt pick:}.

\subsubsection{Implementation}

Start with the usual include directives. We need the cursor font for the
target cursor. 

\begin{lstlisting}{}
#include <Foundation/Foundation.h>
#include <AppKit/AppKit.h>

#include <X11/Xlib.h>
#include <X11/cursorfont.h>
\end{lstlisting}

The function {\tt GSReadPixelFromScreen} picks a color in several steps:
\begin{itemize}
\item set the cursor to a red target cursor
\item grab the pointer
\item wait for a button-release event
\item release the pointer
\item fetch an image containing the pixel that was clicked
\item extract and return the color.
\end{itemize}
The first step is to obtain the current display and its root window.

\begin{lstlisting}{}
NSColor *GSReadPixelFromScreen()
{
    Display *display = XOpenDisplay(NULL);
    Window root = RootWindow(display, DefaultScreen(display));
\end{lstlisting}

We prepare the cursor from the font cursor with a target cross shape by
setting the color components of its foreground and background colors. The
foreground is red (RGB is $(\MAX, 0, 0)$) and the background white (RGB
$(\MAX, \MAX, \MAX).$) The color components are unsigned, so we get the
maximum value by using $-1$ without having to know the actual size of the
components.

\begin{lstlisting}{}
    Cursor cursor = XCreateFontCursor(display, XC_tcross); XColor fgc, bgc;

    fgc.red = -1; fgc.green =  0; fgc.blue =  0;
    bgc.red = -1; bgc.green = -1; bgc.blue = -1;
    XRecolorCursor(display, cursor, &fgc, &bgc);
\end{lstlisting}

The next step is to grab the pointer. No other application will receive button
clicks until we explicitly release the pointer. We must wait until the user
chooses a pixel, i.e. until {\tt XNextEvent} returns a button release, in
which case we release the pointer. We receive no other events because the
event mask argument to {\tt XGrabPointer} only includes button release events.

\begin{lstlisting}{}
    XGrabPointer(display, root, 0, ButtonReleaseMask, 
		 GrabModeAsync, GrabModeAsync, None,
		 cursor, CurrentTime);

    XEvent event;
    XNextEvent(display, &event); 

    XUngrabPointer(display, CurrentTime);
\end{lstlisting}

The location of the button press in root window coordinates tells us what
pixel to fetch. We ask the server for a one pixel image at that location and
read the pixel once we have the image. We may then free the image since it is
no longer needed.

\begin{lstlisting}{}
    XImage *ximage = 
        XGetImage(display, root,
		  event.xbutton.x_root, event.xbutton.y_root, 
		  1, 1, -1, ZPixmap);
    unsigned long p = XGetPixel(ximage, 0, 0);
    XDestroyImage(ximage);
\end{lstlisting}

We require the color components rather than the pixel value, so we query the
server for the color components of the selected pixel in the default
colormap. (We could have extracted the components from the pixel value
ourselves e.g. for {\tt TrueColor} visuals, but we choose to keep it simple.)

\begin{lstlisting}{}
    XColor result; result.pixel = p;
    XQueryColor(display, 
		DefaultColormap(display, DefaultScreen(display)),
		&result);
\end{lstlisting}

This concludes the definition of the color picker function. We have the color
components and use them to obtain the appropriate {\tt NSColor} object, taking
care to scale the values; $-1$ provides the maximum value for each component
when converted to an unsigned short integer.

\begin{lstlisting}{}
    #define MX ((unsigned short)-1)
    return 
	[NSColor colorWithDeviceRed:(float)result.red/MX
		 green:(float)result.green/MX
		 blue:(float)result.blue/MX
		 alpha:1.0];
}
\end{lstlisting}

It remains to implement the controller. It must assemble the window with the
color well after the application finishes launching and pick colors when the
user clicks the corresponding menu item.

\begin{lstlisting}{}
@interface Controller : NSObject
{
    NSColorWell *well;
}

- (void)applicationDidFinishLaunching:(NSNotification *)notif;
- pick:(id)sender;

@end
\end{lstlisting}

First define the dimensions of the window's content view, allocate the window
and initialize it with the title and the minimum size.

\begin{lstlisting}{}
@implementation Controller

#define WELLDIM 200

- (void)applicationDidFinishLaunching:(NSNotification *)notif
{
    NSRect wframe =
        NSMakeRect(0, 0, WELLDIM, WELLDIM);
    NSWindow *window =
        [[NSWindow alloc]
            initWithContentRect:wframe
            styleMask:NSTitledWindowMask | NSResizableWindowMask
            backing:NSBackingStoreBuffered
            defer:NO];
    [window setMinSize:wframe.size];
    [window setTitle:@"Pick"];
\end{lstlisting}

The well has the same size as the window's content frame and starts out
containing the color ``blue.''

\begin{lstlisting}{}
    well = [[NSColorWell alloc] initWithFrame:wframe];
    [well setColor:[NSColor blueColor]];
\end{lstlisting}

We place the well in the view hierarchy by making it the window's content
view. We are done with the window, so we center it and place it on screen.

\begin{lstlisting}{}
    [window setContentView:well];
    [window center];
    [window makeKeyAndOrderFront:self];
}
\end{lstlisting}

The action {\tt pick} is very simple: it invokes {\tt GSReadPixelFromScreen}
and sets the well's color to the color that it returns.

\begin{lstlisting}{}
- pick:(id)sender
{
    [well setColor:GSReadPixelFromScreen()];
    return self;
}

@end
\end{lstlisting}

The main function allocates an autorelease pool, the controller and the
application object.

\begin{lstlisting}{}
int main(int argc, char** argv, char **env)
{
    NSAutoreleasePool *pool = [NSAutoreleasePool new];

    Controller *con = [Controller new];

    NSApplication *app = [NSApplication sharedApplication];
\end{lstlisting}

The menu contains an entry that quits the application and another one that
invokes the color picker.

\begin{lstlisting}{}
    NSMenu *menu = [NSMenu new];
    [menu addItemWithTitle: @"Pick"
          action:@selector(pick:)
	  keyEquivalent:@""];
    [menu addItemWithTitle: @"Quit"
          action:@selector(terminate:)
          keyEquivalent:@"q"];
    [NSApp setMainMenu:menu];
\end{lstlisting}

It remains to connect the controller to the application and start the event
loop.

\begin{lstlisting}{}
    [app setDelegate:con];
    [app run];    

    [pool release];
    exit(0);
}
\end{lstlisting}
