home *** CD-ROM | disk | FTP | other *** search
/ Mac Mania 2 / MacMania 2.toast / Demo's / Tools&Utilities / System Utilities / ParamRAM guard / PRAM guard.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-02  |  12.9 KB  |  447 lines  |  [TEXT/KAHL]

  1. /*
  2.  ***********************************************************************
  3.  *
  4.  *                                PRAM guardian
  5.  *             Reading Parameter RAM (PRAM) and setting/resetting it
  6.  *
  7.  * The program is intended to display the contents of the parameter RAM,
  8.  * a non-volatile RAM that stores some system parameters like the system font
  9.  * number and the speaker volume. The program also has some "standard" PRAM 
  10.  * settings stored as a 'HEXA' resource named "Standard PRAM".
  11.  * The program displays both actual and standard PRAM settings side-by-side, 
  12.  * shows difference(s) in a noticeable form, and can copy one setting onto
  13.  * another and save it.
  14.  *
  15.  ***********************************************************************
  16.  */
  17.  
  18. /* MacHeaders Included */
  19.  
  20. #include <string.h>
  21. #include <stdarg.h>
  22. #include <stdio.h>
  23. #include "myenv.h"
  24.  
  25.  
  26. /*
  27.  *-----------------------------------------------------------------------------------
  28.  *                                 Handling the dialog
  29.  */
  30.  
  31. class ADialog                            // Handle A Mac modal dialog
  32. {
  33. protected:
  34.     DialogPtr the_dialog;
  35. public:
  36.     ADialog(const short dialog_id);
  37.     ~ADialog(void);
  38.     void printf(const int item_no, const char * fmt_str,...);    // Put a formatted text into a dialog item
  39.     void set_onoff(const int item_no,const Boolean val);        // Set an on/off item
  40.     void hilight(const int item_no, const Boolean onoff);        // Hilight an item
  41.     void enable_item(const int item_no, const Boolean onoff);        // Enable/Disable the control (button)
  42. };
  43.  
  44.  
  45.                                     // Creating a dialog with a given resource ID
  46. ADialog::ADialog(const short dialog_id)
  47. {
  48.     the_dialog = GetNewDialog(dialog_id,nil,(WindowPtr)(-1));
  49.     assert( the_dialog != 0 );
  50. }
  51.  
  52.  
  53.                                     // Dispose of the dialog
  54. ADialog::~ADialog(void)
  55. {
  56.     assert( the_dialog != 0 );
  57.     DisposDialog(the_dialog);
  58.     the_dialog = 0;
  59. }
  60.  
  61.                                         // Put a formatted text into a dialog item
  62.                                         // Note that the function is smart enough to
  63.                                         // tell a static text item from a button
  64.                                         // and set up the text or button title
  65.                                         // appropriately
  66. void ADialog::printf(const int item_no, const char * fmt_str,...)
  67. {
  68.     OSErr syserr;
  69.         
  70.     char buffer [400];
  71.     va_list args;
  72.     va_start(args,fmt_str);            // Init 'args' to the beginning of
  73.                                     // the variable length list of args
  74.       vsprintf(buffer,fmt_str,args);
  75.     CtoPstr(buffer);
  76.  
  77.       short  item_type;
  78.       Handle item;
  79.       Rect   boundary_box;
  80.       
  81.       GetDItem(the_dialog,item_no,&item_type,&item,&boundary_box);
  82.     assert( item != nil );
  83.     if( (item_type & (~itemDisable)) == statText )
  84.       SetIText(item,(unsigned char const *)buffer);
  85.     else if( (item_type & ctrlItem) == ctrlItem )    // If an item is a button, set its title
  86.       SetCTitle((ControlHandle)item,(unsigned char const *)buffer);
  87.     else
  88.         _error("Can't handle an item of type %d",item_type);
  89. }
  90.  
  91.                                         // Set an on/off item (it has to be a button)
  92. void ADialog::set_onoff(const int item_no,const Boolean val)
  93. {
  94.       short  item_type;
  95.       Handle item;
  96.       Rect   boundary_box;
  97.       
  98.       GetDItem(the_dialog,item_no,&item_type,&item,&boundary_box);
  99.     assert( item != nil );
  100.     assert( (item_type & ctrlItem) == ctrlItem );
  101.     SetCtlValue((ControlHandle)item, val ? 1 : 0 );
  102. }
  103.  
  104.                                 // Hilight a dialog item
  105.                                 // Again, if the item turns out to be a text item,
  106.                                 // the entire text is highlighted.
  107.                                 // If the item is a button, it's highlighted
  108. void ADialog::hilight(const int item_no, const Boolean onoff)
  109. {
  110.       short  item_type;
  111.       Handle item;
  112.       Rect   boundary_box;
  113.       
  114.       GetDItem(the_dialog,item_no,&item_type,&item,&boundary_box);
  115.     assert( item != nil );
  116.     if( (item_type & (~itemDisable)) == statText )
  117.     {
  118.       if( (**(TEHandle)item).selEnd > 0 )        // The text has been selected
  119.         if( onoff )
  120.           ;                                        // Item is already selected
  121.         else
  122.           SelIText(the_dialog,item_no,0,0);        // Unselect the text
  123.       else if ( onoff )
  124.           SelIText(the_dialog,item_no,0,32767);    // Select the text
  125.     } 
  126.     else if( (item_type & ctrlItem) == ctrlItem )    // If an item is a button, set its title
  127.       HiliteControl((ControlHandle)item, onoff ? inButton : 0 );
  128.     else
  129.         _error("Can't handle an item of type %d",item_type);
  130. }
  131.  
  132.  
  133.                                 // Enable/Disable the control (button)
  134. void ADialog::enable_item(const int item_no, const Boolean onoff)
  135. {
  136.       short  item_type;
  137.       Handle item;
  138.       Rect   boundary_box;
  139.       
  140.       GetDItem(the_dialog,item_no,&item_type,&item,&boundary_box);
  141.     assert( item != nil );
  142.     assert( (item_type & ctrlItem) == ctrlItem );
  143.     HiliteControl((ControlHandle)item, onoff ? 0 : 255 );
  144. }
  145.  
  146.  
  147. class MyDialog : ADialog            // Handle THE dialog of the present program
  148. {
  149.     Boolean this_machine_selected;        // Item "this computer's PRAM" is selected
  150. public:
  151.  
  152.     enum Items { item_quit = 2, item_copy=3, 
  153.                  item_this_computer=19, item_standard=35 };        // Selectable items
  154.     enum { pi_atalkA=1, pi_atalkB, pi_eligible_dev, pi_modem_port_conf,
  155.            pi_printer_port_conf, pi_alarm, pi_font, pi_auto_key,
  156.            pi_printer_port, pi_speaker_vol, pi_click_times, pi_mouse_scaling,
  157.            pi_external_startup_disk, pi_menu_blink_rate, pi_save };
  158.            
  159.     MyDialog(void);
  160.     ~MyDialog(void) {}
  161.     Items handle(void);            // Handle the dialog, return the clicked item that can't handle
  162.     Boolean is_this_machine_selected(void) const    { return this_machine_selected; }
  163. };
  164.  
  165. MyDialog::MyDialog(void)
  166.     : ADialog(128)
  167. {
  168.     this_machine_selected = TRUE;
  169.     hilight(item_this_computer,TRUE);
  170.     printf(item_copy,">>> copy >>>");
  171. }
  172.  
  173. MyDialog::Items MyDialog::handle(void)
  174. {
  175.     short item_hit;
  176.     while(1)
  177.     {
  178.         ModalDialog(nil,&item_hit);
  179.         switch(item_hit)
  180.         {
  181.             case item_this_computer:
  182.                  this_machine_selected = TRUE;
  183.                  hilight(item_this_computer,TRUE);
  184.                   hilight(item_standard,FALSE);
  185.                  printf(item_copy,">>> copy >>>");
  186.                   continue;
  187.              
  188.             case item_standard:
  189.                  this_machine_selected = FALSE;
  190.                  hilight(item_this_computer,FALSE);
  191.                   hilight(item_standard,TRUE);
  192.                  printf(item_copy,"<<< copy <<<");
  193.                   continue;
  194.         }
  195.         break;
  196.     }
  197.     return (Items)item_hit;
  198. }
  199.  
  200. /*
  201.  *-----------------------------------------------------------------------------------
  202.  *                                 PRAM classes
  203.  */
  204.     
  205.  
  206. class PRAM
  207. {
  208. typedef unsigned short ushort;
  209. typedef unsigned char byte;
  210.  
  211. protected:                    // This is a layout of the Parameter RAM.
  212.     byte valid;                // Check agains struct SysParmType in <OsUtils.h>
  213.     byte aTalkA;
  214.     byte aTalkB;
  215.     byte config;
  216.     ushort portA;
  217.     ushort portB;
  218.     unsigned long alarm;                    // Alarm clock setting
  219.     short font;                                // System font number minus 1
  220.     struct {
  221.         ushort    auto_key_threshold     : 4;    // in 4-tick units
  222.         ushort    auto_key_rate        : 4;    // in two-tick units
  223.         ushort    reserved            : 7;
  224.         ushort    printer_connection    : 1;    // 1 - the printer is connected to the modem port
  225.         } kbdPrint;
  226.     struct {
  227.         ushort    reserved            : 5;
  228.         ushort    speaker_volume        : 3;    // 0 (silent) through 7 (loud)
  229.         ushort    double_click_time    : 4;    // in 4-tick units
  230.            ushort    caret_blink_time    : 4;    // in 4-tick units
  231.         } volClik;
  232.     struct {
  233.         ushort    reserved            : 9;
  234.         ushort    mouse_scaling        : 1;
  235.         ushort     reserved2            : 1;
  236.         ushort    startup_disk_ext    : 1;    // 1 means use an external disk to boot up
  237.         ushort    menu_blink_times    : 2;
  238.         ushort    reserved3             : 2;
  239.         } misc;
  240.  
  241.     Boolean modified;                    // Modification flag
  242.     void save(const SysPPtr pram_ptr);    // Saved the modified PRAM back to where it
  243.                                         // was found in the first place
  244.     
  245. public:
  246.  
  247.     PRAM (const SysPPtr pram_ptr);        // Load up the data to the structure
  248.     ~PRAM(void) {}
  249. };
  250.  
  251.                                     // Load up (i.e., copy) the data to this class
  252.                                     // using the supplied ptr
  253. PRAM::PRAM(const SysPPtr pram_ptr)
  254. {
  255.     assert( pram_ptr != 0 );
  256.     memcpy(&valid,pram_ptr,sizeof(SysParmType));
  257.     assert( valid == 0xA8 );
  258.     modified = FALSE;
  259. }
  260.  
  261.                                     // Save (i.e., copy) the data from this class
  262.                                     // to the supplied ptr
  263.                                     // Clear the modification bit after the operation
  264. void PRAM::save(const SysPPtr pram_ptr)
  265. {
  266.     assert( pram_ptr != 0 );
  267.     assert( valid == 0xA8 );
  268.     assert( modified );
  269.     memcpy(pram_ptr,&valid,sizeof(SysParmType));
  270.     modified = FALSE;
  271. }
  272.  
  273.                                     // A class to display the PRAM
  274. class PRAM_Display : protected PRAM
  275. {
  276.     ADialog& dialog;                    // A dialog to display the PRAM
  277.     const short starting_item_no;        // where the contents of PRAM is to be displayed
  278.  
  279. public:
  280.     PRAM_Display(const SysPPtr pram_ptr, ADialog& _dialog, const int _starting_item_no);
  281.     ~PRAM_Display(void) {}
  282.     void display(void);
  283. };
  284.  
  285. PRAM_Display::PRAM_Display(const SysPPtr pram_ptr, ADialog& _dialog, const int _starting_item_no)
  286.     : PRAM(pram_ptr), starting_item_no(_starting_item_no), dialog(_dialog)
  287. {
  288.     assert( starting_item_no > 0 );
  289. }
  290.  
  291.                                     // Display the PRAM settings in the consecutive
  292.                                     // dialog boxes starting with starting_item_no+1
  293. void PRAM_Display::display(void)
  294. {
  295.     //message("kbdPrint %04x",*(ushort *)&kbdPrint);
  296.     //message("volClick %04x",*(ushort *)&volClik);
  297.     //message("misc %04x",*(ushort *)&misc);
  298.     dialog.printf(starting_item_no+MyDialog::pi_atalkA,"%X",aTalkA);
  299.     dialog.printf(starting_item_no+MyDialog::pi_atalkB,"%X",aTalkB);
  300.     
  301.     dialog.printf(starting_item_no+MyDialog::pi_eligible_dev,"%X",config);
  302.     dialog.printf(starting_item_no+MyDialog::pi_modem_port_conf,"%04X",portA);
  303.     dialog.printf(starting_item_no+MyDialog::pi_printer_port_conf,"%04X",portB);
  304.     dialog.printf(starting_item_no+MyDialog::pi_alarm,"%6u",alarm);
  305.     dialog.printf(starting_item_no+MyDialog::pi_font,"%2d",font+1);
  306.     
  307.     dialog.printf(starting_item_no+MyDialog::pi_auto_key,"%d/%d",4*kbdPrint.auto_key_threshold,
  308.                                                                  4*kbdPrint.auto_key_rate);
  309.     dialog.printf(starting_item_no+MyDialog::pi_printer_port,"%s",kbdPrint.printer_connection ?
  310.                                     "Printer" : "Modem");
  311.     dialog.printf(starting_item_no+MyDialog::pi_speaker_vol,"%1u",volClik.speaker_volume);
  312.     dialog.printf(starting_item_no+MyDialog::pi_click_times,"%d/%d",4*volClik.double_click_time,
  313.                                                                     4*volClik.caret_blink_time);
  314.     dialog.set_onoff(starting_item_no+MyDialog::pi_mouse_scaling,misc.mouse_scaling);
  315.     dialog.set_onoff(starting_item_no+MyDialog::pi_external_startup_disk,misc.startup_disk_ext);
  316.     dialog.printf(starting_item_no+MyDialog::pi_menu_blink_rate,"%1u",misc.menu_blink_times);
  317.  
  318.     dialog.enable_item(starting_item_no+MyDialog::pi_save,modified);
  319. }
  320.  
  321.                                     // PRAM that is gotten from the system
  322. class ActualPRAM : public PRAM_Display
  323. {
  324. public:
  325.     ActualPRAM(ADialog& dialog, const int starting_item_no);
  326.     ~ActualPRAM(void) {}
  327.     void save(void);                // Save changes made within the structure to PRAM
  328.     void operator = (const PRAM& pram) { *(PRAM *)this = pram; modified = TRUE; }
  329. };
  330.  
  331.  
  332. ActualPRAM::ActualPRAM(ADialog& dialog, const int starting_item_no)
  333.     : PRAM_Display(GetSysPPtr(),dialog,starting_item_no)
  334. {
  335. }
  336.  
  337.                                 // Save changes made within the structure to PRAM
  338. void ActualPRAM::save(void)
  339. {
  340.     PRAM::save(GetSysPPtr());
  341.     do_well( WriteParam() );
  342. }
  343.  
  344.  
  345.                                     // PRAM that is gotten from the "Standard PRAM"
  346.                                     // resource
  347. class StandardPRAM : public PRAM_Display
  348. {
  349.     Handle handle;
  350. public:
  351.     StandardPRAM(ADialog& dialog, const int starting_item_no);
  352.     ~StandardPRAM(void) {}
  353.     void save(void);                // Save changes made within the structure to PRAM
  354.     void operator = (const PRAM& pram) { *(PRAM *)this = pram; modified = TRUE; }
  355. };
  356.  
  357.  
  358. StandardPRAM::StandardPRAM(ADialog& dialog, const int starting_item_no)
  359.     : PRAM_Display((SysPPtr)*(handle=Get1NamedResource('HEXA',"\pStandard PRAM")),
  360.                    dialog,starting_item_no)
  361. {
  362.     assert( SizeResource(handle) == sizeof(SysParmType) );
  363. }
  364.  
  365.                                 // Save changes made within the structure to PRAM
  366. void StandardPRAM::save(void)
  367. {
  368.     PRAM::save((SysPPtr)*handle);
  369.     ChangedResource(handle);
  370.     do_well( ResError() );
  371.     WriteResource(handle);
  372.     do_well( ResError() );
  373. }
  374.  
  375.  
  376. /*
  377.  *-----------------------------------------------------------------------------------
  378.  *                                 Handling the dialog
  379.  */
  380.  
  381. /*
  382.  *-----------------------------------------------------------------------------------
  383.  *                                 Routing module
  384.  */
  385.  
  386. extern "C" char * ExtPRAM(void);
  387.  
  388. void main(void)
  389. {
  390.     Initialize_MAC();
  391.     
  392.     MyDialog dialog;
  393.     ActualPRAM this_computer_pram(dialog,MyDialog::item_this_computer);
  394.     StandardPRAM standard_PRAM(dialog,MyDialog::item_standard);
  395.     
  396.     this_computer_pram.display();
  397.     standard_PRAM.display();
  398.     
  399. #if 1
  400.     {
  401.         char * buf = ExtPRAM();
  402.         message("Another extparm %0x %0x %0x",*((unsigned long *)buf),
  403.                                               *((unsigned long *)buf+1),
  404.                                               *((unsigned long *)buf+2));
  405.         //message("Another extparm %0x",*((unsigned long *)buf));
  406.         message("Another volclick %0x",*((unsigned short *)buf+16));
  407.         message("Another beep %0x",*(unsigned short *)(buf+0x7c));
  408.     }
  409. #endif
  410.     for(;;)
  411.     {
  412.         switch(dialog.handle())
  413.         {
  414.             case MyDialog::item_copy:
  415.                 if( dialog.is_this_machine_selected() )     // Copy to standard
  416.                 {
  417.                   standard_PRAM = this_computer_pram;
  418.                   standard_PRAM.display();
  419.                 }
  420.                 else
  421.                 {
  422.                   this_computer_pram = standard_PRAM;
  423.                   this_computer_pram.display();
  424.                 }
  425.                 continue;
  426.                 
  427.             case MyDialog::item_this_computer+MyDialog::pi_save:
  428.                  this_computer_pram.save();
  429.                  this_computer_pram.display();
  430.                  continue;
  431.                  
  432.             case MyDialog::item_standard+MyDialog::pi_save:
  433.                  standard_PRAM.save();
  434.                  standard_PRAM.display();
  435.                  continue;
  436.  
  437.             case MyDialog::item_quit:
  438.                  break;
  439.                  
  440.             default:
  441.                 continue;
  442.         }
  443.         break;
  444.     }
  445.     
  446. }
  447.