From: pottier@clipper.ens.fr (Francois Pottier)
Subject: csmp-digest-v3-051
Date: Fri, 12 Aug 1994 16:04:14 +0200 (MET DST)

C.S.M.P. Digest             Fri, 12 Aug 94       Volume 3 : Issue 51
 
Today's Topics:
 
        Controls, Fonts, Dialogs & ResEdit (long)
        Deleting ptr to base not calling dtors of derived
        Icon positions on desktop
        Looking for source code
        Need C source code for recording sound
        OpenPicture with temporary memory?
        QuickTime 2.0 and MIDI
        Tab Patch for TextEdit
        [Q] Increasing stack size?



The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
(pottier@clipper.ens.fr).
 
The digest is a collection of article threads from the internet newsgroup
comp.sys.mac.programmer.  It is designed for people who read c.s.m.p. semi-
regularly and want an archive of the discussions.  If you don't know what a
newsgroup is, you probably don't have access to it.  Ask your systems
administrator(s) for details.  If you don't have access to news, you may
still be able to post messages to the group by using a mail server like
anon.penet.fi (mail help@anon.penet.fi for more information).
 
Each issue of the digest contains one or more sets of articles (called
threads), with each set corresponding to a 'discussion' of a particular
subject.  The articles are not edited; all articles included in this digest
are in their original posted form (as received by our news server at
nef.ens.fr).  Article threads are not added to the digest until the last
article added to the thread is at least two weeks old (this is to ensure that
the thread is dead before adding it to the digest).  Article threads that
consist of only one message are generally not included in the digest.

The digest is officially distributed by two means, by email and ftp.

If you want to receive the digest by mail, send email to listserv@ens.fr
with no subject and one of the following commands as body:
    help		                Sends you a summary of commands
    subscribe csmp-digest Your Name	Adds you to the mailing list
    signoff csmp-digest			Removes you from the list
Once you have subscribed, you will automatically receive each new
issue as it is created.

The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
Questions related to the ftp site should be directed to
scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP
digest are available there.

Also, the digests are available to WAIS users.  To search back issues
with WAIS, use comp.sys.mac.programmer.src. With Mosaic, use
http://www.wais.com/wais-dbs/comp.sys.mac.programmer.html.


-------------------------------------------------------

>From jcr@mbunix.mitre.org (Rogers)
Subject: Controls, Fonts, Dialogs & ResEdit (long)
Date: 28 Jul 1994 19:31:23 GMT
Organization: The MITRE Corporation, Bedford, MA

There's been a bit of traffic lately all having to do with fonts
of dialog items, and I just happen to have been concerned with that
myself lately, and also with controls, so I decided to try to put
together a concise guide to these overlapping topics. It follows.
Everyone feel free to add to it. Or send comments to me and I'll
incorporate.

=====================================================================
Creating Controls with ResEdit 2.1.1                     28 July 1994
=====================================================================

Here is a guide to creating controls using ResEdit 2.1.1.

Please distribute freely, and add to any appropriate FAQs.

Please send any comments regarding errors, omissions, etc., to:

     Jeff Rogers
     jrogers@mitre.org
_____________________________________________________________________

When editing a control in ResEdit, you see a template much like
the ASCII depiction below.


+-------------------------------------------------------------------+
|=|_|============== CNTL ID = 128 from App_pi.rsrc =================|
|-----------------------------------------------------------------+-|
|                                                                 |^|
|               +-----+ +-----+ +-----+ +-----+    ,-----.        | |
|  BoundsRect   | 391 | | 502 | | 411 | | 652 |   (  Set  )       | |
|               +-----+ +-----+ +-----+ +-----+    '-----'        | |
|               +-----------+                                     | |
|  Value        | 0         |                                     | |
|               +-----------+                                     | |
|                ,-.            ,-.                               | |
|  Visible      ( 0 ) True     (   ) False                        | |
|                '-'            '-'                               | |
|               +-----------+                                     | |
|  Max          | 1         |                                     | |
|               +-----------+                                     | |
|               +-----------+                                     | |
|  Min          | 0         |                                     | |
|               +-----------+                                     | |
|               +-----------+                                     | |
|  ProcID       | 8         |                                     | |
|               +-----------+                                     | |
|               +----------------+                                | |
|  RefCon       | 0              |                                | |
|               +----------------+                                | |
|               +------------------------------------+            | |
|  Title        | Generate Schedule...               |            | |
|               +------------------------------------+            | |
|                                                                 |v|
|_________________________________________________________________|_|


The proper values for the various fields are not always obvious.
Below is a guide to assigning the correct values.

BoundsRect
- --------
This is the control's rectangle in local coordinates. The bounds
are shown in the following order: top, left, bottom, right.

Value
- ---
This is the initial value of the control. It should be given one of
the following values, based on the type of control you wish to create:

   PushButton  : 0

   CheckBox    : 0 = not checked
                 1 = checked

   RadioButton : 0 = not selected
                 1 = selected

   ScrollBar   : anything between Max and Min, inclusive

   PopUpMenu   : The Value parameter of a pop-up menu is used when
                 creating the menu to indicate how the pop-up's
                 title is to be drawn. It should be any ORed
                 combination (sum) of the following:

                      0 - left-justified
                      1 - center-justified
                    255 - right-justified
                    256 - bold             4096 - shadow
                    512 - italic           8192 - condensed
                   1024 - underlined      16384 - extended
                   2048 - outlined        32768 - plain

                 After the pop-up menu is created, this field
                 will contain the value 1.

Visible
- -----
This indicates whether the control is initially visible.

Max
- -
This is the maximum value the control may assume. It should
be given one of the following values:

   PushButton  : 1
   CheckButton : 1
   RadioButton : 1
   ScrollBar   : any value appropriate to the application
   PopUpMenu   : width in pixels of pop-up menu's title
                 (After the pop-up menu is created, this field
                  will contain the # of items in the pop-up menu.)

Min
- -
This is the minimum value the control may assume. It should
be given one of the following values:

   PushButton  : 0
   CheckButton : 0
   RadioButton : 0
   ScrollBar   : any value appropriate to the application
   PopUpMenu   : resource ID of menu to pop up
                 (After the pop-up menu is created,
                  this field will contain the value 1.)

ProcID
- ----
This indicates which type of control to create, and also which
font to use when drawing the control's title and other text. It
should be given one of the following values:

   PushButton,  in system font :    0
                in window font :    8

   CheckButton, in system font :    1
                in window font :    9

   RadioButton, in system font :    2
                in window font :   10

   PopUpMenu ................. : 1008 *

   * PopUpMenu behavior can be affected by ORing (summing) the
     ProcID with any of the following:
        1 - don't dynamically adjust pop-up's width to accommodate
            long menu items
        8 - use the grafPort's font to draw the control's text
        4 - ignore "min" field; instead, build a menu listing all
            available resources of the type contained in "refCon"
            field
     Thus the following are valid ProcID values for a popUpMenu:
        1008 - dynamic menu width - system font - menu from "Min"
        1009 - fixed menu width   - system font - menu from "Min"
        1012 - dynamic menu width - system font - list a resType
        1013 - fixed menu width   - system font - list a resType
        1016 - dynamic menu width - window font - menu from "Min"
        1017 - fixed menu width   - window font - menu from "Min"
        1020 - dynamic menu width - window font - list a resType
        1021 - fixed menu width   - window font - list a resType

RefCon
- ----
This 32-bit value can be used by your app in any way you wish.

For popUpMenus, this field may (depending on the value of "ProcID"
above) be used during creation of the popUpMenu and contain a
4-character resource type.

Title
- ---
This is the control's title. This text shows up inside a pushButton,
or beside a checkBox, radioButton or popUpMenu. For scrollBars it
remains invisible, but still can be used, e.g., to search a window's
controls by title.


============================
Dialogs, Controls, and Fonts
============================

A question that often arises is how to get pushButtons, checkBoxes,
radioButtons, and/or popUpMenus in a dialog to be drawn with a font
other than the system font. There are several ways to do this, one
of which is the following:

In the DITL editor, rather than creating each control as the type of
control you ultimately want it to be, instead create it as a generic
control. Then, in the CNTL editor, you can specify the ProcID that
will cause the control to be drawn in the dialog's font instead of
the system font. (Thanks to Jens Alfke [jens_alfke@powertalk.apple.com]
for this one.) Otherwise, the dialog manager creates the controls
for you, and it will use ProcID values specifying use of the system
font when drawing the controls. Once these controls are created, there
seems to be no way to change this aspect of them; Apple has provided
a "GetCVariant" call but no "SetCVariant" call.

To change the font of statText and editText items, you must take
a different approach. Once the dialog has been created, call a
routine like the following:

/**********************************************************************
*
*  FUNCTION:    SetDialogFontAndSize( DialogPtr theDialog,
*                                     short     fontNum,
*                                     short     fontSize    )
*
*  DESCRIPTION: This function sets the font and size to be used
*               subsequently by static-text and edit-text items
*               of a dialog.
*
*  WRITTEN BY:  jarezina@magnus.acs.ohio-state.edu
*               (Jasna M. Arezina-Wilson)
*
*  MODIFIED BY: Jeffrey C. Rogers
*               (jrogers@mitre.org)
*
****************/

void SetDialogFontAndSize( DialogPtr theDialog,
                           short     fontNum,
                           short     fontSize   )
{
  FontInfo   f ;
  GrafPtr    savedPort ;
  
  // Store the current grafPort, then change to the dialog.
  
  GetPort( &savedPort );
  SetPort( theDialog );
  
  // Set up the dialog's grafPort font info.
  
  TextFont( fontNum );
  TextSize( fontSize );
  
  // Deal with the static & edit text items.
  
  GetFontInfo( &f );
  (*((DialogPeek)theDialog)->textH)->txFont = fontNum ;
  (*((DialogPeek)theDialog)->textH)->txSize = fontSize ;
  (*((DialogPeek)theDialog)->textH)->lineHeight = f.ascent + f.descent +
                                                             f.leading ;
  (*((DialogPeek)theDialog)->textH)->fontAscent = f.ascent ;
  
  // Restore previous grafPort.
  
  SetPort( savedPort );
}
/*********************************************************************/


---------------------------

>From ant@kunikpok.icus.com (handle)
Subject: Deleting ptr to base not calling dtors of derived
Date: Wed, 27 Jul 94 04:41:07 CDT
Organization: Kunikpok Kennels and Komputers (Pet Project)

I'm having a problem with destructors. It popped up in a fairly large
hierarchy, and I've boiled it down to the simplest possible below. If
I call a function which accepts a pointer to Base, but the pointer is
of class Derived, when the function deletes the object, it doesn't
call Derived's destructor. If I add a destructor to Base, then it
calls Derived's destructor, then Base's destructor (as I would expect).
This seems like inconsistent behaviour. Is this correct C++? I need to
get it to correctly call Derived's destructor. I don't want to have to
add a destructor to Base (it doesnt need one). If your response is
"just add one anyway", I must point this out: If this is a bug, then
let's find out all the ramifications, instead of just ignoring it.
 
I am using (how on earth did you guess??) Symantec C++ 7.0.3  :)
 
Thanx!
 
- --- test.cp -----
 
class Base { };                 // Empty base class
 
class Derived : public Base     // Derived class, has a constructor
{                               // and destructor
public:
    Derived( void );
    virtual ~Derived( void );
    char* theP;
};
 
Derived::Derived( void )
{
    theP = new char [20000];    // Allocate some space
}
 
Derived::~Derived( void )
{
    if ( theP != 0 )
        delete[] theP;          // Free if allocated
}
 
void    DeleteDerived( Derived* obj )
{
    delete obj;                 // Delete obj
}
 
void    DeleteBase( Base* obj )
{
    delete obj;                 // Delete obj
}
 
main()
{
    Derived*    b1 = new Derived;
    Derived*    b2 = new Derived;
    
    DeleteDerived( b1 );        // Correctly calls ~Derived().
    DeleteBase( b2 );           // Calls *no* destructors
    
    return 0;
}
 
- --- end of test.cp -----
 
- ------------------------------------------------------------------
Chelly Green 'Ant'          <cgreen%podbox.uucp@cs.utexas.edu>

+++++++++++++++++++++++++++

>From neeri@iis.ee.ethz.ch (Matthias Neeracher)
Date: 28 Jul 1994 15:53:09 GMT
Organization: Integrated Systems Laboratory, ETH, Zurich

In article <9q94Pc2w165w@kunikpok.icus.com> ant@kunikpok.icus.com (handle) writes:
> I'm having a problem with destructors. It popped up in a fairly large
> hierarchy, and I've boiled it down to the simplest possible below. If
> I call a function which accepts a pointer to Base, but the pointer is
> of class Derived, when the function deletes the object, it doesn't
> call Derived's destructor. If I add a destructor to Base, then it
> calls Derived's destructor, then Base's destructor (as I would expect).
> This seems like inconsistent behaviour. Is this correct C++?

Yes.

> I need to get it to correctly call Derived's destructor. I don't want to have
> to add a destructor to Base (it doesnt need one).

Well, I'll start with the argument by authority:

To quote Bjarne Stroustrup, _The C++ Programming Language_, 2nd edition:
# In general, it is wise to supply a virtual destructor in all classes that
# act as a base class in the sense that objects of derived classes are
# manipulated (and possibly deleted) through a pointer to the base. This is
# almost always the case for classes with even a single virtual function.

If that doesn't convince you, think about it in technical terms: How is
the compiler to know to call a destructor of the derived class on a

delete base;

statement, unless the base class provides a hint in the form of a virtual
destructor.

>If your response is "just
> add one anyway", I must point this out: If this is a bug, then let's find out
> all the ramifications, instead of just ignoring it.

Your attitude is correct, but it's not a bug.

> I am using (how on earth did you guess??) Symantec C++ 7.0.3  :)
 
Awww, leave those poor Symantec compiler guys alone for a change and let them
fix the bugs that *are* there (As the "*=" thread has shown, it is hard enough
to convince them of those already. The Metrowerks guys, on the other hand,
didn't explicitely admit that it was a bug, but promised to fix it :-).

Matthias

- ---
Matthias Neeracher <neeri@iis.ee.ethz.ch> http://err.ethz.ch/members/neeri.html
  "Paranotions, which designate constructs, may now contain metanotions and
   ``hypernotions'' have been introduced in order to designate protonotions"
                -- A. van Wijngaarden et al., _ALGOL 68 Revised Report_

+++++++++++++++++++++++++++

>From nagle@netcom.com (John Nagle)
Date: Fri, 29 Jul 1994 04:08:28 GMT
Organization: NETCOM On-line Communication Services (408 261-4700 guest)

neeri@iis.ee.ethz.ch (Matthias Neeracher) writes:
>In article <9q94Pc2w165w@kunikpok.icus.com> ant@kunikpok.icus.com (handle) writes:
>> I'm having a problem with destructors. It popped up in a fairly large
>> hierarchy, and I've boiled it down to the simplest possible below. If
>> I call a function which accepts a pointer to Base, but the pointer is
>> of class Derived, when the function deletes the object, it doesn't
>> call Derived's destructor. If I add a destructor to Base, then it
>> calls Derived's destructor, then Base's destructor (as I would expect).
>> This seems like inconsistent behaviour. Is this correct C++?

>Yes.

     That's right, but the rationale for it working this way is wierd.

     The trouble comes from the C++ design decision that classes and
structs are the same, plus the design decision that classes that don't
use "C++ features" have compatible storage layout with C structs.
 Logically, all destructors should be virtual, but that would force
all classes to have the machinery for virtual functions, in case somebody
later derived a class from that class.  This would break C data structure
compatibility.

     It really should be an error to derive a class with a destructor
from a class which does not have a virtual destructor.  If you want
normal destructor semantics, you have to have virtual destructors all the way
down to the base class.  This is easily checkable and should be
checked, rather than being viewed as a rite of passage for C++ programmers.

					John Nagle

+++++++++++++++++++++++++++

>From sokoloff@mv.mv.com (Jim Sokoloff)
Date: Thu, 28 Jul 1994 20:04:24 GMT
Organization: MV Communications, Inc.

In article <9q94Pc2w165w@kunikpok.icus.com>,
handle <ant@kunikpok.icus.com> wrote:
>I'm having a problem with destructors. It popped up in a fairly large
>hierarchy, and I've boiled it down to the simplest possible below. If
>I call a function which accepts a pointer to Base, but the pointer is
>of class Derived, when the function deletes the object, it doesn't
>call Derived's destructor. If I add a destructor to Base, then it
>calls Derived's destructor, then Base's destructor (as I would expect).
>This seems like inconsistent behaviour. Is this correct C++? I need to
>get it to correctly call Derived's destructor. I don't want to have to
>add a destructor to Base (it doesnt need one). If your response is
>"just add one anyway", I must point this out: If this is a bug, then
>let's find out all the ramifications, instead of just ignoring it.
> 
[Sample deleted]
AS far as I know, this is correct C++. Base has no dtor, therefore, when 
you delete a Base *, there is no dtor to call. Therefore, your compiler is
doing the right thing. Add a virtual dtor to Base anyway. This will cause the
correct thing to happen. (From your perspective, meaning Derived dtor is 
called. From the C++ perspective, the correct thing is already happening, and
you have a bug in your code...)
 
- -Jim



+++++++++++++++++++++++++++

>From s2361905@techst02.technion.ac.il (Ben Hekster)
Date: Thu, 28 Jul 1994 19:37:44 GMT
Organization: Technion, Israel Institute of Technology

Hi--

>If
>I call a function which accepts a pointer to Base, but the pointer is
>of class Derived, when the function deletes the object, it doesn't
>call Derived's destructor. If I add a destructor to Base, then it
>calls Derived's destructor, then Base's destructor (as I would expect).
>[...] Is this correct C++?

Yes, this is correct C++.  If you expect to be able to call member
functions that you override in derived classes, you must declare
the member function `virtual' in the base type.  Note that this
is true for any member function, not just destructors.  I.e., if you
have

	class Base { void f(); };

	class Derived : public Base { virtual void f(); };

then any application of f() to a Base binds to Base::f().  If you
want the binding to be dynamic, you must supply the `virtual'.
By omitting it you are implying that either you do not expect this
function to be overridden, or that you don't want/need overridden
versions to be called.

	The questionable thing here is why the compiler doesn't
warn about the redeclaration of f().  Possibly because of C
compatibility reasons.  MPW cfront doesn't either, even with maximum
warnings.

	In general, if your class has virtual members, it should
have a virtual destructor, even if the destructor action itself is
trivial.  The ARM warns about this, to avoid exactly the problem
you are having now.

Ben


+++++++++++++++++++++++++++

>From afcjlloyd@aol.com (AFC JLloyd)
Date: 29 Jul 1994 02:11:07 -0400
Organization: America Online, Inc. (1-800-827-6364)

In article <nagleCtoou4.Bxw@netcom.com>, nagle@netcom.com (John Nagle)
writes:

>neeri@iis.ee.ethz.ch (Matthias Neeracher) writes:
>>In article <9q94Pc2w165w@kunikpok.icus.com> ant@kunikpok.icus.com
(handle) writes:
>>> I'm having a problem with destructors. It popped up in a fairly large
>>> hierarchy, and I've boiled it down to the simplest possible below. If
>>> I call a function which accepts a pointer to Base, but the pointer is
>>> of class Derived, when the function deletes the object, it doesn't
>>> call Derived's destructor. If I add a destructor to Base, then it
>>> calls Derived's destructor, then Base's destructor (as I would
expect).
>>> This seems like inconsistent behaviour. Is this correct C++?
>
>>Yes.
>
>     That's right, but the rationale for it working this way is wierd.
>
>     The trouble comes from the C++ design decision that classes and
>structs are the same, plus the design decision that classes that don't
>use "C++ features" have compatible storage layout with C structs.
> Logically, all destructors should be virtual, but that would force
>all classes to have the machinery for virtual functions, in case somebody
>later derived a class from that class.  This would break C data structure
>compatibility.
>
>     It really should be an error to derive a class with a destructor
>from a class which does not have a virtual destructor.  If you want
>normal destructor semantics, you have to have virtual destructors all the
way
>down to the base class.  This is easily checkable and should be
>checked, rather than being viewed as a rite of passage for C++
programmers.

I think it's a little more complicated than this.  I can think of lots of
uses for classes that don't need any virtual functions, but need
destructors (e.g. resource acquisition classes).  There is no point in
making the destructor be virtual in such a case, and doing so generates a
whole vtbl when none is needed, so the overhead cost is actually quite
high (much more so than adding one entry to an already existing vtbl).

However, I agree with the idea that it should be an error to derive from
classes that don't have virtual destructors.  Since the compiler doesn't
enforce it (what a great optional warning!), the only thing you can do is
add it to your list of coding guidelines.  Scott Meyer's is now writing a
column for the C++ Report which continues the set of guidelines he
established in his (truly excellent) book "Effective C++: 50 Specific Ways
to Improve Your Programs and Designs".  His most recent column presents
the guideline: "Avoid having concrete classes inherit from concrete
classes".  Couple this with the guideline "Make destructors virtual in
abstract base classes", and you're well covered.

By the way, if the guideline against deriving from concrete classes seems
wrong to you, I highly recommend you read the article (July-August 94
issue of C++ Report, should still be on the newstands).

Jim Lloyd
afcjlloyd@aol.com
 

---------------------------

>From eajohnsn@blue.weeg.uiowa.edu (Eric Johnson)
Subject: Icon positions on desktop
Date: 25 Jul 1994 18:12:33 -0500
Organization: University of Iowa, Iowa City, IA, USA

Hope this isn't too obvious, but I lack most reference sources.  I am 
curious how programs like UnderWare know where on the screen the 
different icons and folders are kept.  If I wanted to write a program 
that would move the desktop icons around (or copy the screen and pretend 
to move them), where do I find their positions?  Any tips or pointers to 
the correct IM volume would be great.

Eric Johnson				eajohnsn@blue.weeg.uiowa.edu
Program in Genetics
University of Iowa



+++++++++++++++++++++++++++

>From zobkiw@datawatch.com (joe zobkiw)
Date: Tue, 26 Jul 1994 15:19:14 GMT
Organization: Datawatch Corporation

In article <311gt1$2g57@blue.weeg.uiowa.edu>, eajohnsn@blue.weeg.uiowa.edu
(Eric Johnson) wrote:

> Hope this isn't too obvious, but I lack most reference sources.  I am 
> curious how programs like UnderWare know where on the screen the 
> different icons and folders are kept.  If I wanted to write a program 
> that would move the desktop icons around (or copy the screen and pretend 
> to move them), where do I find their positions?  Any tips or pointers to 
> the correct IM volume would be great.
> 

For each volume, recurse through the "Desktop folder" and perform an
FSpGetFInfo on each file. The fdLocation gives you the location of the
topLeft corner of the icon. For directories (if you use FSpGetDInfo) it is
the frLocation field.

___________________________________________________________
_/_/_/_/   Joe Zobkiw                                   ,,,
    _/     Senior Software Engineer                     - -
  _/       Datawatch Corporation                         L
_/_/_/_/   zobkiw@datawatch.com                          -

+++++++++++++++++++++++++++

>From dkj@apple.com (Dave Johnson)
Date: Tue, 26 Jul 1994 17:54:41 GMT
Organization: Apple Computer

In article <zobkiw-2607941019140001@zobkiw.datawatch.com>,
zobkiw@datawatch.com (joe zobkiw) wrote:

> For each volume, recurse through the "Desktop folder" and perform an
> FSpGetFInfo on each file. The fdLocation gives you the location of the
> topLeft corner of the icon. For directories (if you use FSpGetDInfo) it is
> the frLocation field.

Note also that with the scriptable Finder (7.5+, I think) you can get/set
the locations of items via AppleScript or Apple Events real easy . . .

+++++++++++++++++++++++++++

>From macneils@aol.com (MacneilS)
Date: 28 Jul 1994 20:44:03 -0400
Organization: America Online, Inc. (1-800-827-6364)

In article <mouse-280794174850@ppp-83-19.bu.edu>, mouse@bu.edu (Matt Mick)
writes:

>>>>>>
Look at the NIM:Files.  It tells you how to get the h and v pos of the
file.  I think, if I remember correctly, that is for the Icon!
<<<<<<

You want to use HGetFInfo(). This will give you all of the information
that the Finder itself uses for the posistion of icons.

Take Care,
MacneilS@aol.com

+++++++++++++++++++++++++++

>From grobbins@apple.com (Grobbins)
Date: 28 Jul 1994 21:06:31 -0700
Organization: Skunkworks

In article <mouse-280794174850@ppp-83-19.bu.edu>,
Matt Mick <mouse@bu.edu> wrote:
>In article <311gt1$2g57@blue.weeg.uiowa.edu>, eajohnsn@blue.weeg.uiowa.edu
>(Eric Johnson) wrote:
>> Hope this isn't too obvious, but I lack most reference sources.  I am 
>> curious how programs like UnderWare know where on the screen the 
>> different icons and folders are kept.
>
>Look at the NIM:Files.  It tells you how to get the h and v pos of the
>file.  I think, if I remember correctly, that is for the Icon!

The fdLocation field of a file's FInfo (returned by PBGetCatInfo and
FSpGetFInfo, among other calls) may have the icon location.  But because
the Finder ruthlessly caches its file information, the numbers on
disk may not be accurate and cannot reliably be used to determine or
set the icon position.

With the Scriptable Finder, you can use AppleScript to have the Finder
get and set the positions of icons.  But any commercial products now
that "know" where the icons reside are probably doing hacky skanky things
to get that information reliably, 'cause the non-scriptable versions of
the Finder are really unfriendly about sharing the knowledge.

Grobbins                grobbins@apple.com

Usual disclaimers apply.


+++++++++++++++++++++++++++

>From mouse@bu.edu (Matt Mick)
Date: Thu, 28 Jul 1994 17:48:49 -0500
Organization: Boston University

In article <311gt1$2g57@blue.weeg.uiowa.edu>, eajohnsn@blue.weeg.uiowa.edu
(Eric Johnson) wrote:

> Hope this isn't too obvious, but I lack most reference sources.  I am 
> curious how programs like UnderWare know where on the screen the 
> different icons and folders are kept.  If I wanted to write a program 
> that would move the desktop icons around (or copy the screen and pretend 
> to move them), where do I find their positions?  Any tips or pointers to 
> the correct IM volume would be great.
> 
> Eric Johnson				eajohnsn@blue.weeg.uiowa.edu
> Program in Genetics
> University of Iowa

Look at the NIM:Files.  It tells you how to get the h and v pos of the
file.  I think, if I remember correctly, that is for the Icon!

--matt

---------------------------

>From rweber@helium.Gas.UUG.Arizona.EDU (Roygena R Weber)
Subject: Looking for source code
Date: 26 Jul 1994 22:52:09 GMT
Organization: University of Arizona UNIX Users Group


Could somebody point me to any ftp sites (besides umich and sumex) that 
contain Macintosh source code? Pascal is preferred, but C is okay, too.

Also, is there a FAQ for this group? Where can it be found?

Thanks,

JACOB WEBER------------------------------------------*
 \   Tucson, Arizona                    Where's       \
  \   rweber@gas.uug.arizona.edu         My            \
   \   CompuServe: 72303,3540             Thing?        \
    *----------------------------------------------------*


+++++++++++++++++++++++++++

>From tg3@u.washington.edu (Thurman Gillespy III)
Date: Wed, 27 Jul 1994 09:21:22 -0800
Organization: Dept of Radiology, Univ of Washington

In article <31442p$enm@news.CCIT.Arizona.EDU>,
rweber@helium.Gas.UUG.Arizona.EDU (Roygena R Weber) wrote:

> Could somebody point me to any ftp sites (besides umich and sumex) that 
> contain Macintosh source code? Pascal is preferred, but C is okay, too.
> 
> Also, is there a FAQ for this group? Where can it be found?
> 
> Thanks,
> 
> JACOB WEBER------------------------------------------*
>  \   Tucson, Arizona                    Where's       \
>   \   rweber@gas.uug.arizona.edu         My            \
>    \   CompuServe: 72303,3540             Thing?        \
>     *----------------------------------------------------*

You should get the Apprentice CD-ROM from Celestin Company. This CD-ROM
is PACKED with source code, demos, and various utilites. Its a bargain
at $35.

  Celestin Company
  celestin@pt.olympus.net
  (800) 835-5514 oders
  file://speedway.net/pub/celestin/www/Celestin.html

-- 
Thurman Gillespy III, MD         |  tg3@u.washington.edu
Department of Radiology, SB-05   |  (206)543-3320 voice
University of Washington         |  (206)543-6317 fax
Seattle, WA 98195

+++++++++++++++++++++++++++

>From kenlong@netcom.com (Ken Long)
Date: Wed, 27 Jul 1994 16:02:13 GMT
Organization: NETCOM On-line Communication Services (408 261-4700 guest)

ftp devtools.symantec.com - has C source.
ftp gatekeeper.dec.com - pub/DEC/Modula-2/m2.tar.Z
ftp ftp.cwi.nl - Pascal
ftp.eb.ele.tue.nl - pub/src/pascal/pasos2*
ftp ftp.uu.net - usenet comp sources
ftp zippy.nimh.nih.gov - image (Pascal - several versions)
ftp nic.switch.ch /software/mac
ftp uniwa.uwa.edu.au - POV
ftp ftp.dartmouth.edu /pub/mac
ftp midway.uchicago.edu /pub/OzTex   
ftp ftpbio.bgsu.edu in pub/mac/alt.sources.mac
ftp ftp.cc.umanitoba.ca /mac/develop
ftp oddjob.uchicago.edu. 
ftp magoo.uwsuper.edu - MacWT .04
ftp csvax.cs.caltech.edu - pub/p2c-1.20.tar.Z.
ftp bigbird.csd.scarolina.edu -  pub/mac - JWWalker
ftp mrcnext.cso.uiuc.edu - pub/mac (old P, B, C, M2, F, A and HC)
ftp prep.ai.mit.edu  pub/gnu/etc/GNU

That oughta get you started.

Get any ftp site lists that are available and connect and see what they 
have.  The MacFTP List is pretty well known, but there are others.

I found one site by reading comp.sources.wanted, and a referral by 
someone there.  That group is mostly non-Mac, but I get site tips from 
messages.  Whenever I read, "So-and-so file is available at ftp.xxx.xxx" 
and it's a site I haven't look on yet, I save that address in NotePad++ 
(which I run in addition to my telecom program) and connect after I get 
out of tin.

Always get the site indexes - description files too, if they have them.  
Or start a screen capture as soon as you connect.  I save all the site 
directory lists in a folder on my desktop called "Indexes."

Get on some services, too.  AOL has sources you won't find anywhere else, 
and other services may be the same.  You don't have to remain a meber 
for life - just long enough to get all their unique source code, if any.

-Ken-


+++++++++++++++++++++++++++

>From Bill Melotti <bill.melotti@rl.ac.uk>
Date: 27 Jul 1994 17:27:59 GMT
Organization: Rutherford Appleton Labs (EPSRC)

Looking for source code

Try ftp.switch.ch

Bill
- -----------------------------------------
Bill Melotti                   Rm2.09, R68,
Electronics Engineer           D-RAL,
System Design Group            Chilton,
Electronics Division           Nr. Didcot,
Rutherford Appleton Lab        OX11 0QX

V (0235) 446815, F (0235) 445753
- ----------------------
All these opinions are mine and no one elses

+++++++++++++++++++++++++++

>From kenlong@netcom.com (Ken Long)
Date: Wed, 27 Jul 1994 19:48:34 GMT
Organization: NETCOM On-line Communication Services (408 261-4700 guest)

: You should get the Apprentice CD-ROM from Celestin Company. This CD-ROM
: is PACKED with source code, demos, and various utilites. Its a bargain
: at $35.

If you're going the CD route, EduCarp (no typo) has source on CD's and 
disks, and MacTech has there source CD available for a couple C notes - 
that's U.S. currency, not music tones.  Yeah, you can have it for a 
song!  Two C notes!

Meanwhile, back at reality, there's also the AMUG CD, but theirs and 
EduCarp's contain stuff that's posted.  MacTechs is from their mag.

-Ken-

+++++++++++++++++++++++++++

>From quesnel@sound.music.mcgill.ca (Rene Quesnel)
Date: Wed, 27 Jul 1994 18:21:03 GMT
Organization: Faculty of Music, McGill University

Roygena R Weber (rweber@helium.Gas.UUG.Arizona.EDU) wrote:

> Could somebody point me to any ftp sites (besides umich and sumex) that 
> contain Macintosh source code? Pascal is preferred, but C is okay, too.

Try ftp.apple.com in directory dts/mac/sc. It contains code snippets and
more elaborate examples, some in pascal, a  lot in C and C++. They also
have the source code for the book Macintosh Programming Secrets by Knaster
and Rollin.

You can get the csmp FAQ at nada.kth.se in directory
pub/hacks/mac-faq/

Rene Quesnel

Music Technology and Sound Recording Areas
Faculty of Music, McGill University
Montreal, QC, Canada
e-mail: quesnel@music.mcgill.ca


+++++++++++++++++++++++++++

>From celestin@pt.olympus.net (Paul Celestin)
Date: Thu, 28 Jul 1994 12:54:41 -0700
Organization: Celestin Company

In article <31442p$enm@news.CCIT.Arizona.EDU>,
rweber@helium.Gas.UUG.Arizona.EDU (Roygena R Weber) wrote:

> Could somebody point me to any ftp sites (besides umich and
> sumex) that  contain Macintosh source code? Pascal is
> preferred, but C is okay, too.

Here is a list of a few places I know of:

ftp://ftpbio.bgsu.edu/
ftp://daemon.ncsa.uiuc.edu/TCL/
ftp://ftp.luth.se/pub/mac/developer/
ftp://f.ms.uky.edu/pub/mac/sources/
ftp://ftp.ncsa.uiuc.edu/Mac/
ftp://ics.uci.edu/mac/think-c/
ftp://nic.switch.ch/software/mac/src/
ftp://zippy.nimh.nih.gov/pub/nih-image/
ftp://oak.oakland.edu/pub/macintosh/code/
ftp://plains.nodak.edu/pub/mac/pub/programming/src/
ftp://ssyx.ucsc.edu/pub/mac/
ftp://ftp.cc.umanitoba.ca/Mac-Develop/
ftp://ftp.netcom.com/pub/xplain/

-- 
celestin@pt.olympus.net              (Paul Celestin, Celestin Company)
Home of Apprentice - the Mac Programmer Source Code & Utilities CD-ROM
finger me for more information about Celestin Company and its products

---------------------------

>From smithjim@aol.com (Smith Jim)
Subject: Need C source code for recording sound
Date: 28 Jul 1994 18:12:06 -0400
Organization: America Online, Inc. (1-800-827-6364)

I am looking for source code in C that demonstrates how to record sound
with the
microphone input port.  Any ideas?  Thanks.

Jim 

+++++++++++++++++++++++++++

>From mars@netcom.com (Darren Giles)
Date: Fri, 29 Jul 1994 21:40:31 GMT
Organization: NETCOM On-line Communication Services (408 261-4700 guest)

In article <319afm$sh@search01.news.aol.com>,
Smith Jim <smithjim@aol.com> wrote:
>I am looking for source code in C that demonstrates how to record sound
>with the
>microphone input port.  Any ideas?  Thanks.
>
>Jim 

Here's a section of code which does what I believe you're looking for,
asynchronously, and writes the sampled sound to a resource.  Enjoy!

- Darren

#define	SND_BUFFER_SIZE		(15*11000)
 
typedef struct {
	short					nbr_channels;
	Fixed					sample_rate;
	short					sample_size;
	OSType					compression_type;
} snd_in_info;
 
 
////////////////////////////////////////////////////////////////////////////
OSErr my_sound_start_recording () {
	OSErr					myErr;
	long					buff_size;
 
 
	if (!g_snd_dev_refNum)
		return -1;
		
	//	Find out default settings
	myErr= SPBGetDeviceInfo (g_snd_dev_refNum, siNumberChannels, (char*) &g_snd_info.nbr_channels);
	TST_MYERR_RTN ("calling SPBGetDeviceInfo")
	myErr= SPBGetDeviceInfo (g_snd_dev_refNum, siSampleRate, (char*) &g_snd_info.sample_rate);
	TST_MYERR_RTN ("calling SPBGetDeviceInfo")
	myErr= SPBGetDeviceInfo (g_snd_dev_refNum, siSampleSize, (char*) &g_snd_info.sample_size);
	TST_MYERR_RTN ("calling SPBGetDeviceInfo")
	myErr= SPBGetDeviceInfo (g_snd_dev_refNum, siCompressionType, (char*) &g_snd_info.compression_type);
	TST_MYERR_RTN ("calling SPBGetDeviceInfo")
	
	//	Set to record at 11kHz
	g_snd_info.sample_rate = rate11khz;
	myErr= SPBSetDeviceInfo (g_snd_dev_refNum, siSampleRate, (char*) &g_snd_info.sample_rate);
	TST_MYERR_RTN ("calling SPBSetDeviceInfo")
	myErr= SPBGetDeviceInfo (g_snd_dev_refNum, siSampleRate, (char*) &g_snd_info.sample_rate);
	TST_MYERR_RTN ("calling SPBGetDeviceInfo")
 
	//	Create new sound handle & setup for SND_RSRC_TYPE rsrc header
	g_snd_hdl= NewHandle (SND_BUFFER_SIZE);
	TST_NIL_RTN (g_snd_hdl, "allocating g_snd_hdl handle");
	myErr= SetupSndHeader (g_snd_hdl, g_snd_info.nbr_channels,
				g_snd_info.sample_rate, g_snd_info.sample_size, 
				g_snd_info.compression_type, 60, 0, &g_snd_header_len);
	TST_MYERR_RTN ("calling SetupSndHeader")
	buff_size= GetHandleSize (g_snd_hdl) - g_snd_header_len;
	HLockHi (g_snd_hdl);
	
	//	Setup & call sound input recording
	g_snd_PB.inRefNum=			g_snd_dev_refNum;
	g_snd_PB.count=				buff_size;
	g_snd_PB.milliseconds=		0;
	g_snd_PB.bufferLength=		buff_size;
	g_snd_PB.bufferPtr=			(Ptr) (*g_snd_hdl + g_snd_header_len);
	g_snd_PB.completionRoutine=	nil;
	g_snd_PB.interruptRoutine=	nil;
	g_snd_PB.userLong=			0;
	g_snd_PB.error=				noErr;
	g_snd_PB.unused1=			0;
	myErr= SPBRecord (&g_snd_PB, true);
	TST_MYERR_RTN ("calling SPBRecord")
 
	return noErr;
}
 
 
////////////////////////////////////////////////////////////////////////////
OSErr my_sound_stop_recording () {
	OSErr					myErr;
	long					lead_size;
	uchar					*sample;
 
 
	if (!g_snd_dev_refNum)
		return -1;
		
	//	Make sure we're done reading
	myErr= SPBStopRecording (g_snd_dev_refNum);
	TST_MYERR_RTN ("calling SPBStopRecording")
	
	//	Update snd info for # bytes actually kept
	HUnlock (g_snd_hdl);
	SetHandleSize (g_snd_hdl, g_snd_header_len+g_snd_PB.count);
	myErr= SetupSndHeader (g_snd_hdl, g_snd_info.nbr_channels,
				g_snd_info.sample_rate, g_snd_info.sample_size, 
				g_snd_info.compression_type, 60, g_snd_PB.count,
				&g_snd_header_len);
	
	//	Play it back
	myErr= SndPlay (nil, g_snd_hdl, 0);
	TST_MYERR_RTN ("calling SndPlay")
	
	return noErr;
}
 
 
////////////////////////////////////////////////////////////////////////////
OSErr my_sound_cancel_recording () {
	OSErr					myErr;
 
 
	//	Make sure we're done reading
	if (g_snd_dev_refNum) {
		myErr= SPBStopRecording (g_snd_dev_refNum);
		TST_MYERR_RTN ("calling SPBStopRecording")
	}
	
	if (g_snd_hdl) {
		ReleaseResource (g_snd_hdl);
		DisposeHandle (g_snd_hdl);
		g_snd_hdl= nil;
	}
	
	return noErr;
}

+++++++++++++++++++++++++++

>From kenlong@netcom.com (Ken Long)
Date: Fri, 29 Jul 1994 20:25:21 GMT
Organization: NETCOM On-line Communication Services (408 261-4700 guest)

On AOL, in the MDV lib., theres an aiff recorder source.  Apple's 
SoundApp.pas source has some record routine (s), as I recall.

On AOL, go to the file search (keyword: quickfinder) click the developer 
box and type in: sound
and hit return.  That should lead you to some.

Also, there's source on AOL not listed in the MDV library.  Type in 
search word: source
in other directories than MDV, to track it down.

-Ken-

+++++++++++++++++++++++++++

>From Mark Hanrek <hanrek@cts.com>
Date: Fri, 29 Jul 1994 20:45:36 GMT
Organization: The Information Workshop

In article <319afm$sh@search01.news.aol.com> Smith Jim, smithjim@aol.com
writes:

>I am looking for source code in C that demonstrates how to record 
> sound with the microphone input port.  Any ideas?  Thanks.

Jim,

There should be at least one source code example in the Development File
Libraries.

There are lots and lots of examples, though, on the Developer CD.  If you
know someone with direct internet access, you can have them download a few
from ftp.apple.com.

Hope this helps.

Mark Hanrek

---------------------------

>From AIKEN <INRA000@MUSICB.MCGILL.CA>
Subject: OpenPicture with temporary memory?
Date: Tue, 26 Jul 1994 20:00:30 GMT
Organization: McGill University

Hiya,

    Can anyone think of a reasonably robust way of coercing OpenPicture
into allocating its picture using temporary memory? I was surprised to
find no straightforward way of doing this, considering may QD features,
such as GWorlds, have support for temporary memory.

    Any help appreciated.

    Cheers,

    Mark Aiken
    inra@musicb.mcgill.ca


+++++++++++++++++++++++++++

>From giles@med.cornell.edu (Aaron Giles)
Date: Wed, 27 Jul 1994 01:56:18 -0400
Organization: Cornell University Medical College

In article <26JUL94.16209243.0081@VM1.MCGILL.CA>, AIKEN
<INRA000@MUSICB.MCGILL.CA> wrote:

>     Can anyone think of a reasonably robust way of coercing OpenPicture
> into allocating its picture using temporary memory? I was surprised to
> find no straightforward way of doing this, considering may QD features,
> such as GWorlds, have support for temporary memory.

I don't know how "kosher" this is, but I've done it successfully in a
shipping app without any apparent problems.  At least, it *seems* simple
enough. :-)  Here's the gist:

THz tempZone, oldZone;
PicHandle thePict;
OSErr theErr;

// allocate a handle in temp memory, and retrieve the temporary zone from that
thePict = (PicHandle)TempNewHandle(4, &theErr);
if (theErr == noErr && thePict) {
   tempZone = HandleZone((Handle)thePict);
   DisposeHandle((Handle)thePict);

   // open the picture
   oldZone = GetZone();
   SetZone(tempZone);
   thePict = OpenCPicture(&myParams);
   SetZone(oldZone);
}

Aaron
-- 
Aaron Giles (giles@med.cornell.edu)
Power Macintosh Developer, Cornell University Medical College
JPEGView home page: http://www.med.cornell.edu/jpegview.html
JPEGView FTP site:   ftp://ftp.med.cornell.edu/pub/aarong/jpegview/

+++++++++++++++++++++++++++

>From Jens Alfke <jens_alfke@powertalk.apple.com>
Date: Wed, 27 Jul 1994 20:28:49 GMT
Organization: Apple Computer

In article <26JUL94.16209243.0081@VM1.MCGILL.CA> AIKEN,
INRA000@MUSICB.MCGILL.CA writes:
>     Can anyone think of a reasonably robust way of coercing OpenPicture
> into allocating its picture using temporary memory?

Aaron Giles' solution of switching to the temp-mem zone is explicitly
non-kosher; IM warns not to do anything with the parent zone of temp handles.
I _think_ the only bad thing that will happen, pre-Copland, is that the
handle will not automatically be disposed when your app quits. If you make
sure it's always disposed, this shouldn't be a problem. In a modern-OS
system, though, this might break.

Other approaches I can think of:
* Call OpenPicture, then call NewTempHandle and copy the data from
thePort->picSave handle into the temp handle, then modify thePort->picSave to
point to the temp handle (and dispose the original one.)
* Temporarily patch NewHandle during the OpenPicture call, and have the patch
call NewTempHandle.


--Jens Alfke
  jens_alfke@powertalk              Rebel girl, rebel girl,
            .apple.com              Rebel girl you are the queen of my world

+++++++++++++++++++++++++++

>From giles@med.cornell.edu (Aaron Giles)
Date: Thu, 28 Jul 1994 11:02:18 -0400
Organization: Cornell University Medical College

In article <1994Jul27.202849.19507@gallant.apple.com>, Jens Alfke
<jens_alfke@powertalk.apple.com> wrote:

> Aaron Giles' solution of switching to the temp-mem zone is explicitly
> non-kosher; IM warns not to do anything with the parent zone of temp handles.

Must've missed that warning, but I figured what I was doing was bad
anyway. :-)  Thanks for the "cleaner" suggestions! (cleaner being a very
relative term here)

Aaron
-- 
Aaron Giles (giles@med.cornell.edu)
Power Macintosh Developer, Cornell University Medical College
JPEGView home page: http://www.med.cornell.edu/jpegview.html
JPEGView FTP site:   ftp://ftp.med.cornell.edu/pub/aarong/jpegview/

+++++++++++++++++++++++++++

>From jmunkki@beta.hut.fi (Juri Munkki)
Date: 29 Jul 1994 22:54:13 GMT
Organization: Helsinki University of Technology

In article <1994Jul27.202849.19507@gallant.apple.com> Jens Alfke <jens_alfke@powertalk.apple.com> writes:
>Aaron Giles' solution of switching to the temp-mem zone is explicitly
>non-kosher; IM warns not to do anything with the parent zone of temp handles.
>I _think_ the only bad thing that will happen, pre-Copland, is that the
>handle will not automatically be disposed when your app quits. If you make
>sure it's always disposed, this shouldn't be a problem. In a modern-OS
>system, though, this might break.

It probably couldn't be made very compatible with old versions of the
MultiFinder in any case and some of us (don't look at me though) want
to support System 6.

>Other approaches I can think of:
>* Call OpenPicture, then call NewTempHandle and copy the data from
>thePort->picSave handle into the temp handle, then modify thePort->picSave to
>point to the temp handle (and dispose the original one.)

Sounds dangerous to me, although I'm pretty sure this is safe at least now.

>* Temporarily patch NewHandle during the OpenPicture call, and have the patch
>call NewTempHandle.

Patch???? For something as simple as this? Patches are a necessary evil in
some cases, but should be avoided when there's a better solution. Besides,
this will break if QD decides that it needs to load a resource or create
some other handle when it does the OpenPicture, because the other handle will
also be temp memory even though it shouldn't.

In any case, why not just save the QD bottleneck that handles saving pictures.
You keep a regular handle for the header of the picture and write the data
into temporary memory. For example code on how this is done, just read the
IM chapter that has the example on how to write a picture to disk and replace
the file system calls with temporary memory calls.

-- 
  Juri Munkki			There ain't no such thing as a shareware lunch.
 jmunkki@hut.fi				Windsurfing: Faster than the wind.

---------------------------

>From cabo@mi.aau.dk (Christian Orellana)
Subject: QuickTime 2.0 and MIDI
Date: Mon, 25 Jul 1994 21:34:49 GMT
Organization: aau


Hi!
I understand that some music extension is needed to make QuickTime 2.0 interact
with MIDI. Does anybody know the details of this product? like:

a) Is this an existing product?
b) Where do I get it?
c) How does it work; does it cooperate with the midi manager? 
d) Does it support general midi pacthes only, or can one add custom sounds?
e) Is it implemented as a component?

Best regards -
Christian A.Borlund Orellana
Institute of Physics and Astronomy Aarhus University.
______________________________________________________
Internet e-mail:        muscabo@dfi.aau.dk
voice:                  +45-86102798
mail:                   Dr.Margrethesvej 11,3.th.
                        8200 Aarhus N, DENMARK.
______________________________________________________


+++++++++++++++++++++++++++

>From rmah@panix.com (Robert Mah)
Date: 26 Jul 1994 20:51:28 GMT
Organization: One Step Beyond

cabo@mi.aau.dk (Christian Orellana) wrote:

) I understand that some music extension is needed to make QuickTime 2.0
) interact with MIDI. Does anybody know the details of this product? like:
) 
) a) Is this an existing product?

Has been announced.  Was on the latest developer CD.  I'm not sure if 
it's available to the general public or shipping with new machines yet.

) b) Where do I get it?

Apple.  You can get the QT developer's kit from APDA.

) c) How does it work; does it cooperate with the midi manager? 

I haven't looked at it closely, but from the general description, I think
it implements the General MIDI spec (or parts of it).  That is, it contains
samples for a variety of instruments at various pitches and probably allows
you to play them by note.

) d) Does it support general midi pacthes only, or can one add custom sounds?
) e) Is it implemented as a component?

Don't know.  Anyone looked at the extension on the CD closer yet?

Cheers,
Rob
_____________________________________________________________________
Robert S. Mah           Software Development          +1.212.947.6507
One Step Beyond        and Network Consulting          rmah@panix.com

+++++++++++++++++++++++++++

>From quesnel@sound.music.mcgill.ca (Rene Quesnel)
Date: Wed, 27 Jul 1994 11:44:47 GMT
Organization: Faculty of Music, McGill University

Christian Orellana (cabo@mi.aau.dk) wrote:

> Hi!
> I understand that some music extension is needed to make QuickTime 2.0 interact
> with MIDI. Does anybody know the details of this product? like:

> a) Is this an existing product?
> b) Where do I get it?
> c) How does it work; does it cooperate with the midi manager? 
> d) Does it support general midi pacthes only, or can one add custom sounds?
> e) Is it implemented as a component?

There is a short document "QuickTime 2.0 Information" available at
ftp.support.apple.com in directory 
/pub/Apple SW Updates /Macintosh/Supplemental System Software/.
It doesn't say much but it's a start.

Rene Quesnel

Music Technology and Sound Recording Areas
Faculty of Music, McGill University
Montreal, QC, Canada
e-mail: quesnel@music.mcgill.ca


+++++++++++++++++++++++++++

>From andreas@sctc.com (Glenn Andreas)
Date: Wed, 27 Jul 1994 15:37:11 GMT
Organization: SCTC

rmah@panix.com (Robert Mah) writes:

>cabo@mi.aau.dk (Christian Orellana) wrote:

>) I understand that some music extension is needed to make QuickTime 2.0
>) interact with MIDI. Does anybody know the details of this product? like:
>) 

>) c) How does it work; does it cooperate with the midi manager? 

>I haven't looked at it closely, but from the general description, I think
>it implements the General MIDI spec (or parts of it).  That is, it contains
>samples for a variety of instruments at various pitches and probably allows
>you to play them by note.

>) d) Does it support general midi pacthes only, or can one add custom sounds?
>) e) Is it implemented as a component?

>Don't know.  Anyone looked at the extension on the CD closer yet?

Actually, the "Music Component Architecture" (or something like that) isn't
MIDI.  However, with MoviePlayer 2.0 you can convert MIDI files to QuickTime
movies that just contain the (music) sound track.  Also, if you have a MIDI
output device, you can have QuickTime convert the music to play on the MIDI
device.  Don't know if there are any simple, direct ways to input from a
MIDI device, since I don't own one.

There are actually three different components - the Music Component (a low
level component that you aren't suppose to talk to), the Note Allocator, and
the Tune Player.  You basically set up a bunch of commands, similar to MIDI
(there are note commands, rest commands, knob commands, general commands,
control commands, etc...), and send them to the Tune Player.

The Music Component (there are actually two - built in synthesizer, and
"general MIDI device") is the thing that actually either plays them via
the sound manager, or converts them to MIDI.  The note allocator sits between
the two and figures out how to manage the music component based on the needs
of the tune player.

All in all, once you've figured it out, it works quite well, especially for
things such as adding background music to games (for example).  BTW, I've
recently written an article that will hopefully appear in an upcoming
MacTech explaining the basic format of music commands and the tune player.

Glenn Andreas


+++++++++++++++++++++++++++

>From rmah@panix.com (Robert Mah)
Date: 27 Jul 1994 20:47:57 GMT
Organization: One Step Beyond

andreas@sctc.com (Glenn Andreas) wrote:

) Actually, the "Music Component Architecture" (or something like that)
) isn't MIDI.  However, with MoviePlayer 2.0 you can convert MIDI files
) to QuickTime movies that just contain the (music) sound track.  Also,
) if you have a MIDI output device, you can have QuickTime convert the
) music to play on the MIDI device.  Don't know if there are any simple,
) [...]

Sounds cool, though it's too bad Apple didn't try harder to conform with
the General MIDI standard.  Oh well.

Do you know where I could pick up the docs on this stuff?  I searched
the latest developer CD with QT 2.0 on it, but couldn't find any info.
Some special, new Apple multimedia FTP site perchance?

Cheers,
Rob
_____________________________________________________________________
Robert S. Mah           Software Development          +1.212.947.6507
One Step Beyond        and Network Consulting          rmah@panix.com

+++++++++++++++++++++++++++

>From aclaasse@nyx.cs.du.edu (Arne Claassen)
Date: 27 Jul 1994 22:52:49 -0600
Organization: University of Denver, Dept. of Math & Comp. Sci.

In article <rmah-2707940250560001@rmah.dialup.access.net>,
Robert Mah <rmah@panix.com> wrote:
>Sounds cool, though it's too bad Apple didn't try harder to conform with
>the General MIDI standard.  Oh well.

In what respect? The story i got was that Roland liscensen them their GS
seris sounds for Quicktime 2.0. Only a subset of the entire GM set is supposed
to be in QT 2.0, but the rest can be added by developers if needed.
The internal format is not a standard midifile, but if a MIDI device is 
present (i'd have to assume that QT 2.0 works with MIDI Manager) it will
play through to the midi device. At least that's what the propaganda claimed.

Arne F. Claassen     claassen@ebs330.eb.uah.edu


+++++++++++++++++++++++++++

>From al@crucible.powertools.com (Al Evans)
Date: 29 Jul 94 14:35:21 GMT
Organization: PowerTools, Austin, Texas

In article <317dj1$b0h@nyx.cs.du.edu> aclaasse@nyx.cs.du.edu (Arne Claassen) writes:

>In article <rmah-2707940250560001@rmah.dialup.access.net>,
>Robert Mah <rmah@panix.com> wrote:
>>Sounds cool, though it's too bad Apple didn't try harder to conform with
>>the General MIDI standard.  Oh well.

>In what respect? The story i got was that Roland liscensen them their GS
>seris sounds for Quicktime 2.0. Only a subset of the entire GM set is supposed
>to be in QT 2.0, but the rest can be added by developers if needed.

If the QuickTime 2.0 music-playing routines "conformed with the General
MIDi standard," you would be able to play to a note-allocator 
NoteChannel just like you would to a real MIDI device. This is not
feasible beyond a certain elementary level (i.e., note-on, note-off,
and perhaps controller events). A simple example: using the built-in
synthesizer, a program change cannot be implemented in real time, since
it requires loading a new sound sample from the disk (which is slow)
and you can't do it at interrupt time.

Actually, according to *one* Apple tech support person, you're not 
allowed to make ANY note allocator calls at interrupt time. I dismissed
this as improbable, since the note allocator has no built-in timing
facilities (as does the Midi Manager, for example). So far, I have
had no trouble calling NAPlayNote(), at least, from an interrupt 
handler -- I was told by another Apple tech support person that this
was legal.
					--Al Evans--
-- 
Al Evans		|   Graphic Elements: A new standard for 
________________________|__ high-performance interactive Macintosh graphics.
al@crucible.powertools.com |  Available from mac.archive.umich.edu
- -------------------------| /mac/development/libraries/graphicelements2.sit.hqx

---------------------------

>From rcostale@nmsu.edu (Raphael J. Costales)
Subject: Tab Patch for TextEdit
Date: 29 Jul 1994 05:22:07 GMT
Organization: New Mexico State University, Las Cruces, NM

/***************************************************************************
 
    tab_patch.c
 
    A while back, jesjones@stein.u.washington.edu posted some code written
in Modula-2 for three patches to TextEdit.  These patches enable TextEdit to
display tab characters as a run of spaces.  The three routines are:
 
    1.  DrawText
    2.  TextWidth
    3.  Pixel2Char (System 6)
        NPixel2Char (System 7)
 
    I rewritten the code in C in Think C ver. 4 using System 6 and tested it
on a Mac Plus - eight years old, but it still works fine!  I just wrote the
Pixel2Char, but NPixel2Char would be handled the same way.  The three patches
work the same way.  They expand tab characters into spaces then call the
original routine.
 
    Note, Pixel2Char & NPixel2Char are not real traps.  They use a generic
trap, ScriptUtil, after pushing a selector on the stack (see IM V).  Because
ScriptUtil takes a varying number of arguments, some assembly is required -
excuse the pun.
 
    Fell free to send any comments or suggestions other than buy a new Mac!
 
    rcostale@nmsu.edu
 
***************************************************************************/
 
#define TABLEN      4           /* Tab length */
#define MAXSIZE     256         /* Size of Buffer.  Any text expanded beyond
                                 * the size of the buffer won't be displayed
                                 */
 
extern WindowPtr myWindow;      /* Of course, these would be your working */
extern TEHandle TEH;            /* Window pointer and TextEdit handle */
 
static pascal void  DoTrap();
 
pascal void newDrawText(char *, short, short);
pascal int  newTextWidth(char *, short, short);
pascal int  newPixel2Char(char *, short, short, short, Boolean *, long);
 
ProcPtr     oldDrawText, oldTextWidth, oldPixel2Char;
 
TabsOn()    /* Install patches */
{
    /* The first two patches are straight forward */
 
    oldDrawText = (ProcPtr) NGetTrapAddress(0xA885, ToolTrap);
    oldTextWidth = (ProcPtr) NGetTrapAddress(0xA886, ToolTrap);
 
    NSetTrapAddress((long) newDrawText, 0xA885, ToolTrap);
    NSetTrapAddress((long) newTextWidth, 0xA886, ToolTrap);
 
    /* The Pixel2Char uses the generic trap ScriptUtil.  We will patch in
     * an assembly routine that test the selector
     */
 
    oldPixel2Char = (ProcPtr) NGetTrapAddress(0xA8B5, ToolTrap);
    NSetTrapAddress((long) DoTrap, 0xA8B5, ToolTrap);
}
 
TabsOff()   /* Remove the patches when you're application finishes! */
{
    NSetTrapAddress((long) oldDrawText, 0xA885, ToolTrap);
    NSetTrapAddress((long) oldTextWidth, 0xA886, ToolTrap);
    NSetTrapAddress((long) oldPixel2Char, 0xA8B5, ToolTrap);
}
 
/* The assembly routine to check selector */
static pascal void DoTrap()
{
    long    selector = 0x820E0014;  /* or 0x8222002 for NPixel2Char */
 
    asm {
        move.l  selector, d0
        unlk    a6
        cmp.l   4(sp), d0           /* Is it the Pixel2Char selector? */
        bne.s   @old                /* No, do old oldPixel2Char */
        jmp     newPixel2Char       /* Yes, do patch */
@old
        move.l  oldPixel2Char, a0
        jmp     (a0)
    }
}
 
pascal void newDrawText(char textPtr[], short first, short count)
{
    char    buffPtr[MAXSIZE] = {0};
    int     buffCount;
 
    /* if were using my window then expand the text into the buffer and
     * call the original routine using the buffer.
     */
 
    if (FrontWindow() == myWindow) {
        buffCount = tab2spaces(textPtr + first, buffPtr, count);
        CallPascal(buffPtr, 0, buffCount, oldDrawText);
    }
    else
        CallPascal(textPtr, first, count, oldDrawText);
}
 
pascal int newTextWidth(char textPtr[], short first, short count)
{
    char    buffPtr[MAXSIZE] = {0};
    int     buffCount;
 
    /* same idea here */
 
    if (FrontWindow() == myWindow) {
        buffCount = tab2spaces(textPtr + first, buffPtr, count);
        return CallPascalW(buffPtr, 0, buffCount, oldTextWidth);
    }
    else
        return CallPascalW(textPtr, first, count, oldTextWidth);
}
 
/* This function converts tabs to spaces and places the text in a buffer.
 * It also returns the size of the buffer.
 */
int tab2spaces(char textPtr[], char buffPtr[], short count)
{
    char    chr;
    int     i, j, buffCount, spc;
 
    i = j = spc = 0;
    buffCount = offset(textPtr);
    for (i = 0; i < count; i++) {
        switch (chr = textPtr[i]) {
        case '\t':
            spc = TABLEN - (buffCount % TABLEN);
            while (spc--) {
                buffPtr[j++] = ' ';
                buffCount++;
            }
            break;
        case '\r':
            buffCount = 0;
        default:
            buffPtr[j++] = chr;
            buffCount++;
        }
    }
    return j;
}
 
/* This function finds the offset from the start of a line. */
int offset(char textPtr[])
{
    char   *linePtr, *charPtr;
    int     i = 0;
 
    linePtr = textPtr;
 
    /* find start of line */
 
    while ((linePtr > (*(**TEH).hText)) && (*linePtr != '\r'))
        linePtr--;
 
    /* find offset */
 
    for (charPtr = linePtr; charPtr < textPtr; charPtr++)
        switch (*charPtr) {
        case '\t':
            i = i + TABLEN - (i % TABLEN);
            break;
        case '\r':
            i = 0;
            break;
        default:
            i++;
        }
    return i;
}
 
/* Note, the selector is not an actual parameter. The selector is push on to
 * the stack before issuing the ScriptUtil trap.  Since the Pascal calling
 * convention pushes parametes from left-to-right, the selector is right above
 * the return address.  Use NPixel2Char declaration if you're using System 7.
 */
pascal int newPixel2Char(char textPtr[], short count, short slop, short width,
                         Boolean *leadingEdge, long selector)
{
    char    buffPtr[MAXSIZE] = {0};
    int     buffCount, pos;
 
    /* Again, we expand the text into a buffer and call the original trap */
 
    if (FrontWindow() == myWindow) {
        buffCount = tab2spaces(textPtr, buffPtr, count);
        pos = CallPascalW(buffPtr, buffCount, slop, width, &leadingEdge,
                          selector, oldPixel2Char);
        return charPos(textPtr, pos);
    }
    else
        return CallPascalW(textPtr, count, slop, width, &leadingEdge,
                           selector, oldPixel2Char);
}
 
/* returns the character position in the actual text corresponding to
 * position in the buffer.
 */
int charPos(char textPtr[], int pos)
{
    char   *linePtr;
    int i = 0, j =0 ;
 
    linePtr = textPtr;
    while ((linePtr > (*(**TEH).hText)) && (*linePtr != '\r'))
        linePtr--;
 
    while (i < pos) {
        switch (*linePtr) {
        case '\t':
            i = i + TABLEN - (i % TABLEN);
            j++;
            break;
        case '\r':
            i = j = 0;
            break;
        default:
            i++; j++;
        }
        linePtr++;
    }
    return j;
}

-- 
+------+
|      | Raphael J.S. Costales
| NMSU | rcostale@nmsu.edu
|  *___| New Mexico State University

---------------------------

>From cshotton@oac.hsc.uth.tmc.edu (Chuck Shotton)
Subject: [Q] Increasing stack size?
Date: Fri, 29 Jul 1994 11:27:07 -0600
Organization: Academic Computing, UT-Houston

Can anyone think of a reason why a program that runs fine on most every Mac
model ends up with a stack (not heap) that runs out of space on a SE or
Plus? Is there something different that Think C (or CodeWarrior, for that
matter) must do on a 68K Mac that would cause it to eat significantly more
stack space? FWIW the app is MacHTTP, so it's playing with MacTCP,
AppleScript (if available), and AppleTalk (if required by MacTCP).

Stack space and heap space come out of the same chunk of memory allocated
to the application, correct? Is it possible that one of the aforementioned
software elements may eat up a bunch of memory on a Plus or SE? The
confusing thing is that frequent checks of available RAM show nothing amiss
while the program is running, yet it ends up with a corrupted stack
(because it runs out of space?)

--_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_\_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
Chuck Shotton                             \ 
Assistant Director, Academic Computing     \   "Are we there yet?"
U. of Texas Health Science Center Houston   \ 
cshotton@oac.hsc.uth.tmc.edu  (713) 794-5650 \ 
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-\-_-_-_-_-_-_-_-_-_-_-_-_-

+++++++++++++++++++++++++++

>From larson@oahu.cs.ucla.edu (Christopher Larson)
Date: Fri, 29 Jul 94 18:36:15 GMT
Organization: UCLA, Computer Science Department

In article <cshotton-290794112707@oac2.hsc.uth.tmc.edu> cshotton@oac.hsc.uth.tmc.edu (Chuck Shotton) writes:
>Can anyone think of a reason why a program that runs fine on most every Mac
>model ends up with a stack (not heap) that runs out of space on a SE or
>Plus?

Sure. Neither of those machines has Color Quickdraw. On machines without CQD,
the default stack size is (I believe) 8K, but on a machine with CQD (as most
Macs out there today are) the default stack size is 32K. Your program must
use stack space larger than 8K and smaller than 32K -- hence it works on
CQD machines but not the old ones.

>Stack space and heap space come out of the same chunk of memory allocated
>to the application, correct?

Yup.

>Is it possible that one of the aforementioned
>software elements may eat up a bunch of memory on a Plus or SE?

I doubt they eat any _more_ on a Plus or SE than on other machines; whether
or not they eat up a 'bunch' is left as an exercise for the reader ;-).

>The
>confusing thing is that frequent checks of available RAM show nothing amiss
>while the program is running, yet it ends up with a corrupted stack
>(because it runs out of space?)

Are you checking the amount of free stack space during runtime (other than
by watching the stack sniffer inititate a system error)? During development,
you should try to max out the stack usage and then call StackSpace() to
determine your stack usage. If this usage is larger than the smallest default
stack size, you should expand the stack to accomidate for this difference.
(E.g. if you find that your program uses 20K of stack space, you should
expand the stack by at least 12K (perhaps a little more for cushioning) in
the initialization phase of your program.)

Techniques for expanding the stack and the details of the StackSpace() call
can be found in Inside Macintosh: Memory.

--Chris
_______________________________________________________________________________
Chris Larson -- Amateur Macintosh Geek, CoBase Research Assistant
L.A. Institute of Slowly and Painfully Working Out the Surprisingly Obvious
Death to the Trojans! Go Bruins!

(Insert disclaimer here)
Internet: larson@kingston.cs.ucla.edu

---------------------------

End of C.S.M.P. Digest
**********************