home *** CD-ROM | disk | FTP | other *** search
- /*
- * File Sample.c
- *
- * Copyright Apple Computer, Inc. 1985-1987
- * All rights reserved.
- * Portions Copyright Bear River Associates, Inc. 1987
- * All rights reserved.
- *
- * Sample application in MPW C using TIFF library routines.
- *
- * This program displays a fixed sized window in which the user can
- * paste a PICT from scrap, and then save this as a TIFF file. The types
- * of TIFF images that can be read in is very limited as this program only
- * attempts to demonstrate the use of the TIFF library. Only simple images,
- * such as those with only 1 bit per pixel, in the Motorola Byte Order can
- * be read. Of those, only the first 32k of the image is read in.
- */
-
- /* Standard C Include files */
- /* #include "CType.h" */
- /* #include "ErrNo.h" */
- /* #include "FCntl.h" */
- /* #include "IOCtl.h" */
- /* #include "Math.h" */
- /* #include "SetJmp.h" */
- /* #include "Signal.h" */
- /* #include "StdIO.h" */
- /* #include "String.h" */
-
- /* Primary Interface Files */
- #include "Types.h"
- #include "Resources.h"
- #include "Quickdraw.h"
- #include "Windows.h"
- #include "OSUtils.h"
-
- /* Commonly Included files */
- #include "ToolUtils.h"
- /* #include "TextEdit.h" */
- /* #include "Controls.h" */
-
- /* Other Interface files */
- /* #include "AppleTalk.h" */
- /* #include "CursorCtl.h" */
- #include "Desk.h"
- /* #include "DeskBus.h" */
- /* #include "Devices.h" */
- #include "Dialogs.h"
- /* #include "DiskInit.h" */
- /* #include "Disks.h" */
- /* #include "ErrMgr.h" */
- /* #include "Errors.h" */
- #include "Events.h"
- /* #include "Files.h" */
- #include "Fonts.h"
- /* #include "Graf3D.h" */
- /* #include "Lists.h" */
- /* #include "Memory.h" */
- #include "Menus.h"
- /* #include "Packages.h" */
- /* #include "Palette.h" */
- /* #include "Perf.h" */
- /* #include "Picker.h" */
- /* #include "Printing.h" */
- /* #include "Retrace.h" */
- /* #include "ROMDefs.h" */
- /* #include "SANE.h" */
- #include "Scrap.h"
- /* #include "Script.h" */
- /* #include "SCSI.h" */
- #include "SegLoad.h"
- /* #include "Serial.h" */
- /* #include "Slots.h" */
- /* #include "Sound.h" */
- /* #include "Start.h" */
- /* #include "Strings.h" */
- /* #include "Time.h" */
- /* #include "Traps.h" */
- /* #include "Values.h" */
- /* #include "VarArgs.h" */
- /* #include "Video.h" */
-
- /* Application-specific Include files */
- #include "::TiffLibrary:TIFFLib.h"
- #include "sample.h"
- #include "messages.h"
-
- extern _DataInit();
-
- /*
- * Resource ID constants.
- */
- #define appleID 128 /* This is a resource ID */
- #define fileID 129 /* ditto */
- #define editID 130 /* ditto */
-
- #define appleMenu 0 /* MyMenus[] array indexes */
- #define aboutMeCommand 1
-
- #define fileMenu 1
- #define openCommand 1
- #define closeCommand 2
- #define saveCommand 3
- #define saveAsCommand 4
- #define quitCommand 6
-
- #define editMenu 2
- #define undoCommand 1
- #define cutCommand 3
- #define copyCommand 4
- #define pasteCommand 5
- #define clearCommand 6
-
- #define menuCount 3
- /*
- * For the one and only text window
- */
- #define windowID 128
- /*
- * For the About Sample... DLOG
- */
- #define aboutMeDLOG 128
- #define okButton 1
-
- /*
- * HIWORD and LOWORD macros, for readability.
- */
- #define HIWORD(aLong) (((aLong) >> 16) & 0xFFFF)
- #define LOWORD(aLong) ((aLong) & 0xFFFF)
-
- /*
- * Global Data objects, used by routines external to main().
- */
- MenuHandle MyMenus[menuCount]; /* The menu handles */
- Boolean DoneFlag; /* Becomes TRUE when File/Quit chosen */
-
- /*
- * TIFF Sepecific Declarations
- */
- BitMap myBitMap = {
- nil, /* Ptr baseAddr */
- 0, /* short rowBytes */
- {0,0,0,0} /* Rect bounds */
- };
-
- int main()
- {
- Rect screenRect;
- Rect dragRect;
- Rect txRect;
- Point mousePt;
- CursHandle ibeamHdl;
- EventRecord myEvent;
- WindowPtr theActiveWindow;
- WindowPtr whichWindow;
- register WindowPtr myWindow; /* Referenced often */
- WindowRecord wRecord;
- extern void setupMenus();
- extern void doCommand();
-
- /*
- * Initialization traps
- */
- UnloadSeg(_DataInit);
- InitGraf(&qd.thePort);
- InitFonts();
- FlushEvents(everyEvent, 0);
- InitWindows();
- InitMenus();
- InitDialogs(nil);
- InitCursor();
- /*
- * setupMenus is execute-once code, so we can unload it now.
- */
- setupMenus(); /* Local procedure, below */
- UnloadSeg(setupMenus);
- /*
- * Calculate the drag rectangle in advance.
- * This will be used when dragging a window frame around.
- * It constrains the area to within 4 pixels from the screen edge
- * and below the menu bar, which is 20 pixels high.
- */
- screenRect = qd.screenBits.bounds;
- SetRect(&dragRect, 4, 20 + 4, screenRect.right-4, screenRect.bottom-4);
- /*
- * Create our one and only window from the WIND resource.
- * If the WIND resource isn't there, we die.
- */
- myWindow = GetNewWindow(windowID, &wRecord, (WindowPtr) -1);
- SetPort(myWindow);
- /*
- * Create a TextEdit record with the destRect and viewRect set
- * to my window's portRect (offset by 4 pixels on the left and right
- * sides so that text doesn't jam up against the window frame).
- */
- txRect = myWindow->portRect;
- InsetRect(&txRect, 4, 0);
-
- ibeamHdl = GetCursor(iBeamCursor); /* Grab this for use later */
- /*
- * Ready to go.
- * Start with a clean event slate, and cycle the main event loop
- * until the File/Quit menu item sets DoneFlag.
- *
- * It would not be good practice for the doCommand() routine to
- * simply ExitToShell() when it saw the QuitItem -- to ensure
- * orderly shutdown, satellite routines should set global state,
- * and let the main event loop handle program control.
- */
- DoneFlag = false;
- for ( ;; ) {
- if (DoneFlag) {
- break; /* from main event loop */
- }
- /*
- * Main Event tasks:
- */
- SystemTask();
- theActiveWindow = FrontWindow(); /* Used often, avoid repeated calls */
- /*
- * Handle the next event.
- */
- if (!GetNextEvent(everyEvent, &myEvent)) {
- /*
- * A null or system event, not for me.
- * Here is a good place for heap cleanup and/or
- * segment unloading if I want to.
- */
- continue;
- }
- /*
- * In the unlikely case that the active desk accessory does not
- * handle mouseDown, keyDown, or other events, GetNextEvent() will
- * give them to us! So before we perform actions on some events,
- * we check to see that the affected window in question is really
- * our window.
- */
- switch (myEvent.what) {
- case mouseDown:
- switch (FindWindow(&myEvent.where, &whichWindow)) {
- case inSysWindow:
- SystemClick(&myEvent, whichWindow);
- break;
-
- case inMenuBar:
- doCommand(MenuSelect(&myEvent.where));
- break;
-
- case inDrag:
- DragWindow(whichWindow, &myEvent.where, &dragRect);
- break;
-
- case inGrow:
- /* There is no grow box. (Fall through) */
-
- case inContent:
- if (whichWindow != theActiveWindow) {
- SelectWindow(whichWindow);
- }
- break;
-
- default:
- break;
- }
- break;
-
- case keyDown:
- case autoKey:
- if (myWindow == theActiveWindow) {
- if (myEvent.modifiers & cmdKey)
- doCommand(MenuKey(myEvent.message & charCodeMask));
- }
- break;
-
- case activateEvt:
- break;
-
- case updateEvt:
- if ((WindowPtr) myEvent.message == myWindow) {
- BeginUpdate(myWindow);
- DisplayImage(myWindow, &myBitMap);
- EndUpdate(myWindow);
- }
- break;
-
- default:
- break;
-
- }
-
- }
- /*
- * Cleanup here.
- */
- CloseWindow(myWindow);
-
- return 0; /* Return from main() to allow C runtime cleanup */
- }
-
- /*
- * Demonstration of the segmenting facility:
- *
- * This code is execute-once, so we toss it in the "Initialize"
- * segment so that main() can unload it after it's called.
- *
- * There really isn't much here, but it demonstrates the segmenting facility.
- */
- /*
- * Set the segment to Initialize. BEWARE: leading and trailing white space
- * would be part of the segment name!
- */
- #define __SEG__ Initialize
-
- /*
- * Set up the Apple, File, and Edit menus.
- * If the MENU resources are missing, we die.
- */
- void setupMenus()
- {
- extern MenuHandle MyMenus[];
- register MenuHandle *pMenu;
-
- /*
- * Set up the desk accessories menu.
- * The "About Sample..." item, followed by a grey line,
- * is presumed to be already in the resource. We then
- * append the desk accessory names from the 'DRVR' resources.
- */
- MyMenus[appleMenu] = GetMenu(appleID);
- AddResMenu(MyMenus[appleMenu], (ResType) 'DRVR');
- /*
- * Now the File and Edit menus.
- */
- MyMenus[fileMenu] = GetMenu(fileID);
- MyMenus[editMenu] = GetMenu(editID);
- /*
- * Now insert all of the application menus in the menu bar.
- *
- * "Real" C programmers never use array indexes
- * unless they're constants :-)
- */
- for (pMenu = &MyMenus[0]; pMenu < &MyMenus[menuCount]; ++pMenu) {
- InsertMenu(*pMenu, 0);
- }
-
- DrawMenuBar();
-
- return;
- }
-
- /*
- * Back to the Main segment.
- */
- #define __SEG__ Main
-
- /*
- * Display the Sample Application dialog.
- * Wait until the OK button is clicked before returning.
- */
- void showAboutMeDialog()
- {
- GrafPtr savePort;
- DialogPtr theDialog;
- short itemHit;
-
- GetPort(&savePort);
- theDialog = GetNewDialog(aboutMeDLOG, nil, (WindowPtr) -1);
- SetPort(theDialog);
-
- do {
- ModalDialog(nil, &itemHit);
- } while (itemHit != okButton);
-
- CloseDialog(theDialog);
-
- SetPort(savePort);
- return;
- }
- /*
- * Process mouse clicks in menu bar
- */
- void doCommand(mResult)
- long mResult;
- {
- int theMenu, theItem;
- char daName[256];
- GrafPtr savePort;
- extern MenuHandle MyMenus[];
- extern Boolean DoneFlag;
- extern void showAboutMeDialog();
-
- theItem = LOWORD(mResult);
- theMenu = HIWORD(mResult); /* This is the resource ID */
-
- switch (theMenu) {
- case appleID:
- if (theItem == aboutMeCommand) {
- showAboutMeDialog();
- } else {
- GetItem(MyMenus[appleMenu], theItem, daName);
- GetPort(&savePort);
- (void) OpenDeskAcc(daName);
- SetPort(savePort);
- }
- break;
-
- case fileID:
- switch (theItem) {
- case openCommand:
- DoOpen(&myBitMap);
- break;
- case closeCommand:
- DoClose();
- ClearImage(&myBitMap);
- break;
- case saveCommand:
- DoSave(&myBitMap);
- break;
- case saveAsCommand:
- DoSaveAs(&myBitMap);
- break;
- case quitCommand:
- DoQuitCleanUp(&myBitMap);
- DoneFlag = true; /* Request exit */
- break;
- default:
- break;
- }
- break;
-
- case editID:
- /*
- * If this is for a 'standard' edit item,
- * run it through SystemEdit first.
- * SystemEdit will return FALSE if it's not a system window.
- */
- if ((theItem <= clearCommand) && SystemEdit(theItem-1)) {
- break;
- }
- /*
- * Otherwise, it's my window.
- * Handle Cut/Copy/Paste
- */
- switch (theItem) {
- case undoCommand: /* do my stuff for now */
- break;
- case cutCommand:
- if (myBitMap.baseAddr != nil) {
- ImageToClipPict(&myBitMap);
- EraseRect(&(FrontWindow())->portRect);
- MyDisposPtr(&myBitMap.baseAddr);
- }
- break;
- case copyCommand:
- /* put image into clipboard */
- if (myBitMap.baseAddr != nil)
- ImageToClipPict(&myBitMap);
- break;
- case pasteCommand:
- /* get the contents of the clipboard */
- ClipPictToImage(&myBitMap);
- break;
- case clearCommand:
- if (myBitMap.baseAddr != nil) {
- EraseRect(&(FrontWindow())->portRect);
- MyDisposPtr(&myBitMap.baseAddr);
- }
- break;
- default:
- break;
- } /*endsw theItem*/
- break;
-
- default:
- break;
-
- }/*endsw theMenu*/
-
- HiliteMenu(0);
-
- return;
- }
-