home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Prog / T / TIFF Code Folder / sample.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-12-16  |  11.0 KB  |  483 lines  |  [TEXT/MPS ]

  1. /*
  2.  * File Sample.c
  3.  *
  4.  * Copyright Apple Computer, Inc. 1985-1987
  5.  * All rights reserved.
  6.  * Portions Copyright Bear River Associates, Inc. 1987
  7.  * All rights reserved.
  8.  *
  9.  * Sample application in MPW C using TIFF library routines.
  10.  *
  11.  *    This program displays a fixed sized window in which the user can
  12.  *    paste a PICT from scrap, and then save this as a TIFF file.  The types
  13.  *    of TIFF images that can be read in is very limited as this program only
  14.  *    attempts to demonstrate the use of the TIFF library.  Only simple images,
  15.  *    such as those with only 1 bit per pixel, in the Motorola Byte Order can
  16.  *    be read. Of those, only the first 32k of the image is read in.
  17.  */
  18.  
  19. /* Standard C Include files */
  20. /* #include "CType.h" */
  21. /* #include "ErrNo.h" */
  22. /* #include "FCntl.h" */
  23. /* #include "IOCtl.h" */
  24. /* #include "Math.h" */
  25. /* #include "SetJmp.h" */
  26. /* #include "Signal.h" */
  27. /* #include "StdIO.h" */
  28. /* #include "String.h" */
  29.  
  30. /* Primary Interface Files */
  31. #include "Types.h"
  32. #include "Resources.h"
  33. #include "Quickdraw.h"
  34. #include "Windows.h"
  35. #include "OSUtils.h"
  36.  
  37. /* Commonly Included files */
  38. #include "ToolUtils.h"
  39. /* #include "TextEdit.h" */
  40. /* #include "Controls.h" */
  41.  
  42. /* Other Interface files */
  43. /* #include "AppleTalk.h" */
  44. /* #include "CursorCtl.h" */
  45. #include "Desk.h"
  46. /* #include "DeskBus.h" */
  47. /* #include "Devices.h" */
  48. #include "Dialogs.h"
  49. /* #include "DiskInit.h" */
  50. /* #include "Disks.h" */
  51. /* #include "ErrMgr.h" */
  52. /* #include "Errors.h" */
  53. #include "Events.h"
  54. /* #include "Files.h" */
  55. #include "Fonts.h"
  56. /* #include "Graf3D.h" */
  57. /* #include "Lists.h" */
  58. /* #include "Memory.h" */
  59. #include "Menus.h"
  60. /* #include "Packages.h" */
  61. /* #include "Palette.h" */
  62. /* #include "Perf.h" */
  63. /* #include "Picker.h" */
  64. /* #include "Printing.h" */
  65. /* #include "Retrace.h" */
  66. /* #include "ROMDefs.h" */
  67. /* #include "SANE.h" */
  68. #include "Scrap.h"
  69. /* #include "Script.h" */
  70. /* #include "SCSI.h" */
  71. #include "SegLoad.h"
  72. /* #include "Serial.h" */
  73. /* #include "Slots.h" */
  74. /* #include "Sound.h" */
  75. /* #include "Start.h" */
  76. /* #include "Strings.h" */
  77. /* #include "Time.h" */
  78. /* #include "Traps.h" */
  79. /* #include "Values.h" */
  80. /* #include "VarArgs.h" */
  81. /* #include "Video.h" */
  82.  
  83. /* Application-specific Include files */
  84. #include "::TiffLibrary:TIFFLib.h"
  85. #include "sample.h"
  86. #include "messages.h"
  87.  
  88. extern _DataInit();
  89.  
  90. /*
  91.  * Resource ID constants.
  92.  */
  93. #define    appleID            128             /* This is a resource ID */
  94. #define    fileID             129             /* ditto */
  95. #define    editID             130             /* ditto */
  96.  
  97. #define    appleMenu        0                /* MyMenus[] array indexes */
  98. #define    aboutMeCommand    1
  99.  
  100. #define    fileMenu        1
  101. #define openCommand        1
  102. #define closeCommand    2
  103. #define saveCommand        3
  104. #define saveAsCommand    4
  105. #define    quitCommand     6
  106.  
  107. #define    editMenu        2
  108. #define    undoCommand     1
  109. #define    cutCommand        3
  110. #define    copyCommand     4
  111. #define    pasteCommand    5
  112. #define    clearCommand    6
  113.  
  114. #define menuCount         3
  115. /*
  116.  * For the one and only text window
  117.  */
  118. #define windowID        128
  119. /*
  120.  * For the About Sample... DLOG
  121.  */
  122. #define    aboutMeDLOG        128
  123. #define    okButton        1
  124.  
  125. /*
  126.  * HIWORD and LOWORD macros, for readability.
  127.  */
  128. #define HIWORD(aLong)        (((aLong) >> 16) & 0xFFFF)
  129. #define LOWORD(aLong)        ((aLong) & 0xFFFF)
  130.  
  131. /*
  132.  * Global Data objects, used by routines external to main().
  133.  */
  134. MenuHandle        MyMenus[menuCount];     /* The menu handles */
  135. Boolean         DoneFlag;                /* Becomes TRUE when File/Quit chosen */
  136.  
  137. /*
  138.  * TIFF Sepecific Declarations
  139.  */
  140. BitMap    myBitMap = {
  141.     nil,                /* Ptr baseAddr */
  142.     0,                    /* short rowBytes */
  143.     {0,0,0,0}            /* Rect bounds */
  144. };
  145.  
  146. int main()
  147. {
  148.     Rect                    screenRect;
  149.     Rect                    dragRect;
  150.     Rect                    txRect;
  151.     Point                    mousePt;
  152.     CursHandle                ibeamHdl;
  153.     EventRecord             myEvent;
  154.     WindowPtr                theActiveWindow;
  155.     WindowPtr                whichWindow;
  156.     register    WindowPtr    myWindow;            /* Referenced often */
  157.     WindowRecord            wRecord;
  158.     extern void             setupMenus();
  159.     extern void             doCommand();
  160.  
  161.     /*
  162.      * Initialization traps
  163.      */
  164.     UnloadSeg(_DataInit);
  165.     InitGraf(&qd.thePort);
  166.     InitFonts();
  167.     FlushEvents(everyEvent, 0);
  168.     InitWindows();
  169.     InitMenus();
  170.     InitDialogs(nil);
  171.     InitCursor();
  172.     /*
  173.      * setupMenus is execute-once code, so we can unload it now.
  174.      */
  175.     setupMenus();            /* Local procedure, below */
  176.     UnloadSeg(setupMenus);
  177.     /*
  178.      * Calculate the drag rectangle in advance.
  179.      * This will be used when dragging a window frame around.
  180.      * It constrains the area to within 4 pixels from the screen edge
  181.      * and below the menu bar, which is 20 pixels high.
  182.      */
  183.     screenRect = qd.screenBits.bounds;
  184.     SetRect(&dragRect, 4, 20 + 4, screenRect.right-4, screenRect.bottom-4);
  185.     /*
  186.      * Create our one and only window from the WIND resource.
  187.      * If the WIND resource isn't there, we die.
  188.      */
  189.     myWindow = GetNewWindow(windowID, &wRecord, (WindowPtr) -1);
  190.     SetPort(myWindow);
  191.     /*
  192.      * Create a TextEdit record with the destRect and viewRect set
  193.      * to my window's portRect (offset by 4 pixels on the left and right
  194.      * sides so that text doesn't jam up against the window frame).
  195.      */
  196.     txRect = myWindow->portRect;
  197.     InsetRect(&txRect, 4, 0);
  198.  
  199.     ibeamHdl = GetCursor(iBeamCursor);        /* Grab this for use later */
  200.     /*
  201.      * Ready to go.
  202.      * Start with a clean event slate, and cycle the main event loop
  203.      * until the File/Quit menu item sets DoneFlag.
  204.      *
  205.      * It would not be good practice for the doCommand() routine to
  206.      * simply ExitToShell() when it saw the QuitItem -- to ensure
  207.      * orderly shutdown, satellite routines should set global state,
  208.      * and let the main event loop handle program control.
  209.      */
  210.     DoneFlag = false;
  211.     for ( ;; ) {
  212.         if (DoneFlag) {
  213.             break;        /* from main event loop */
  214.         }
  215.         /*
  216.          * Main Event tasks:
  217.          */
  218.         SystemTask();
  219.         theActiveWindow = FrontWindow();        /* Used often, avoid repeated calls */
  220.         /*
  221.          * Handle the next event.
  222.          */
  223.         if (!GetNextEvent(everyEvent, &myEvent)) {
  224.             /*
  225.              * A null or system event, not for me.
  226.              * Here is a good place for heap cleanup and/or
  227.              * segment unloading if I want to.
  228.              */
  229.             continue;
  230.         }
  231.         /*
  232.          * In the unlikely case that the active desk accessory does not
  233.          * handle mouseDown, keyDown, or other events, GetNextEvent() will
  234.          * give them to us!  So before we perform actions on some events,
  235.          * we check to see that the affected window in question is really
  236.          * our window.
  237.          */
  238.         switch (myEvent.what) {
  239.             case mouseDown:
  240.                 switch (FindWindow(&myEvent.where, &whichWindow)) {
  241.                     case inSysWindow:
  242.                         SystemClick(&myEvent, whichWindow);
  243.                         break;
  244.  
  245.                     case inMenuBar:
  246.                         doCommand(MenuSelect(&myEvent.where));
  247.                         break;
  248.  
  249.                     case inDrag:
  250.                         DragWindow(whichWindow, &myEvent.where, &dragRect);
  251.                         break;
  252.  
  253.                     case inGrow:
  254.                         /* There is no grow box. (Fall through) */
  255.  
  256.                     case inContent:
  257.                         if (whichWindow != theActiveWindow) {
  258.                             SelectWindow(whichWindow);
  259.                         }
  260.                         break;
  261.  
  262.                     default:
  263.                         break;
  264.                 }
  265.                 break;
  266.  
  267.             case keyDown:
  268.             case autoKey:
  269.                 if (myWindow == theActiveWindow) {
  270.                     if (myEvent.modifiers & cmdKey)
  271.                         doCommand(MenuKey(myEvent.message & charCodeMask));
  272.                 }
  273.                 break;
  274.  
  275.             case activateEvt:
  276.                 break;
  277.  
  278.             case updateEvt:
  279.                 if ((WindowPtr) myEvent.message == myWindow) {
  280.                     BeginUpdate(myWindow);
  281.                     DisplayImage(myWindow, &myBitMap);
  282.                     EndUpdate(myWindow);
  283.                 }
  284.                 break;
  285.  
  286.             default:
  287.                 break;
  288.  
  289.         }
  290.  
  291.     }
  292.     /*
  293.      * Cleanup here.
  294.      */
  295.     CloseWindow(myWindow);
  296.     
  297.     return 0;        /* Return from main() to allow C runtime cleanup */
  298. }
  299.  
  300. /*
  301.  * Demonstration of the segmenting facility:
  302.  *
  303.  * This code is execute-once, so we toss it in the "Initialize"
  304.  * segment so that main() can unload it after it's called.
  305.  *
  306.  * There really isn't much here, but it demonstrates the segmenting facility.
  307.  */
  308. /*
  309.  * Set the segment to Initialize.  BEWARE: leading and trailing white space
  310.  * would be part of the segment name!
  311.  */
  312. #define    __SEG__ Initialize
  313.  
  314. /*
  315.  * Set up the Apple, File, and Edit menus.
  316.  * If the MENU resources are missing, we die.
  317.  */
  318. void setupMenus()
  319. {
  320.     extern        MenuHandle    MyMenus[];
  321.     register    MenuHandle    *pMenu;
  322.  
  323.     /*
  324.      * Set up the desk accessories menu.
  325.      * The "About Sample..." item, followed by a grey line,
  326.      * is presumed to be already in the resource.  We then
  327.      * append the desk accessory names from the 'DRVR' resources.
  328.      */
  329.     MyMenus[appleMenu] = GetMenu(appleID);
  330.     AddResMenu(MyMenus[appleMenu], (ResType) 'DRVR');
  331.     /*
  332.      * Now the File and Edit menus.
  333.      */
  334.     MyMenus[fileMenu] = GetMenu(fileID);
  335.     MyMenus[editMenu] = GetMenu(editID);
  336.     /*
  337.      * Now insert all of the application menus in the menu bar.
  338.      *
  339.      * "Real" C programmers never use array indexes
  340.      * unless they're constants :-)
  341.      */
  342.     for (pMenu = &MyMenus[0]; pMenu < &MyMenus[menuCount]; ++pMenu) {
  343.         InsertMenu(*pMenu, 0);
  344.     }
  345.  
  346.     DrawMenuBar();
  347.  
  348.     return;
  349. }
  350.  
  351. /*
  352.  * Back to the Main segment.
  353.  */
  354. #define    __SEG__ Main
  355.  
  356. /*
  357.  * Display the Sample Application dialog.
  358.  * Wait until the OK button is clicked before returning.
  359.  */
  360. void showAboutMeDialog()
  361. {
  362.     GrafPtr     savePort;
  363.     DialogPtr    theDialog;
  364.     short        itemHit;
  365.  
  366.     GetPort(&savePort);
  367.     theDialog = GetNewDialog(aboutMeDLOG, nil, (WindowPtr) -1);
  368.     SetPort(theDialog);
  369.  
  370.     do {
  371.         ModalDialog(nil, &itemHit);
  372.     } while (itemHit != okButton);
  373.  
  374.     CloseDialog(theDialog);
  375.  
  376.     SetPort(savePort);
  377.     return;
  378. }
  379. /*
  380.  * Process mouse clicks in menu bar
  381.  */
  382. void doCommand(mResult)
  383.     long    mResult;
  384. {
  385.     int                 theMenu, theItem;
  386.     char                daName[256];
  387.     GrafPtr             savePort;
  388.     extern MenuHandle    MyMenus[];
  389.     extern Boolean        DoneFlag;
  390.     extern void             showAboutMeDialog();
  391.  
  392.     theItem = LOWORD(mResult);
  393.     theMenu = HIWORD(mResult);        /* This is the resource ID */
  394.  
  395.     switch (theMenu) {
  396.         case appleID:
  397.             if (theItem == aboutMeCommand) {
  398.                 showAboutMeDialog();
  399.             } else {
  400.                 GetItem(MyMenus[appleMenu], theItem, daName);
  401.                 GetPort(&savePort);
  402.                 (void) OpenDeskAcc(daName);
  403.                 SetPort(savePort);
  404.             }
  405.             break;
  406.  
  407.         case fileID:
  408.             switch (theItem) {
  409.                 case openCommand:
  410.                     DoOpen(&myBitMap);
  411.                     break;
  412.                 case closeCommand:
  413.                     DoClose();
  414.                     ClearImage(&myBitMap);
  415.                     break;
  416.                 case saveCommand:
  417.                     DoSave(&myBitMap);
  418.                     break;
  419.                 case saveAsCommand:
  420.                     DoSaveAs(&myBitMap);
  421.                     break;
  422.                 case quitCommand:
  423.                     DoQuitCleanUp(&myBitMap);
  424.                     DoneFlag = true;            /* Request exit */
  425.                     break;
  426.                 default:
  427.                     break;
  428.             }
  429.             break;
  430.  
  431.         case editID:
  432.             /*
  433.              * If this is for a 'standard' edit item,
  434.              * run it through SystemEdit first.
  435.              * SystemEdit will return FALSE if it's not a system window.
  436.              */
  437.             if ((theItem <= clearCommand) && SystemEdit(theItem-1)) {
  438.                 break;
  439.             }
  440.             /*
  441.              * Otherwise, it's my window.
  442.              * Handle Cut/Copy/Paste
  443.              */
  444.             switch (theItem) {
  445.                 case undoCommand:    /* do my stuff for now */
  446.                     break;
  447.                 case cutCommand:
  448.                     if (myBitMap.baseAddr != nil) {
  449.                         ImageToClipPict(&myBitMap);
  450.                         EraseRect(&(FrontWindow())->portRect);
  451.                         MyDisposPtr(&myBitMap.baseAddr);
  452.                     }
  453.                     break;
  454.                 case copyCommand:
  455.                     /* put image into clipboard */
  456.                     if (myBitMap.baseAddr != nil)
  457.                         ImageToClipPict(&myBitMap);
  458.                     break;
  459.                 case pasteCommand:
  460.                     /* get the contents of the clipboard */
  461.                     ClipPictToImage(&myBitMap);
  462.                     break;
  463.                 case clearCommand:
  464.                     if (myBitMap.baseAddr != nil) {
  465.                         EraseRect(&(FrontWindow())->portRect);
  466.                         MyDisposPtr(&myBitMap.baseAddr);
  467.                     }
  468.                     break;
  469.                 default:
  470.                     break;
  471.             } /*endsw theItem*/
  472.             break;
  473.  
  474.         default:
  475.             break;
  476.  
  477.     }/*endsw theMenu*/
  478.  
  479.     HiliteMenu(0);
  480.  
  481.     return;
  482. }
  483.