home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK1.toast / Development Kits (Disc 1) / ColorSync / Sample Code / CSDemo 2.1 / CSDemoSources / winProfile.c < prev    next >
Encoding:
Text File  |  1996-03-20  |  32.9 KB  |  1,128 lines  |  [TEXT/CWIE]

  1. // A profile window
  2. //
  3. // David Hayward 
  4. // Developer Technical Support
  5. // AppleLink: DEVSUPPORT
  6. //
  7. // Copyrite 1995, Apple Computer,Inc
  8. //
  9. // This file contains the menus routines for a profile window.
  10. // 
  11. // 12/13/94    david    first cut
  12.  
  13.  
  14. #include <QuickDraw.h>
  15. #include <Icons.h>
  16. #include <Fonts.h>
  17. #include <LowMem.h>
  18. #include <Files.h>
  19. #include <TextUtils.h>
  20. #include <QDOffScreen.h>
  21. #include <Resources.h>
  22. #include <StandardFile.h>
  23.  
  24. #include "appGlobals.h"
  25. #include "appMain.h"
  26. #include "appMenus.h"
  27. #include "appErrors.h"
  28. #include "appAEvts.h"
  29.  
  30. #include "win.h"
  31. #include "winTables.h"
  32. #include "winProfile.h"
  33. #include "winProfileGetSet.h"
  34. #include "winProfID.h"
  35. #include "winProfIDGetSet.h"
  36. #include "winProfList.h"
  37. #include "winProfListGetSet.h"
  38.  
  39. #include "stringUtils.h"
  40. #include "colorsyncUtils.h"
  41. #include "resourceUtils.h"
  42.  
  43.  
  44. /**\
  45. |**| ==============================================================================
  46. |**| PRIVATE TYPEDEFS
  47. |**| ==============================================================================
  48. \**/
  49. typedef struct FlagList
  50. {
  51.     short    count ;            // 1-based count of structs to follow 
  52.     struct
  53.     {
  54.         short    shift ;            // bits to shift over
  55.         short    mask ;            // bits to then mask over
  56.         short    value ;            // resulting value
  57.         Str27    string ;
  58.     } entry[];
  59. } FlagList, *FlagListPtr, **FlagListHdl ;
  60.  
  61.  
  62. /**\
  63. |**| ==============================================================================
  64. |**| PRIVATE DEFINES
  65. |**| ==============================================================================
  66. \**/
  67. #define rProfileWindID                1000            // 'WIND' resource id
  68. #define rProfileLabelsStringID        1000            // 'STR ' resource id
  69. #define rProfileVarsStringID        1001            // 'STR ' resource id
  70. #define rProfileWhereVarStringID    1002            // 'STR ' resource id
  71. #define rProfileIconID                1003            // icon family resource id
  72.  
  73.  
  74. /**\
  75. |**| ==============================================================================
  76. |**| PRIVATE FUNCTION PROTOTYPES
  77. |**| ==============================================================================
  78. \**/
  79. void        DoDrawProfData            ( winHandle win ) ;
  80. void        MungeProfileHeader1        ( CMProfileRef prof, Handle text ) ;
  81. void        MungeProfileHeader2        ( CMProfileRef prof, Handle text ) ;
  82. OSErr        RendIntent2String        ( unsigned long intent, StringPtr dest ) ;
  83. OSErr        ColorSpace2String        ( OSType spaceType, StringPtr dest ) ;
  84. OSErr        ProfileClass2String        ( OSType classType, StringPtr dest ) ;
  85. OSErr        DoCreateProfWindow        ( winHandle win ) ;
  86. void        ProfMakeSysProfileCmnd    ( winHandle win ) ;
  87. void        ProfCreateProfIDCmnd    ( winHandle win ) ;
  88. void        SaveCmndProfile            ( winHandle win ) ;
  89. void        SaveAsCmndProfile        ( winHandle win ) ;
  90. void        RevertCmndProfile        ( winHandle win ) ;
  91. long        PopUpMenuSelectFont        ( MenuHandle theMenu, short top, short left,
  92.                                           short popUpItem, short font, short size) ;
  93. OSErr        GetFlagListStringPtr    ( short id, unsigned long flags, StringPtr dest ) ;
  94. OSErr        BuildFlagListMenu        ( short id, unsigned long flags, MenuHandle menu ) ;
  95. OSErr        SetFlagFromMenuItem        ( short id, unsigned long *flags, short mitem ) ;
  96.  
  97.  
  98. /**\
  99. |**| ==============================================================================
  100. |**| PUBLIC FUNCTIONS
  101. |**| ==============================================================================
  102. \**/
  103.  
  104.  
  105. /*------------------------------------------------------------------------------*\
  106.     winUpdateProfile
  107.  *------------------------------------------------------------------------------*
  108.         This is a UpdateProcPtr for Profile windows.  
  109.         It handles all drawing into the window.
  110.         For ProfList windows, this means that this routine is responible for
  111.         drawing the the basic CS1 and CS2 profile info into the window.
  112.         This ProcPtr is envoked by CallWinUpdateProc() which is called by:
  113.             DoUpdateEvent() which dispaches update events.
  114. \*------------------------------------------------------------------------------*/
  115. void    winUpdateProfile ( winHandle win, EventRecord *e )
  116. {
  117.     WindowRef        window = (WindowRef)e->message;
  118.     GrafPtr            savedPort ;
  119.     
  120.     GetPort(&savedPort ) ;    
  121.     SetPort( (GrafPtr)window ) ;
  122.  
  123.     BeginUpdate( window ) ;
  124.  
  125.     DoDrawProfData( win ) ;
  126.     
  127.     // signal that we finished drawing
  128.     EndUpdate( window ) ;
  129.     SetPort( savedPort ) ;
  130. }
  131.  
  132.  
  133. /*------------------------------------------------------------------------------*\
  134.     winClickProfile
  135.  *------------------------------------------------------------------------------*
  136.         This is a ClickProcPtr for Profile windows.
  137.         So far, all this contains is a crude handling of the popup menus
  138.         Other things, such as initiating a drag-and-drop should also go here
  139.         This ProcPtr is envoked by CallWinClickProc() which is called by:
  140.             DoMouseDownEvent() which dispaches mouse down events 
  141. \*------------------------------------------------------------------------------*/
  142. void winClickProfile ( winHandle win, EventRecord *e ) 
  143. {
  144.     CMError                    cmerr ;
  145.     CMProfileRef            prof;
  146.     CMAppleProfileHeader    head ;
  147.     unsigned long            vers ;
  148.     unsigned long            *flagPtr ;
  149.     Point                    where ;
  150.     Rect                    varsRect ;
  151.     
  152.     varsRect = GetRect ( rProfileVarsStringID ) ;
  153.  
  154.     // if in correct region
  155.     where = e->where;
  156.     GlobalToLocal(&where);
  157.     
  158.     if ( (where.h >= varsRect.left) && (where.h <= varsRect.left+8) )
  159.     {
  160.         short        row, resID, mitem;
  161.         long        mresult;
  162.         MenuHandle    menu;
  163.         Point        mOrigin ;
  164.         
  165.         row = (where.v - varsRect.top) /12;
  166.         
  167.         if ( row>=14 && row<=17 )
  168.         {
  169.             prof = GetProfileRef( win );
  170.         
  171.             cmerr = CMGetProfileHeader(prof, &head) ;
  172.             if (cmerr) return ;
  173.         
  174.             vers = head.cm2.profileVersion ;
  175.     
  176.             menu = NewMenu(5000,"\ppopup");
  177.             InsertMenu(menu,-1);
  178.             
  179.             mOrigin.h = varsRect.left;
  180.             mOrigin.v = varsRect.top + 12*row;            
  181.             LocalToGlobal(&mOrigin);
  182.  
  183.             flagPtr = nil;
  184.             
  185.             if (row==14 && vers>=cmCS2ProfileVersion)        // CS2 Atrb0
  186.             {    flagPtr = &(head.cm2.deviceAttributes[0]) ;
  187.                 resID = 1001;
  188.             }                
  189.             if (row==16 && vers>=cmCS2ProfileVersion)        // CS2 Flags
  190.             {    flagPtr = &(head.cm2.flags) ;
  191.                 resID = 1002;
  192.             }                
  193.             if (row==16 && vers<cmCS2ProfileVersion)        // CS1 Flags
  194.             {    flagPtr = (unsigned long *)&(head.cm1.flags) ;
  195.                 resID = 1003;
  196.             }                
  197.             if (row==17)                                    // CS Intent
  198.             {    flagPtr = &(head.cm2.renderingIntent) ;
  199.                 resID = 1000;
  200.             }                
  201.  
  202.             if (flagPtr) cmerr = BuildFlagListMenu( resID, *flagPtr, menu ) ;
  203.             
  204.             if (flagPtr && !cmerr)
  205.             {
  206.                 mresult = PopUpMenuSelectFont(menu,mOrigin.v,mOrigin.h,0, 3, 9);
  207.                 DeleteMenu((**menu).menuID);
  208.                 mitem = LoWord(mresult);
  209.  
  210.                 cmerr = SetFlagFromMenuItem( resID, flagPtr, mitem ) ;
  211.                 
  212.                 if (!cmerr)
  213.                 {
  214.                     cmerr = CMSetProfileHeader(prof, &head) ;
  215.                     SetWinDirty( win, true ) ;
  216.                     InvalRect( &varsRect ) ;
  217.                     DoAppAdjustMenus() ;        // undim app items
  218.                 }
  219.             }
  220.             DisposeMenu(menu);
  221.         }
  222.     }
  223. }
  224.  
  225.  
  226. /*------------------------------------------------------------------------------*\
  227.     winCloseProfile
  228.  *------------------------------------------------------------------------------*
  229.         This is a CloseProcPtr for Profile windows.
  230.         So far, all this does is call DisposeWinHandle()
  231.         This win type doesn't need to be saved so ther is no reason to prompt the
  232.         user to save the file here.
  233.         This ProcPtr is envoked by CallWinCloseProc() which is called by:
  234.             DoMouseDownEvent() which dispached click events (e.g. close box), and
  235.             MenuProcPtrs which are called whenever menu events occur.
  236. \*------------------------------------------------------------------------------*/
  237. void    winCloseProfile ( winHandle win ) 
  238. {
  239.     DisposeWinHandle( win ) ;
  240. }
  241.  
  242.  
  243. /*------------------------------------------------------------------------------*\
  244.     winMenuProfile
  245.  *------------------------------------------------------------------------------*
  246.         This is a MenuProcPtr for Profile windows.
  247.         This routine dispatches any menu commands that the window can handle
  248.         to the appropriate function.
  249.         This ProcPtr is envoked by CallWinMenuProc() which is called by:
  250.             HandleMenuCommand() which dispatches all menu events.
  251. \*------------------------------------------------------------------------------*/
  252. void winMenuProfile ( winHandle win, long menuResult, Boolean *didit )
  253. {
  254.     short            menuID;
  255.     short            menuItem;
  256.     
  257.     *didit = true ;
  258.     menuID   = HiWrd(menuResult) ;
  259.     menuItem = LoWrd(menuResult) ;
  260.     switch ( menuID )
  261.     {
  262.         case mFile:
  263.             switch ( menuItem )
  264.             {
  265.                 case iSave:                // save this document under the name it was opened
  266.                     SaveCmndProfile( win ) ;
  267.                     break ;
  268.                 case iSaveAs:            // save this document under a new name
  269.                     SaveAsCmndProfile( win ) ;
  270.                     break ;
  271.                 case iRevert:            // discard all changes made to the document since it was last saved
  272.                     RevertCmndProfile( win ) ;
  273.                     break ;
  274.                 default :
  275.                     *didit = false ;
  276.                     break ;
  277.             }
  278.             break ;
  279.  
  280.         case mProfiles:
  281.             switch ( menuItem )
  282.             {
  283.                 case iSetDefaultProf:
  284.                     ProfMakeSysProfileCmnd( win ) ;
  285.                     break ;
  286.                 case iCreateProfID:
  287.                     ProfCreateProfIDCmnd( win ) ;
  288.                     break ;
  289.                 default :
  290.                     *didit = false ;
  291.                     break ;
  292.             }
  293.             break ;
  294.  
  295.         default :
  296.             *didit = false ;
  297.             break ;
  298.     }
  299.     HiliteMenu(0) ;        // Unhighlight whatever MenuSelect or MenuKey hilited
  300. }
  301.  
  302.     
  303. /*------------------------------------------------------------------------------*\
  304.     winUpdateMenusProfile
  305.  *------------------------------------------------------------------------------*
  306.         This is a UpdateMenuProcPtr for Profile windows.
  307.         This routine enables any menu commands that the window can handle.
  308.         This ProcPtr is envoked by CallWinUpdateMenusProc() which is called by:
  309.             DoAppAdjustMenus() which dispatches all menu events.
  310. \*------------------------------------------------------------------------------*/
  311. void winUpdateMenusProfile ( winHandle win ) 
  312. {
  313.     MenuHandle        theMenu ;
  314.     FSSpec            spec ;
  315.     Boolean            dirty ;
  316.     Boolean            hasFile ;
  317.     OSType            subtype ;
  318.     winHandle        frontWin;
  319.     
  320.     frontWin = GetFrontWindowWinHandle() ;
  321.     
  322.     if ( win == frontWin )
  323.     {
  324.         spec = GetWinFSSpec( win ) ;
  325.         dirty = GetWinDirty( win ) ;
  326.         hasFile = ( spec.name[0] > 0 ) ;
  327.         subtype = GetWinSubtype( win ) ;
  328.  
  329.         // do the file menu
  330.         theMenu = GetMenuHandle ( mFile ) ;
  331.     
  332.             EnableItem ( theMenu, kWholeMenu ) ;
  333.             EnableItem ( theMenu, iClose ) ;
  334.             EnableItem ( theMenu, iSaveAs ) ;
  335.         
  336.             // for the next 2, check to see if the document has been changed
  337.             if ( dirty && subtype==kFileSubType)
  338.                 EnableItem ( theMenu, iSave ) ;
  339.             if ( dirty && subtype==kFileSubType && hasFile )
  340.                 EnableItem ( theMenu, iRevert ) ;
  341.  
  342.         // do the profiles menu
  343.         theMenu = GetMenuHandle ( mProfiles ) ;
  344.         
  345.             EnableItem ( theMenu, kWholeMenu ) ;
  346.             EnableItem ( theMenu, iCreateProfID ) ;
  347.             if ( subtype==kFileSubType )
  348.                 EnableItem ( theMenu, iSetDefaultProf ) ;
  349.     }
  350. }
  351.  
  352.  
  353. /*------------------------------------------------------------------------------*\
  354.     winAllocProfile
  355.  *------------------------------------------------------------------------------*
  356.         This is a AllocProcPtr for Profile windows.
  357.         This routine is responsible for filling in all the needed fields of the
  358.         winHandle structure.  This routine shouldn't be called directly.
  359.         Instead, the code which needs to create a document of this type should
  360.         call NewWinHandle(win,winAllocProfile) to envoke this function.
  361.         This ProcPtr is envoked by NewWinHandle() which is called by:
  362.             app_aeODOC_handler() which handles ODOC AppleEvents, and
  363.             app_aePDOC_handler() which handles PDOC AppleEvents.
  364. \*------------------------------------------------------------------------------*/
  365. OSErr winAllocProfile ( winHandle win )
  366. {
  367.     OSErr            err = noErr ;
  368.     ProfileDataHdl    data ;
  369.         
  370.     // we need ColorSync 2.
  371.     if (!CS2_available())
  372.         return eWarnNoColorSync ;
  373.  
  374.     // set the window type
  375.     SetWinType( win, kProfileType ) ;
  376.     
  377.     // stuff winHandle fields
  378.     SetWinUpdateProc        ( win,      (UpdateProcPtr) winUpdateProfile ) ;
  379.     SetWinClickProc            ( win,       (ClickProcPtr) winClickProfile ) ;
  380.     SetWinMenuProc            ( win,        (MenuProcPtr) winMenuProfile ) ;
  381.     SetWinUpdateMenusProc    ( win, (UpdateMenusProcPtr) winUpdateMenusProfile ) ;
  382.     SetWinOpenProc            ( win,        (OpenProcPtr) winOpenProfile ) ;
  383.     SetWinCloseProc            ( win,       (CloseProcPtr) winCloseProfile ) ;
  384.     SetWinDisposeProc        ( win,     (DisposeProcPtr) winDisposeProfile ) ;
  385.  
  386.     // allocate data handle
  387.     data = (ProfileDataHdl)NewHandleClear( sizeof(ProfileDataRec) ) ;    
  388.     if( data == nil ) return MemError() ;
  389.     SetWinData( win, (Handle)data ) ;
  390.     
  391.     // stuff ProfileDataHdl fields
  392.     SetWinSubtype( win, kFileSubType ) ;    // set default subtype
  393.     
  394.     return err ;    
  395. }
  396.  
  397.  
  398. /*------------------------------------------------------------------------------*\
  399.     winOpenProfile
  400.  *------------------------------------------------------------------------------*
  401.         This is a OpenProcPtr for Profile windows.
  402.         This routine is responsible for opening a Profile window after all the
  403.         needed fields of the winHandle structure have been filled in by winAllocProfile.
  404.         On entry the DocumentRecord must contain a valid FSSpec.
  405.         If a Profile window for the FSSpec is already onen, then this routine 
  406.         will bring it to the front instead of opening a second window.
  407.         This routine shouldn't be called directly.  Instead, the code which needs
  408.         to create a document of this type should call NewWinHandle(win,winAllocProfile),
  409.         SetWinFSSpec (win,spec), and then CallWinOpenProc(win) to envoke this function.
  410.         This ProcPtr is envoked by CallWinOpenProc() which is called by:
  411.             app_aeODOC_handler() which handles ODOC AppleEvents, and
  412.             app_aePDOC_handler() which handles PDOC AppleEvents.
  413. \*------------------------------------------------------------------------------*/
  414. OSErr winOpenProfile ( winHandle win )
  415. {
  416.     OSErr                err = noErr ;
  417.     winHandle            existingWin ;
  418.     FSSpec                spec ;
  419.     CMProfileRef         prof ;
  420.     CMProfileLocation    profLoc ;
  421.     OSType                subtype ;    // this is the subtype of window ('file' 'embd' or 'sysp')
  422.     unsigned long        index ;        // if embeded subtype then this tells us which one
  423.     Boolean                alreadyOpen = false;
  424.     short                count, i ;
  425.     
  426.     spec = GetWinFSSpec( win ) ;
  427.     subtype = GetWinSubtype( win ) ;
  428.     index = GetProfileIndex( win ) ;
  429.  
  430.     // see if already open
  431.     switch (subtype)
  432.     {
  433.         case kFileSubType :
  434.              if ( FindWinHandle( &spec, kProfileType, subtype, 1, 1, &existingWin ) == 1 )
  435.                  alreadyOpen = true ;
  436.              break ;
  437.              
  438.         case kEmbededSubType :
  439.             count = FindWinHandle( &spec, kProfileType, subtype, 0, 0, nil ) ;
  440.             for (i=1; i<=count && !alreadyOpen; i++)
  441.             {
  442.                 if ( FindWinHandle( &spec, kProfileType, subtype, i, 1, &existingWin ) == 1 )
  443.                     if ( GetProfileIndex(existingWin) == index )
  444.                         alreadyOpen = true ;
  445.             }
  446.              break ;
  447.              
  448.         case kSysProfSubType :
  449.              if ( FindWinHandle( nil, kProfileType, subtype, 1, 1, &existingWin ) == 1 )
  450.                  alreadyOpen = true ;
  451.              break ;
  452.     }
  453.      
  454.      if (alreadyOpen)
  455.     {
  456.         // bring it to the front
  457.         SelectWindow( GetWinWindow(existingWin) ) ;        
  458.         return kWasAlreadyOpen ;
  459.     }
  460.  
  461.     switch (subtype)
  462.     {
  463.         case kFileSubType :
  464.             err = OpenProfileFSSpec( spec, &prof ) ;
  465.             if ( err ) return err;
  466.             SetProfileRef( win, prof ) ;            // set the window's data's profile ref
  467.             break ;
  468.             
  469.         case kEmbededSubType :
  470.             //? the prof is valid
  471.             //? the spec is the spec of the pict file
  472.             break ;
  473.             
  474.         case kSysProfSubType :
  475.             err = CMGetSystemProfile( &prof ) ;
  476.             err = CMGetProfileLocation( prof, &profLoc) ;
  477.             if ( err ) return err ;
  478.             if ( profLoc.locType != cmFileBasedProfile )
  479.                 return fnfErr ;                        //? should also close prof
  480.             spec = profLoc.u.fileLoc.spec ;
  481.             SetWinFSSpec( win, &spec ) ;
  482.             SetProfileRef( win, prof ) ;            // this should be nil already
  483.             break ;
  484.     }
  485.     
  486.     err = DoCreateProfWindow( win ) ;
  487.     return err ;    
  488. }
  489.  
  490.  
  491. /*------------------------------------------------------------------------------*\
  492.     winDisposeProfile
  493.  *------------------------------------------------------------------------------*
  494.         This is a DisposeProcPtr for Profile windows.
  495.         This routine is responsible for disposing of any data that was allocated
  496.         by the document and stored in the its data handle.
  497.         This ProcPtr is envoked by CallWinDisposeProc() which is called by:
  498.             DisposeWinHandle() which disposes of the entire winHandle.
  499. \*------------------------------------------------------------------------------*/
  500. void winDisposeProfile ( winHandle win )
  501. {
  502.     ProfileDataHdl    data ;
  503.     CMProfileRef    prof ;
  504.  
  505.     data = (ProfileDataHdl) GetWinData ( win ) ;
  506.     if ( data==nil ) return;
  507.  
  508.     prof = GetProfileRef( win ) ;
  509.     if ( prof != nil )
  510.         CMCloseProfile( prof ) ;
  511.  
  512.     // lastly, dispose of the data handle
  513.     DisposeHandle( (Handle)data ) ;
  514. }
  515.  
  516.  
  517. /**\
  518. |**| ==============================================================================
  519. |**| PRIVATE FUNCTIONS
  520. |**| ==============================================================================
  521. \**/
  522.  
  523.  
  524. static void DoDrawProfData ( winHandle win ) 
  525. {    
  526.     long                length ;
  527.     Rect                labelRect, varsRect, whereRect, iconRect ; // = {7,53,39,85} ;
  528.     Handle                labelText, varText,  whereText ;
  529.     CMProfileRef        prof ;    
  530.     CMError                cmerr ;
  531.     OSType                subtype ;
  532.     unsigned long        vers ;
  533.     Str255                name, path ;
  534.     FSSpec                spec ;
  535.  
  536. // get rects from resources
  537.     labelRect = GetRect ( rProfileLabelsStringID ) ;
  538.     varsRect = GetRect ( rProfileVarsStringID ) ;
  539.     whereRect = GetRect ( rProfileWhereVarStringID ) ;
  540.     iconRect = GetRect ( rProfileIconID ) ;
  541.  
  542. // draw icon
  543.     PlotIconID( &iconRect, atNone, ttNone, rProfileIconID ) ;
  544.  
  545. // draw labels
  546.     TextSize(9) ;
  547.     TextFace(bold) ;
  548.     TextFont(geneva) ;
  549.  
  550.     labelText = GetResource( 'TEXT', rProfileLabelsStringID ) ;
  551.     
  552.     HLock( labelText ) ;
  553.     length = GetHandleSize( labelText ) ;
  554.     TETextBox( *labelText, length, &labelRect, teFlushRight) ;
  555.     HUnlock( labelText ) ;
  556.     ReleaseResource( labelText ) ;
  557.  
  558.     TextSize(9) ;
  559.     TextFace(0) ;
  560.     TextFont(geneva) ;
  561.  
  562. // get the profile's vital stats
  563.     subtype = GetWinSubtype( win ) ;
  564.     prof = GetProfileRef( win ) ;
  565.     spec = GetWinFSSpec( win ) ;
  566.     
  567. // get the profile's name element
  568.     cmerr = GetProfName ( prof, (StringPtr)&name ) ;
  569.     if (cmerr) return ;
  570.  
  571. // draw the profile's name
  572.     MoveTo (varsRect.left,varsRect.top-19) ;
  573.     if ( IsPseudoProfile(prof) )
  574.         TextFace(italic) ;
  575.     DrawString( name ) ;
  576.     TextFace(0) ;
  577.  
  578. // get profile version
  579.     cmerr = GetProfVersion ( prof, &vers) ;
  580.     if (cmerr) return ;
  581.  
  582. // set up the profile info text
  583.     varText = GetResource( 'TEXT', rProfileVarsStringID ) ;
  584.     if (vers == cmCS1ProfileVersion)
  585.         MungeProfileHeader1( prof, varText ) ;
  586.     else if (vers >= cmCS2ProfileVersion)
  587.         MungeProfileHeader2( prof, varText ) ;
  588.     else return ;                            // need a better error code here
  589.  
  590. // set up the "where" info text
  591.     whereText = GetResource( 'TEXT', rProfileWhereVarStringID ) ;
  592.     FSSpecToString( GetWinFSSpec(win), path, (subtype==kEmbededSubType) ) ;
  593.     MyReplaceText ( whereText, path, "\p«Where»" ) ;
  594.     MyReplaceText ( whereText, "\p:\0", "\p:" ) ;
  595.  
  596. // draw the profile info
  597.     HLock( varText ) ;
  598.     length = GetHandleSize( varText ) ;
  599.     TETextBox( *varText, length, &varsRect, teFlushLeft) ;
  600.     HUnlock( varText ) ;
  601.     ReleaseResource( varText ) ;    
  602.  
  603. // draw the "where" information
  604.     HLock( whereText ) ;
  605.     length = GetHandleSize( whereText ) ;
  606.     TETextBox( *whereText, length, &whereRect, teFlushLeft) ;
  607.     HUnlock( whereText ) ;
  608.     ReleaseResource( whereText ) ;
  609. }
  610.  
  611.  
  612. /*------------------------------------------------------------------------------*\
  613. \*------------------------------------------------------------------------------*/
  614. static void MungeProfileHeader1 ( CMProfileRef prof, Handle text )
  615. {
  616.     CMAppleProfileHeader    head ;
  617.     CMHeader                cm1 ;
  618.     Str255                    myStr ;
  619.     CMError                    cmerr ;
  620.     
  621. // get the profile's header
  622.     cmerr = CMGetProfileHeader(prof, &head) ;
  623.     if (cmerr) return ;
  624.     cm1 = head.cm1 ;
  625.     
  626. // Vers
  627.     MyReplaceText( text, "\p1.0", "\p«Vers»" ) ;
  628. // Embed
  629. // Size
  630.     FormatLong( cm1.size, rBytesFMAT, myStr) ;
  631.     MyReplaceText( text, myStr, "\p«Size»" ) ;
  632. // ColorSpace
  633.     ColorSpace2String ( cm1.dataType, myStr ) ;
  634.     MyReplaceText( text, myStr, "\p«ColorSpace»" ) ;
  635. // InterchangeSpace
  636.     ColorSpace2String ( 'XYZ ', myStr ) ;
  637.     MyReplaceText( text, myStr, "\p«XchngSpace»" ) ;
  638. // CMM
  639.     OSTypeToString( cm1.CMMType, myStr) ;
  640.     MyReplaceText( text, myStr, "\p«CMM»" ) ;
  641. // Class
  642.     ProfileClass2String ( cm1.deviceType, myStr ) ;
  643.     MyReplaceText( text, myStr, "\p«Class»" ) ;
  644. // Manufacturer
  645.     OSTypeToString( cm1.deviceManufacturer, myStr) ;
  646.     MyReplaceText( text, myStr, "\p«Manufacturer»" ) ;
  647. // DeviceModel
  648.     LongHexToString ( cm1.deviceModel, myStr) ;
  649.     MyReplaceText( text, myStr, "\p«DeviceModel»" ) ;
  650. // Attributes
  651.     LongHexToString ( cm1.deviceAttributes[0], myStr) ;
  652.     MyReplaceText( text, myStr, "\p«Attributes0»" ) ;
  653.     LongHexToString ( cm1.deviceAttributes[1], myStr) ;
  654.     MyReplaceText( text, myStr, "\p«Attributes1»" ) ;
  655. // Flags
  656.     LongHexToString ( cm1.flags, myStr) ;
  657.     MyReplaceText( text, myStr, "\p«Flags»" ) ;
  658. // Intent
  659.     RendIntent2String ( cm1.options, myStr ) ;
  660.     MyReplaceText( text, myStr, "\p«Intent»" ) ;
  661. // White
  662.     MyReplaceText( text, "\p«X», «Y», «Z»", "\p«White»" ) ;
  663.     FormatSmallFract( cm1.white.X, rDotThreeFMAT, myStr ) ;
  664.     MyReplaceText( text, myStr, "\p«X»" ) ;
  665.     FormatSmallFract( cm1.white.Y, rDotThreeFMAT, myStr ) ;
  666.     MyReplaceText( text, myStr, "\p«Y»" ) ;
  667.     FormatSmallFract( cm1.white.Z, rDotThreeFMAT, myStr ) ;
  668.     MyReplaceText( text, myStr, "\p«Z»" ) ;
  669. // Created
  670.     MyReplaceText( text, "\p--", "\p«Created»" ) ;
  671. }
  672.  
  673.  
  674. /*------------------------------------------------------------------------------*\
  675. \*------------------------------------------------------------------------------*/
  676. static void MungeProfileHeader2 ( CMProfileRef prof, Handle text )
  677. {
  678.     CMAppleProfileHeader    head ;
  679.     CM2Header                cm2 ;
  680.     Str255                    myStr ;
  681.     CMError                    cmerr ;
  682.     unsigned long            rawSecs ;
  683.  
  684. // get the profile's header
  685.     cmerr = CMGetProfileHeader(prof, &head) ;
  686.     if (cmerr) return ;
  687.     cm2 = head.cm2 ;
  688.     
  689. // Vers
  690.     VersionToString( cm2.profileVersion, myStr) ;
  691.     MyReplaceText( text, myStr, "\p«Vers»" ) ;
  692. // Embed
  693. // Size
  694.     FormatLong( cm2.size, rBytesFMAT, myStr) ;
  695.     MyReplaceText( text, myStr, "\p«Size»" ) ;
  696. // ColorSpace
  697.     ColorSpace2String ( cm2.dataColorSpace, myStr ) ;
  698.     MyReplaceText( text, myStr, "\p«ColorSpace»" ) ;
  699. // InterchangeSpace
  700.     ColorSpace2String ( cm2.profileConnectionSpace, myStr ) ;
  701.     MyReplaceText( text, myStr, "\p«XchngSpace»" ) ;
  702. // CMM
  703.     OSTypeToString( cm2.CMMType, myStr) ;
  704.     MyReplaceText( text, myStr, "\p«CMM»" ) ;
  705. // Class
  706.     OSTypeToString( cm2.profileClass, myStr) ;
  707.     ProfileClass2String ( cm2.profileClass, myStr ) ;
  708.     MyReplaceText( text, myStr, "\p«Class»" ) ;
  709. // Manufacturer
  710.     OSTypeToString( cm2.deviceManufacturer, myStr) ;
  711.     MyReplaceText( text, myStr, "\p«Manufacturer»" ) ;
  712. // DeviceModel
  713.     LongHexToString ( cm2.deviceModel, myStr) ;
  714.     MyReplaceText( text, myStr, "\p«DeviceModel»" ) ;
  715. // Attributes
  716.     LongHexToString ( cm2.deviceAttributes[0], myStr) ;
  717.     MyReplaceText( text, myStr, "\p«Attributes0»" ) ;
  718.     LongHexToString ( cm2.deviceAttributes[1], myStr) ;
  719.     MyReplaceText( text, myStr, "\p«Attributes1»" ) ;
  720. // Flags
  721.     LongHexToString ( cm2.flags, myStr) ;
  722.     MyReplaceText( text, myStr, "\p«Flags»" ) ;
  723. // Intent
  724.     RendIntent2String ( cm2.renderingIntent, myStr ) ;
  725.     MyReplaceText( text, myStr, "\p«Intent»" ) ;
  726. // White
  727.     MyReplaceText( text, "\p«X», «Y», «Z»", "\p«White»" ) ;
  728.     FormatFixed( cm2.white.X, rDotThreeFMAT, myStr) ;
  729.     MyReplaceText( text, myStr, "\p«X»" ) ;
  730.     FormatFixed( cm2.white.Y, rDotThreeFMAT, myStr) ;
  731.     MyReplaceText( text, myStr, "\p«Y»" ) ;
  732.     FormatFixed( cm2.white.Z, rDotThreeFMAT, myStr) ;
  733.     MyReplaceText( text, myStr, "\p«Z»" ) ;
  734. // Created
  735.     MyReplaceText( text, "\p«Date», «Time»", "\p«Created»" ) ;
  736.     DateToSeconds( (DateTimeRec*)&(cm2.dateTime), &rawSecs) ;
  737.     IUDateString( rawSecs, abbrevDate, myStr) ;
  738.     MyReplaceText( text, myStr, "\p«Date»" ) ;
  739.     IUTimeString( rawSecs, false, myStr) ;
  740.     MyReplaceText( text, myStr, "\p«Time»" ) ;
  741. }
  742.  
  743.  
  744. static OSErr RendIntent2String ( unsigned long intent, StringPtr dest )
  745. {
  746.     return GetFlagListStringPtr( 1000, intent, dest ) ;
  747. }
  748.  
  749. static OSErr ColorSpace2String ( OSType spaceType, StringPtr dest )
  750. {
  751.     return GetOSTypeListStringPtr( 129, spaceType, dest ) ;
  752. }
  753.  
  754. static OSErr ProfileClass2String ( OSType classType, StringPtr dest )
  755. {
  756.     return GetOSTypeListStringPtr( 128, classType, dest ) ;
  757. }
  758.  
  759.  
  760.  
  761.  
  762.  
  763. /*------------------------------------------------------------------------------*\
  764.     DoCreateProfWindow
  765.  *------------------------------------------------------------------------------*
  766.         This routine actually creates the WindowRef for a winHandle.
  767.         After creating the window, it:
  768.             reference the window and the DocumentRecord to each other,
  769.             makes the window the current port,
  770.             resizes the window according to the WIND resource,
  771.             titles it according the the FSSpec, and
  772.             makes it visible .
  773.         This routine is called by:
  774.             winOpenProfList() which fills in the winHandle structure
  775. \*------------------------------------------------------------------------------*/
  776. static OSErr DoCreateProfWindow ( winHandle win )
  777. {
  778.     OSErr            err = noErr ;
  779.     WindowRef        window ;
  780.     FSSpec            spec ;
  781.     CMProfileRef     prof ;
  782.     OSType            subtype ;
  783.     Str255            winTitle="\p" ;
  784.         
  785.     // create the window
  786.     window = GetNewCWindow(rProfileWindID, nil, (WindowRef)-1 ) ;
  787.             
  788.     SetWinWindow( win, window ) ;            // save a reference to the window in the winRecord
  789.     SetWindowWinHandle ( window, win ) ;        // save a reference to the winRecord in the window
  790.  
  791.     SetGWorld( (CGrafPtr)GetWinWindow(win), nil ) ;    // set the window to be the current port
  792.  
  793.     SetWinRect( win, ((CGrafPtr)window)->portRect ) ;
  794.  
  795.     spec = GetWinFSSpec( win ) ;
  796.     prof = GetProfileRef( win ) ;
  797.     subtype = GetWinSubtype( win ) ;
  798.  
  799.     // set the name of this document window
  800.     switch (subtype)
  801.     {
  802.         case kFileSubType :
  803.             SetWTitle( window, spec.name ) ;
  804.             break ;
  805.             
  806.         case kEmbededSubType :
  807.             NumToString( GetProfileIndex(win), winTitle ) ;
  808.             pStrIns( winTitle, "\p:", 255 ) ;
  809.             pStrIns( winTitle, spec.name, 255 ) ;
  810.             SetWTitle( window, winTitle ) ;
  811.             break ;
  812.             
  813.         case kSysProfSubType :
  814.             err = GetProfName( nil, winTitle ) ;
  815.             SetWTitle( window, winTitle ) ;
  816.             break ;
  817.     }
  818.     
  819.     // make sure it is visible
  820.     ShowWindow( window ) ;
  821.     
  822.     return err ;
  823. }
  824.  
  825.  
  826. static void ProfMakeSysProfileCmnd ( winHandle win ) 
  827. {
  828.     OSType            subtype ;
  829.     OSErr            err ;
  830.     FSSpec            spec ;
  831.     
  832.     subtype = GetWinSubtype( win ) ;
  833.     if ( subtype==kFileSubType )
  834.     {
  835.         spec = GetWinFSSpec( win ) ;
  836.         err = CMSetSystemProfile( &spec ) ;
  837.     }
  838. }
  839.  
  840. static void ProfCreateProfIDCmnd ( winHandle win ) 
  841. {
  842.     OSErr                    err ;
  843.     CMProfileRef            prof ;
  844.     unsigned long            size ;
  845.     CMProfileIdentifierHdl    ident ;
  846.     winHandle                newwin ;
  847.     
  848.     prof = GetProfileRef( win ) ;
  849.     
  850.     err = CMCreateProfileIdentifierCompat( prof, nil, &size) ;
  851.     if (err) return ;
  852.     ident = (CMProfileIdentifierHdl) NewHandle( size );
  853.     if (!ident) return ;
  854.     HLock( (Handle)ident );
  855.     err = CMCreateProfileIdentifierCompat( prof, *ident, &size) ;
  856.     HUnlock( (Handle)ident );
  857.     
  858.     
  859.     // create a new winHandle of the proper type
  860.     err = NewWinHandle( &newwin, winAllocProfID ) ;
  861.     WarnIfErr( err ) ;
  862.     if (err) return ;
  863.  
  864.     // set the subtype of the winHandle so that the correct search is done
  865.     SetProfIDIDHdl( newwin, ident ) ;
  866.     SetWinSubtype( newwin, kHandleSubType ) ;    // set subtype
  867.     
  868.     err = CallWinOpenProc( newwin ) ;
  869.     if ( err != noErr )
  870.         DisposeWinHandle( newwin ) ;
  871.  
  872.     if ( err == kWasAlreadyOpen )
  873.         err = noErr;
  874. }
  875.  
  876.  
  877. /*------------------------------------------------------------------------------*\
  878.     SaveCmndProfile
  879.  *------------------------------------------------------------------------------*
  880. \*------------------------------------------------------------------------------*/
  881. static void SaveCmndProfile ( winHandle win ) 
  882. {
  883.     FSSpec                spec ;
  884.     Boolean                dirty ;
  885.     Boolean                hasFile ;
  886.     OSErr                err ;
  887.     OSType                subtype ;
  888.     
  889.     spec = GetWinFSSpec( win ) ;
  890.     dirty = GetWinDirty( win ) ;
  891.     hasFile = ( spec.name[0] > 0 ) ;
  892.     subtype = GetWinSubtype( win ) ;
  893.     GetProfileRef( win ) ;
  894.  
  895.     if ( !dirty ) return;                // no need to save
  896.     if ( subtype!=kFileSubType) return;    // can't save
  897.     
  898.     if ( !hasFile )
  899.         SaveAsCmndProfile( win ) ;
  900.     else
  901.     {
  902.         err = CMUpdateProfile(GetProfileRef(win));
  903.         if (err) return ;                // if err, should do something
  904.         SetWinDirty( win, false ) ;
  905.         DoAppAdjustMenus() ;            // undim app items
  906.     }
  907. }
  908.  
  909.  
  910. /*------------------------------------------------------------------------------*\
  911.     SaveAsCmndProfile
  912.  *------------------------------------------------------------------------------*
  913. \*------------------------------------------------------------------------------*/
  914. static void SaveAsCmndProfile ( winHandle win ) 
  915. {
  916.     FSSpec                spec ;
  917.     Boolean                dirty ;
  918.     Boolean                hasFile ;
  919.     StandardFileReply    reply ;
  920.     OSErr                err ;
  921.     WindowRef            window ;
  922.     Str255                title ;
  923.     OSType                subtype ;
  924.     
  925.     spec = GetWinFSSpec( win ) ;
  926.     dirty = GetWinDirty( win ) ;
  927.     hasFile = ( spec.name[0] > 0 ) ;
  928.     subtype = GetWinSubtype( win ) ;
  929.     window = GetWinWindow( win ) ;
  930.     
  931.     if ( hasFile )
  932.         StringToString( spec.name, title ) ;
  933.     else
  934.         GetWTitle( window, title ) ;
  935.     
  936.     StandardPutFile( "\pSave profile as:", title, &reply) ;
  937.     if ( reply.sfGood )
  938.     {
  939.         CMProfileRef        newProf, prof;
  940.         CMProfileLocation    profLoc ;
  941.         
  942.         profLoc.locType = cmFileBasedProfile;
  943.         profLoc.u.fileLoc.spec = reply.sfFile;
  944.         
  945.         prof = GetProfileRef(win);
  946.         err = CMCopyProfile( &newProf, &profLoc, prof) ;
  947.         WarnIfErr( err ) ;
  948.         if ( err ) return ;                    // if err, should do something 
  949.         SetWinFSSpec( win, &spec ) ;        // win's spec = new spec
  950.         SetWTitle( window, spec.name ) ;    // win title = new title
  951.         SetProfileRef(win, newProf);
  952.         SetWinDirty( win, false ) ;
  953.         DoAppAdjustMenus() ;                // undim app items
  954.     }
  955. }
  956.  
  957.  
  958. /*------------------------------------------------------------------------------*\
  959.     RevertCmndProfile
  960.  *------------------------------------------------------------------------------*
  961. \*------------------------------------------------------------------------------*/
  962. static void RevertCmndProfile ( winHandle win ) 
  963. {    
  964.     FSSpec                spec ;
  965.     Boolean                dirty ;
  966.     Boolean                hasFile ;
  967.     OSType                subtype ;
  968.  
  969.     spec = GetWinFSSpec( win ) ;
  970.     dirty = GetWinDirty( win ) ;
  971.     hasFile = ( spec.name[0] > 0 ) ;
  972.     subtype = GetWinSubtype( win ) ;
  973.     
  974.     if ( !dirty || !hasFile ) return ;
  975.     if ( subtype!=kFileSubType) return;    // can't revert
  976.         
  977.                                     // ask user if it's ok
  978.     
  979.     SetWinDirty( win, false ) ;        // clear dirty so we don't get another dialog
  980.     CallWinCloseProc( win ) ;        // close the document
  981.     SendODOC( &spec ) ;                // reopen: send ODOC event to ourselves:
  982. //    DoAppAdjustMenus() ;            // undim app items
  983. }
  984.  
  985.  
  986. #define LMGetWMgrCPort() (* (GrafPtr *) 0x0D2C)
  987.  
  988. static long PopUpMenuSelectFont (MenuHandle theMenu,
  989.                             short top, short left,
  990.                               short popUpItem,
  991.                               short font, short size)
  992. {
  993.     long    result;
  994.     short    SaveSysFontFam;
  995.     GrafPtr    wmPtr,wmCPtr;
  996.     short    SaveWPortFont;
  997.     short    SaveWPortSize;
  998.     
  999.     wmPtr  = LMGetWMgrPort();
  1000.     wmCPtr = LMGetWMgrCPort();
  1001.     SaveWPortFont  = wmPtr->txFont;
  1002.     SaveWPortSize  = wmPtr->txSize;
  1003.     
  1004.     SaveSysFontFam = LMGetSysFontFam();
  1005.     LMSetSysFontFam(font);
  1006.     wmCPtr->txFont = font;
  1007.     wmCPtr->txSize = size;
  1008.     wmPtr->txFont  = font;
  1009.     wmPtr->txSize  = size;
  1010.     
  1011.     result = PopUpMenuSelect(theMenu,top,left,popUpItem);
  1012.     
  1013.     LMSetSysFontFam(SaveSysFontFam);
  1014.     wmCPtr->txFont = SaveWPortFont;
  1015.     wmCPtr->txSize = SaveWPortSize;
  1016.     wmPtr->txFont  = SaveWPortFont;
  1017.     wmPtr->txSize  = SaveWPortSize;
  1018.     
  1019.     return result;
  1020. }
  1021.  
  1022.  
  1023. /*------------------------------------------------------------------------------*\
  1024.     GetFlagListStringPtr
  1025.  *------------------------------------------------------------------------------*
  1026.         This routine loads a 'BTS#' resource and loops through it looking
  1027.         for the string that coresponds to the type parameter.
  1028. \*------------------------------------------------------------------------------*/
  1029.  
  1030. static OSErr GetFlagListStringPtr( short id, unsigned long flags, StringPtr dest )
  1031. {
  1032.     short            i, count;
  1033.     short            shift ;
  1034.     long            maskShift, valueShift ;
  1035.     FlagListHdl        list ;
  1036.     
  1037.     list = (FlagListHdl) GetResource('BTS#', id) ;
  1038.     if (list==nil) return ResError() ;
  1039.     
  1040.     count = (**list).count ;
  1041.     dest[0] = 0 ;
  1042.     
  1043.     for (i=0; i<count; i++ )
  1044.     {
  1045.         shift = (**list).entry[i].shift ;
  1046.         maskShift  = ((unsigned long)((**list).entry[i].mask))  << shift ;
  1047.         valueShift = ((unsigned long)((**list).entry[i].value)) << shift ;
  1048.  
  1049.         if ( (flags & maskShift) == valueShift )
  1050.         {
  1051.             if (dest[0]) pStrCat( dest, "\p, ", 255 );
  1052.             pStrCat( dest, (StringPtr)&((**list).entry[i].string), 255 );
  1053.         }
  1054.     }
  1055.     ReleaseResource( (Handle)list ) ;
  1056.     return noErr ;
  1057. }
  1058.  
  1059. static OSErr BuildFlagListMenu ( short id, unsigned long flags, MenuHandle menu )
  1060. {
  1061.     short            j, i, count;
  1062.     short            shift, lastshift ;
  1063.     long            maskShift, valueShift ;
  1064.     FlagListHdl        list ;
  1065.     
  1066.     list = (FlagListHdl) GetResource('BTS#', id) ;
  1067.     if (list==nil) return ResError() ;
  1068.     
  1069.     count = (**list).count ;
  1070.     
  1071.     for (j=i=0; i<count; i++, j++ )
  1072.     {
  1073.         shift = (**list).entry[i].shift ;
  1074.         maskShift  = ((unsigned long)((**list).entry[i].mask))  << shift ;
  1075.         valueShift = ((unsigned long)((**list).entry[i].value)) << shift ;
  1076.  
  1077.         if ( (i!=0) && (lastshift!=shift) )
  1078.         {
  1079.             AppendMenu( menu, "\p-" );
  1080.             j++;
  1081.         }
  1082.             
  1083.         AppendMenu(menu, (StringPtr)&((**list).entry[i].string) );
  1084.         if ( (flags & maskShift) == valueShift )
  1085.             SetItemMark(menu,j+1,0xC3);
  1086.         
  1087.         lastshift = shift ;
  1088.     }
  1089.     ReleaseResource( (Handle)list ) ;
  1090.     return noErr ;
  1091. }
  1092.  
  1093. static OSErr SetFlagFromMenuItem ( short id, unsigned long *flags, short mitem )
  1094. {
  1095.     short            j, i, count;
  1096.     short            shift, lastshift ;
  1097.     long            maskShift, valueShift ;
  1098.     FlagListHdl        list ;
  1099.     unsigned long    flagsBefore ;
  1100.     
  1101.     flagsBefore = *flags ;
  1102.  
  1103.     list = (FlagListHdl) GetResource('BTS#', id) ;
  1104.     if (list==nil) return ResError() ;
  1105.     
  1106.     count = (**list).count ;
  1107.     
  1108.     for (j=i=0; i<count; i++, j++ )
  1109.     {
  1110.         shift = (**list).entry[i].shift ;
  1111.         maskShift  = ((unsigned long)((**list).entry[i].mask))  << shift ;
  1112.         valueShift = ((unsigned long)((**list).entry[i].value)) << shift ;
  1113.  
  1114.         if ( (i!=0) && (lastshift!=shift) )
  1115.             j++;
  1116.         
  1117.         if (mitem == j+1)
  1118.             *flags = ((*flags) & (~maskShift)) | (valueShift);
  1119.  
  1120.         lastshift = shift ;
  1121.     }
  1122.     ReleaseResource( (Handle)list ) ;
  1123.     
  1124.     return (flagsBefore == *flags) ;        // return something if there was no change
  1125. }
  1126.  
  1127.  
  1128.