attempt to begin mac shell



git-svn-id: http://skia.googlecode.com/svn/trunk@30 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/experimental/CiCarbonSampleMain.c b/experimental/CiCarbonSampleMain.c
new file mode 100644
index 0000000..c1e1dc7
--- /dev/null
+++ b/experimental/CiCarbonSampleMain.c
@@ -0,0 +1,469 @@
+/*
+
+File: main.c
+
+Abstract:   Main event loop and app handling code is found in here.
+
+Version: 1.0
+
+� Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+IMPORTANT:  This Apple software is supplied to 
+you by Apple Computer, Inc. ("Apple") in 
+consideration of your agreement to the following 
+terms, and your use, installation, modification 
+or redistribution of this Apple software 
+constitutes acceptance of these terms.  If you do 
+not agree with these terms, please do not use, 
+install, modify or redistribute this Apple 
+software.
+
+In consideration of your agreement to abide by 
+the following terms, and subject to these terms, 
+Apple grants you a personal, non-exclusive 
+license, under Apple's copyrights in this 
+original Apple software (the "Apple Software"), 
+to use, reproduce, modify and redistribute the 
+Apple Software, with or without modifications, in 
+source and/or binary forms; provided that if you 
+redistribute the Apple Software in its entirety 
+and without modifications, you must retain this 
+notice and the following text and disclaimers in 
+all such redistributions of the Apple Software. 
+Neither the name, trademarks, service marks or 
+logos of Apple Computer, Inc. may be used to 
+endorse or promote products derived from the 
+Apple Software without specific prior written 
+permission from Apple.  Except as expressly 
+stated in this notice, no other rights or 
+licenses, express or implied, are granted by 
+Apple herein, including but not limited to any 
+patent rights that may be infringed by your 
+derivative works or by other works in which the 
+Apple Software may be incorporated.
+
+The Apple Software is provided by Apple on an "AS 
+IS" basis.  APPLE MAKES NO WARRANTIES, EXPRESS OR 
+IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED 
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY 
+AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING 
+THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE 
+OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL APPLE BE LIABLE FOR ANY 
+SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL 
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 
+OF USE, DATA, OR PROFITS; OR BUSINESS 
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, 
+REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF 
+THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER 
+UNDER THEORY OF CONTRACT, TORT (INCLUDING 
+NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN 
+IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF 
+SUCH DAMAGE.
+
+*/ 
+
+
+#include <Carbon/Carbon.h>
+#include "CIDraw.h"
+
+/* Constants */
+#define kMyHIViewSignature 'ciHV'
+#define kMyHIViewFieldID    128
+#define kGammaSliderSignature 'gSLD'
+#define kGammaSliderFieldID    128
+#define	kAboutBoxStringKey		CFSTR("AboutString")	// these key the localizable strings
+
+/* Private Prototypes */
+static OSStatus MyDrawEventHandler(EventHandlerCallRef myHandler, EventRef event, void *userData);
+static void MyGammaSliderProc( ControlHandle control, SInt16 part );
+static pascal OSStatus DoAppCommandProcess(EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+static PMPageFormat CreateDefaultPageFormat(void);
+static OSStatus DoPageSetup(PMPageFormat pageFormat);
+static OSStatus DoPrint(PMPageFormat pageFormat);
+static OSStatus MyDoPrintLoop(PMPrintSession printSession, PMPageFormat pageFormat, PMPrintSettings printSettings);
+static void DoAboutBox();
+
+/* Global Data */
+static HIViewRef    gMyHIView = NULL;
+static HIViewRef    gGammaSliderView = NULL;
+static PMPageFormat gPageFormat = NULL;
+
+int main(int argc, char* argv[])
+{
+    static const HIViewID	kMyViewID = {kMyHIViewSignature,  kMyHIViewFieldID };      
+    static const HIViewID	kGammaSliderID = {kGammaSliderSignature,  kGammaSliderFieldID };      
+
+    IBNibRef			nibRef;
+    WindowRef			window;
+    EventTargetRef		myEventTarget;
+    static const EventTypeSpec 	kMyViewEvents[] = {kEventClassControl, kEventControlDraw };	
+    static const EventTypeSpec 	kMyCommandEvents[] = {kEventClassCommand, kEventCommandProcess };	
+    OSStatus			err = noErr;
+
+    // Create a Nib reference passing the name of the nib file (without the .nib extension)
+    // CreateNibReference only searches into the application bundle.
+    err = CreateNibReference(CFSTR("main"), &nibRef);
+    require_noerr( err, CantGetNibRef );
+    
+    // Once the nib reference is created, set the menu bar. "MainMenu" is the name of the menu bar
+    // object. This name is set in InterfaceBuilder when the nib is created.
+    err = SetMenuBarFromNib(nibRef, CFSTR("MenuBar"));
+    require_noerr( err, CantSetMenuBar );
+    
+    // Then create a window. "MainWindow" is the name of the window object. This name is set in 
+    // InterfaceBuilder when the nib is created.
+    err = CreateWindowFromNib(nibRef, CFSTR("MainWindow"), &window);
+    require_noerr( err, CantCreateWindow );
+    // Get the HIView associated with the window.
+    HIViewFindByID( HIViewGetRoot( window ), kMyViewID, &gMyHIView );
+    
+    // make the view opaque
+    HIViewChangeFeatures(gMyHIView, kHIViewIsOpaque, 0);
+
+    // Get the event target for the view.
+    myEventTarget = GetControlEventTarget (gMyHIView);
+			     
+    // Install the event handler for the HIView.				
+    err = InstallEventHandler (myEventTarget, 
+						    NewEventHandlerUPP (MyDrawEventHandler), 
+						    GetEventTypeCount(kMyViewEvents), 
+						    kMyViewEvents, 
+						    (void *) gMyHIView, 
+						    NULL); 
+
+
+    HIViewFindByID( HIViewGetRoot( window ), kGammaSliderID, &gGammaSliderView );
+    SetControlAction( gGammaSliderView, NewControlActionUPP(MyGammaSliderProc) );
+
+    // Install the handler for the menu commands.
+    InstallApplicationEventHandler(NewEventHandlerUPP(DoAppCommandProcess), GetEventTypeCount(kMyCommandEvents), 
+						kMyCommandEvents, NULL, NULL);
+
+
+    // We don't need the nib reference anymore.
+    DisposeNibReference(nibRef);
+    
+    // The window was created hidden so show it.
+    ShowWindow( window );
+    
+    // Call the event loop
+    RunApplicationEventLoop();
+
+CantCreateWindow:
+CantSetMenuBar:
+CantGetNibRef:
+	return err;
+}
+
+static const void* myGetBytesPointer(void* info) {
+    return info;
+}
+
+static void myReleaseBytePointer(void* info, const void* pointer) {
+    pointer = 0;
+}
+
+static size_t myGetBytesAtPosition(void* info, void* buffer, off_t pos, size_t count) {
+    memcpy(buffer, (const char*)info + pos, count);
+    return count;
+}
+
+static void myReleaseInfo(void* info) {
+}
+
+static void TestDraw(CGContextRef cg, CGRect bounds) {
+    const int w = 64;
+    const int h = 64;
+    uint32_t data[w*h];
+    int i;
+    for (i = 0; i < w*h; i++) {
+        data[i] = 0x00008888;
+    }
+    CGDataProviderDirectCallbacks procs;
+    procs.version = 0;
+    procs.getBytePointer = myGetBytesPointer;
+    procs.releaseBytePointer = myReleaseBytePointer;
+    procs.getBytesAtPosition = myGetBytesAtPosition;
+    procs.releaseInfo = myReleaseInfo;
+    
+    CGColorSpaceRef space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+    
+    size_t size = w * h * 4;
+    CGDataProviderRef dataRef = CGDataProviderCreateDirect(data, size, &procs);
+    CGImageRef ref = CGImageCreate(w, h, 8, 32, w*4,
+                                   space,
+                                   kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast,
+                                   dataRef,
+                                   NULL,
+                                   false,
+                                   kCGRenderingIntentDefault);
+
+    CGColorSpaceRelease(space);
+    CGDataProviderRelease(dataRef);
+    
+    CGRect r = CGRectMake(0, 0, w, h);
+    CGContextDrawImage(cg, r, ref);
+    CGImageRelease(ref);
+}
+
+static OSStatus MyDrawEventHandler(EventHandlerCallRef myHandler, EventRef event, void *userData)
+{
+	// NOTE: GState is save/restored by the HIView system doing the callback, so the draw handler doesn't need to do it
+
+	OSStatus status = noErr;
+	CGContextRef context;
+	HIRect		bounds;
+
+	// Get the CGContextRef
+	status = GetEventParameter (event, kEventParamCGContextRef, 
+					typeCGContextRef, NULL, 
+					sizeof (CGContextRef),
+					NULL,
+					&context);
+
+	if(status != noErr){
+		fprintf(stderr, "Got error %d getting the context!\n", status);
+		return status;
+	}		
+						
+	// Get the bounding rectangle
+	HIViewGetBounds ((HIViewRef) userData, &bounds);
+	
+	// Flip the coordinates by translating and scaling. This produces a
+	// coordinate system that matches the Quartz default coordinate system
+	// with the origin in the lower-left corner with the y axis pointing up.
+	
+//	CGContextTranslateCTM (context, 0, bounds.size.height);
+//	CGContextScaleCTM (context, 1.0, -1.0);
+
+//	DoDraw(context, bounds);
+	TestDraw(context, bounds);
+	return status;
+   
+}
+
+static void MyGammaSliderProc( ControlHandle control, SInt16 part )
+{	
+	gGammaValue = GetControl32BitValue(control);
+	HIViewSetNeedsDisplay(gMyHIView, true);
+	HIViewRender(gMyHIView);   
+}
+
+
+// Handle command-process events at the application level
+static pascal OSStatus DoAppCommandProcess(EventHandlerCallRef nextHandler, EventRef theEvent, void* userData)
+{
+#pragma unused (nextHandler, userData)
+    HICommand  aCommand;
+    OSStatus   result = eventNotHandledErr;
+
+    GetEventParameter(theEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &aCommand);
+    
+    switch (aCommand.commandID)
+    {
+
+	case kHICommandPageSetup:
+	    if(gPageFormat == NULL)
+		gPageFormat = CreateDefaultPageFormat();
+		
+	    if(gPageFormat)
+		(void)DoPageSetup(gPageFormat);
+		
+	    result = noErr;
+	    break;
+
+	case kHICommandPrint:
+	    if(gPageFormat == NULL)
+		gPageFormat = CreateDefaultPageFormat();
+		
+	    if(gPageFormat)
+		(void)DoPrint(gPageFormat);
+
+	    result = noErr;
+	    break;
+
+	case kHICommandAbout:
+	    DoAboutBox();
+	    result = noErr; 
+	    break;
+
+	default:
+	    break;
+
+	case kHICommandQuit:
+		QuitApplicationEventLoop();
+		result = noErr;
+		break;
+    }
+    HiliteMenu(0);
+    return result;
+}
+
+static void DoAboutBox()
+{	
+    CFStringRef outString = NULL;
+    SInt16      alertItemHit = 0;
+    Str255      stringBuf;
+
+    outString =  CFCopyLocalizedString(kAboutBoxStringKey, NULL);
+    if (outString != NULL)
+    {
+		if (CFStringGetPascalString (outString, stringBuf, sizeof(stringBuf), GetApplicationTextEncoding()))
+		{
+			StandardAlert(kAlertStopAlert, stringBuf, NULL, NULL, &alertItemHit);
+		}
+		CFRelease (outString);                             
+    }
+}
+
+// -----------------------------------------------------------------------
+static PMPageFormat CreateDefaultPageFormat(void)
+{
+    OSStatus err = noErr, tempErr;
+    PMPageFormat pageFormat = NULL;
+    PMPrintSession printSession;
+    err = PMCreateSession(&printSession);
+    if(!err){
+	err = PMCreatePageFormat(&pageFormat);	// we own a reference to this page format
+	if(err == noErr)
+	    err = PMSessionDefaultPageFormat(printSession, pageFormat);
+
+	tempErr = PMRelease(printSession);
+	if(!err)err = tempErr;
+    }
+    if(err){
+	fprintf(stderr, "got an error = %d creating the default page format\n", err);
+    }
+    return pageFormat;
+}
+
+// -----------------------------------------------------------------
+static OSStatus DoPageSetup(PMPageFormat pageFormat)
+{
+    OSStatus		err = noErr;
+    PMPrintSession printSession;
+    err = PMCreateSession(&printSession);
+    if(!err){
+	Boolean accepted;
+	if(!err) 	// validate the page format we're going to pass to the dialog code
+	    err = PMSessionValidatePageFormat(printSession, pageFormat, kPMDontWantBoolean);
+	if(!err){
+	    err = PMSessionPageSetupDialog(printSession, pageFormat, &accepted);
+	}
+       (void)PMRelease(printSession);
+    }
+    
+    if(err && err != kPMCancel)
+	fprintf(stderr, "Got an error %d in Page Setup\n", err);
+
+    return err;
+} // DoPageSetup
+
+// -------------------------------------------------------------------------------
+static OSStatus DoPrint(PMPageFormat pageFormat)
+{
+    OSStatus err = noErr;
+    UInt32 minPage = 1, maxPage = 1;
+    PMPrintSession printSession;
+    err = PMCreateSession(&printSession);
+    if(err == noErr){
+	// validate the page format we're going to use
+	err = PMSessionValidatePageFormat(printSession, 
+			    pageFormat,
+			    kPMDontWantBoolean);
+        if (err == noErr)
+        {
+	    PMPrintSettings printSettings = NULL;
+            err = PMCreatePrintSettings(&printSettings);
+            if(err == noErr)
+                err = PMSessionDefaultPrintSettings(printSession, printSettings);
+
+            if (err == noErr)
+		err = PMSetPageRange(printSettings, minPage, maxPage);
+
+            if (err == noErr)
+            {
+                Boolean accepted;
+		err = PMSessionPrintDialog(printSession, printSettings, 
+				pageFormat,
+				&accepted);
+		if(accepted){
+		    err = MyDoPrintLoop(printSession, pageFormat, printSettings);
+		}
+            }
+	    if(printSettings)
+		(void)PMRelease(printSettings);
+        }
+
+        (void)PMRelease(printSession);   // ignoring error since we already have one 
+    }
+    
+    if(err && err != kPMCancel)
+	fprintf(stderr, "Got an error %d in Print\n", err);
+    return err;
+}
+
+// --------------------------------------------------------------------------------------
+static OSStatus MyDoPrintLoop(PMPrintSession printSession, PMPageFormat pageFormat, PMPrintSettings printSettings)
+{
+    OSStatus err = noErr;
+    OSStatus tempErr = noErr;
+    UInt32 firstPage, lastPage, totalDocPages = 1;
+    
+    if(!err)
+	err = PMGetFirstPage(printSettings, &firstPage);
+	
+    if (!err)
+        err = PMGetLastPage(printSettings, &lastPage);
+
+    if(!err && lastPage > totalDocPages){
+        // don't draw more than the number of pages in our document
+        lastPage = totalDocPages;
+    }
+
+    if (!err)		// tell the printing system the number of pages we are going to print
+        err = PMSetLastPage(printSettings, lastPage, false);
+
+    if (!err)
+    {
+        err = PMSessionBeginCGDocument(printSession, printSettings, pageFormat);
+        if (!err){
+	    UInt32 pageNumber = firstPage;
+	    // need to check errors from our print loop and errors from the session for each
+	    // time around our print loop before calling our BeginPageProc
+            while(pageNumber <= lastPage && err == noErr && PMSessionError(printSession) == noErr)
+            {
+                err = PMSessionBeginPage(printSession, pageFormat, NULL);
+                if (!err){
+                    CGContextRef printingContext = NULL;
+                    err = PMSessionGetCGGraphicsContext(printSession, &printingContext);
+                    if(!err){
+			PMRect       pageRect;
+			
+			PMGetAdjustedPaperRect(pageFormat, &pageRect);
+			DoDraw(printingContext, CGRectMake(pageRect.left, pageRect.top, pageRect.right - pageRect.left, pageRect.bottom - pageRect.top));
+                    }
+                    // we must call EndPage if BeginPage returned noErr
+		    tempErr = PMSessionEndPage(printSession);
+                        
+		    if(!err)err = tempErr;
+                }
+		pageNumber++;
+            }	// end while loop
+            
+            // we must call EndDocument if BeginDocument returned noErr
+	    tempErr = PMSessionEndDocument(printSession);
+
+	    if(!err)err = tempErr;
+	    if(!err)
+		err = PMSessionError(printSession);
+        }
+    }
+    return err;
+}
+
+
+