Pallet.c

/*--------------------------------------------------------------------------*/
/*                                                                          */
/*      D/A shell.                                                          */
/*          by John Wang                                                    */
/*                                                                          */
/*      D/A: Pallet                                                         */
/*      Description: Displays the the current color table and palette       */
/*                      information associated with it.                     */
/*                                                                          */
/*--------------------------------------------------------------------------*/
 
#include    <types.h>
#include    <osutils.h>
#include    <memory.h>
#include    <devices.h>
#include    <events.h>
#include    <quickdraw.h>
#include    <fonts.h>
#include    <windows.h>
#include    <files.h>
#include    <errors.h>
#include    <toolutils.h>
#include    <packages.h>
#include    <palettes.h>
 
/*------------------------------------------------------*/
/*  Standard definitions.                               */
/*------------------------------------------------------*/
 
#define TRUE            0xFF
#define FALSE           0
 
/*------------------------------------------------------*/
/*  Macros.                                             */
/*------------------------------------------------------*/
 
#define OWNEDRSRCID(id) (0xC000 | (((-(id)) - 1) << 5))
 
/*------------------------------------------------------*/
/*  Program Specific definitions.                       */
/*------------------------------------------------------*/
 
#define APPHEAP     1
#define SYSHEAP     2
#define DISK        3
#define FREEON      4
 
#define ACCEVENT    64
#define ACCRUN      65
 
/*------------------------------------------------------*/
/*  Global Variables.                                   */
/*------------------------------------------------------*/
 
/*------------------------------------------------------*/
/*  Open.                                               */
/*------------------------------------------------------*/
 
pascal short DRVROpen(CntrlParam *ctlPB, DCtlPtr dCtl)
{
    #pragma unused (ctlPB)
    GrafPtr         savePort;
    WindowPeek      myWindow;
    PaletteHandle   srcPalette;
 
    /*  If the windowPtr is non-nil, we already have a window open.  This desk accessory
        ignores multiple opens. */
    if (dCtl->dCtlWindow != nil)
        return noErr;
 
    GetPort(&savePort);
        
    myWindow = (WindowPeek) GetNewCWindow(OWNEDRSRCID(dCtl->dCtlRefNum), nil, (WindowPtr) -1);
 
    myWindow->windowKind = dCtl->dCtlRefNum;
    dCtl->dCtlWindow = (WindowPtr) myWindow;
 
    srcPalette = NewPalette(256, nil, pmExplicit, 0);
    SetPalette ((WindowPtr) myWindow, srcPalette, TRUE);
    ActivatePalette ((WindowPtr) myWindow);
    SetPort(savePort);
    return noErr;
}
 
/*------------------------------------------------------*/
/*  Prime.                                              */
/*------------------------------------------------------*/
 
pascal short DRVRPrime(CntrlParam *ctlPB, DCtlPtr dCtl)
{
    #pragma unused (ctlPB, dCtl)
    return noErr;           /* Not used in this desk accessory */
}
 
/*------------------------------------------------------*/
/*  Status.                                             */
/*------------------------------------------------------*/
 
pascal short DRVRStatus(CntrlParam *ctlPB, DCtlPtr dCtl)
{
    #pragma unused (ctlPB, dCtl)
    return noErr;           /* Not used in this desk accessory */
}
 
/*------------------------------------------------------*/
/*  Control.                                            */
/*------------------------------------------------------*/
 
pascal short DRVRControl(CntrlParam *ctlPB, DCtlPtr dCtl)
{
    extern  void    doCtlEvent();
    extern  void    doPeriodic();
 
    switch (ctlPB->csCode) {
        case ACCEVENT:              /* accEvent */
            doCtlEvent( *((EventRecord **) &ctlPB->csParam[0]));
            break;
 
        case ACCRUN:                /* periodicEvent */
            doPeriodic(dCtl);
            break;
 
        default:
            break;
    }
    return noErr;
}
 
/*------------------------------------------------------*/
/*  Close.                                              */
/*------------------------------------------------------*/
 
pascal short DRVRClose(char *ctlPB, DCtlPtr dCtl)
{                       /* Save & Restore current grafPort? */
    #pragma unused (ctlPB)
    WindowPtr window;
 
    window = dCtl->dCtlWindow;
    if ( window != nil) {
        dCtl->dCtlWindow = nil;
        DisposeWindow(window);
    }
    return noErr;
}
 
static void drawWindow(WindowPtr window)
{
    int         x, y;
    Rect        myRect;
    GrafPtr     myPort;
    CGrafPtr    myCPort;
    CTabHandle  myctHandle;
    int         myValue;
    RGBColor    myColor;
    ColorSpecPtr    myspecarray;
 
    if (window == nil)
        return;
 
    myColor.red = myColor.green = myColor.blue = 0;
    RGBForeColor(&myColor);
    for (x=1; x< 16; x++) {
        MoveTo(x*16-1, 0);
        LineTo(x*16-1, 255);
    }
    for (y=1; y< 16; y++) {
        MoveTo(0, y*16-1);
        LineTo(255, y*16-1);
    }
 
    GetPort(&myPort);
    myCPort = (CGrafPtr) myPort;
    myctHandle = (**(*myCPort).portPixMap).pmTable;
    
    myspecarray = ((**myctHandle).ctTable);
 
    for (x=0; x< 16; x++) {
        for (y=0; y<16; y++) {
            PmForeColor(y*16+x);
            SetRect(&myRect, x*16, y*16, 15+x*16, 15+y*16);
            PaintRect(&myRect);
            MoveTo(x*16, y*16);
            myColor = myspecarray[y*16+x].rgb;
            myValue = myspecarray[y*16+x].value;
            InvertColor(&myColor);
            RGBForeColor(&myColor);
            Move(2,11);
            if (myValue & (16384)) { /* reserve bit */
                Line(0,-6);
                Line(3,0);
                Line(0,3);
                Line(-3,0);
                Line(3,3);
                Move(3,0);
            } else {
                Move(6,0);
            }
            if (myValue & (32768)) { /* protect bit */
                Line(0,-6);
                Line(3,0);
                Line(0,3);
                Line(-3,0);
            }
        }
    }
}
 
static void doCtlEvent(register EventRecord *theEvent)
{
    register    WindowPtr   myWindow;
 
    if (theEvent->what == updateEvt) {
        myWindow = (WindowPtr) theEvent->message;
        SetPort(myWindow);
        BeginUpdate(myWindow);
        drawWindow(myWindow);
        EndUpdate(myWindow);
    }
}
 
static void doPeriodic(DCtlPtr dCtl)
{
    SetPort(dCtl->dCtlWindow);
    drawWindow(dCtl->dCtlWindow);
}