home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-12-08 | 28.9 KB | 788 lines | [TEXT/R*ch] |
- *4* Files
-
- 4.1) Q: How do I tell fopen() to open a file the user has selected using
- StandardGetFile?
-
- A: The "standard" ANSI C file functions are less than well suited for
- the Macintosh way of doing things. However, if you are doing a port for
- your own enjoyment and benefit (or maybe for in-house work) you can use
- the following function: (see below about converting a wdRefNum into a
- vRefNum/parID pair)
-
- *code*
- FILE *
- fopen_mac ( short vRefNum , long parID , char * fileName , char * mode ) {
-
- short oldVol ;
- short aVol ;
- long aDir , aProc ;
- FILE * ret = NULL ;
-
- if ( GetVol ( NULL , & oldVol ) ) {
- return NULL ;
- }
- if ( GetWDInfo ( oldVol , & aVol , & aDir , & aProc ) ) {
- return NULL ;
- }
- if ( HSetVol ( NULL , vRefNum , parID ) ) {
- return NULL ;
- }
- ret = fopen ( fileName , mode ) ;
- if ( HSetVol ( NULL, aVol , aDir ) ) {
- /* an error we can't currently handle */
- }
- if ( SetVol ( NULL, oldVol ) ) {
- /* an error we can't currently handle */
- }
- return ret ;
- }
- *end*
-
- All of the above is necessary for one reason or another - if you are
- interested, by all means look HSetVol up in Think Reference 2.0 or New
- Inside Mac: Files.
-
- In older versions of MPW; this wouldn't work since the MPW libraries
- used to do a GetVol and explicitly use that value by itself.
-
- 4.2) Q: When can I use the HOpen, HCreate etc file calls? Are they only
- System 7 calls?
-
- A: All the HXxx calls that take a vRefNum and parID as well as the file
- name are implemented in glue that works on any system that has HFS
- (meaning 3.2 and up with the HD20 INIT, and all systems from System 6
- and up)
-
- The glue is available in MPW 3.2 and up, and Think C 5.0 and up. This
- goes for all HXxx calls except HOpenDF; therefore, if you are interested
- in System 6 compatibility, use HOpen instead and make sure you don't
- allow file names beginning with a period.
-
- 4.3) Q: Why do you say wdRefNum sometimes and vRefNum sometimes?
- Why do you say parID sometimes and dirID sometimes?
-
- A: When the Mac first made an appearance in 1984, it identified files by
- using a vRefNum (volume reference number meaning a floppy disk or later
- hard disk) and a name. Once HFS saw the light of day, folders within
- folders became a reality, and you needed a dirID as well to point out
- what folder you really meant on the volume. However, older programs
- that weren't being rewritten still knew nothing about directory IDs, so
- Apple had SFGetFile make up "fake" vRefNums that didn't just specify a
- volume, but also a parent folder. These are called wdRefNums (for
- working directory) and were a necessary evil invented in 1985. You
- should not create (or, indeed, use) wdRefNums yourself.
-
- There is a system-wide table that maps wdRefNums onto vRefNum/parID
- pairs. There is a limit to the size of this table. A dirID and a parID
- is almost the same thing; you say "parID" when you mean the folder
- something is in, while you say a "dirID" when you mean the folder
- itself. If you for instance have a folder called "Foo" with a folder
- called "Bar" in it, the parID for "Bar" would be the dirID for "Foo."
-
- 4.4) Q: How do I convert a wdRefNum as returned by SFGetFile
- into a vRefNum/parID pair to use with the HXxx calls?
-
- A: Use GetWDInfo, which is declared as:
-
- Pascal OSErr GetWDInfo ( short wdRefNum , short * vRefNum , long * parID
- , OSType * procID ) ;
-
- The procID parameter must be non-NULL and point to an OSType variable,
- but the value of that variable can and should be ignored.
-
- It is recommended that, as soon as you get your hands on a wdRefNum, for
- instance from SFGetFile, you directly convert it into a vRefNum/parID
- pair and always use the latter to reference the folder.
-
- 4.5) Q: How do I select a folder using SFGetFile?
-
- A: This requires a custom dialog with a filter proc. It is too
- complicated to show here, but not totally impossible to comprehend.
- There is sample code on ftp.apple.com, in the directory dts/snippets, on
- how to do this.
-
- 4.6) Q: How do I get the full path of a file referenced by a vRefNum,
- parID and name?
-
- A: You don't.
-
- OK, I cheated you. There is exactly ONE valid reason to get the full
- path of a file (or folder, for that matter) and that is to display its
- location to the user in, say, a settings dialog. To actually save the
- location of the file you should do this: (assuming the file is in an
- FSSpec called theFile - you can use FSSpecs in your program even if you
- don't run under System 7; just make your own MyFSMakeFSSpec that fills
- in the FSSpec manually if it's not implemented)
-
- *code*
- if ( ! aliasManagerAvailable ) { /* System 6 ? */
- GetVolumeName ( theFile -> vRefNum , vName ) ;
- GetVolumeModDate ( vRefNum , & date ) ;
- Save ( vName , date , parID , fileName ) ;
- } else {
- NewAlias ( NULL , theFile , & theAlias ) ;
- Save ( theAlias ) ;
- DisposeHandle ( ( Handle ) theAlias ) ;
- }
- *end*
-
- If you are really concerned about these issues (of course you are!) you
- should save BOTH of these methods when available, and load back whatever
- is there that you can handle; since users may be using your application
- in a mixed System 6/System 7 environment.
-
- To get back to the file is left as an exercise for the reader.
-
- To open a file using fopen() or the Pascal equivalent, see above about
- using and not using HSetVol.
-
- 4.7) Q: What about actually getting the full path for a file? I promise
- I will only use it to show the location of a file to the user!
-
- A: Enter PBGetCatInfo, the Vegimatic of the Mac file system. Any Mac
- hacker of knowledge has taken this system call to his heart. What you
- do is this:
-
- *code*
- OSErr
- GetFolderParent ( FSSpec * fss , FSSpec * parent ) {
-
- CInfoPBRec rec ;
- short err ;
-
- * parent = * fss ;
- rec . hFileInfo . ioNamePtr = parent -> name ;
- rec . hFileInfo . ioVRefNum = parent -> vRefNum ;
- rec . hFileInfo . ioDirID = parent -> parID ;
- if ( parent -> name [ 0 ] ) {
- rec . hFileInfo . ioFDirIndex = 0 ;
- } else {
- rec . hFileInfo . ioFDirIndex = -1 ;
- }
- rec . hFileInfo . ioFVersNum = 0 ;
- err = PBGetCatInfoSync ( & rec ) ;
- if ( ! ( rec . hFileInfo . ioFlAttrib & 0x10 ) ) { /* Not a folder */
- if ( ! err ) {
- err = dirNFErr ;
- }
- } else {
- parent -> parID = rec . dirInfo . ioDrParID ;
- parent -> name [ 0 ] = 0 ;
- }
- return err ;
- }
-
-
- OSErr
- GetFullPathHandle ( FSSpec * fss , Handle * h ) {
-
- Handle tempH = NULL ;
- short err ;
- FSSpec fs = * fss ;
-
- while ( fs . parID > 1 ) {
- tempH = NULL ;
- PtrToHand ( & fs . name [ 1 ] , & tempH , fs . name [ 0 ] ) ;
- PtrAndHand ( ( void * ) ":" , tempH , 1 ) ;
- HandAndHand ( * h , tempH ) ;
- SetHandleSize ( * h , 0L ) ;
- HandAndHand ( tempH , * h ) ;
- DisposeHandle ( tempH ) ;
- tempH = NULL ;
- GetFolderParent ( & fs , & sSpec ) ;
- fs = sSpec ;
- }
- GetVolName ( fs . vRefNum , fs . name ) ;
- PtrToHand ( & fs . name [ 1 ] , & tempH , fs . name [ 0 ] ) ;
- PtrAndHand ( ( void * ) ":" , tempH , 1 ) ;
- HandAndHand ( * h , tempH ) ;
- SetHandleSize ( * h , 0L ) ;
- HandAndHand ( tempH , * h ) ;
- DisposeHandle ( tempH ) ;
- tempH = NULL ;
- if ( ! IsFolder ( fss ) ) {
- SetHandleSize ( * h , GetHandleSize ( * h ) - 1 ) ; // Remove colon }
- return 0 ;
- }
- *end*
-
- 4.8) Q: So how do I get the names of the files in a directory?
-
- A: You use PBGetCatInfo again, but this time you set ioFDirIndex to 1 or
- more (you need to know the dirID and vRefNum of the
-
- folder you're interested in) You then call PBGetCatInfoSync for values
- of ioFDirIndex from 1 and up, until you get an fnfErr. Any other err
- means you are not allowed to get info about THAT item, but you may be
- for the next. Then collect the names in the string you made ioNamePtr
- point to as you go along. Note that you need to fill in the ioDirID
- field for each iteration through the loop, and preferrably clear the
- ioFVersNum as well.
-
- Note that the contents of a directory may very well change while you are
- iterating over it; this is most likely on a file server that more than
- one user uses, or under System 7 where you run Personal File Share.
-
- 4.9) Q: How do I find the name of a folder for which I only know the
- dirID and vRefNum?
-
- A: You call (surprise!) PBGetCatInfo! Make ioNamePtr point to an empty
- string (but NOT NULL) of length 63 (like, an Str63) and ioFDirIndex
- negative (-1 is a given winner) - this makes PBGetCatInfo return
- information about the vRefNum/dirID folder instead of the file/folder
- specified by vRefNum, parID and name.
-
- 4.10) Q: How do I make the Finder see a new file that I created? Or if I
- changed the type of it; how do I display a new icon for it?
-
- A: You call (surprise!) PBGetCatInfo followed by PBSetCatInfo for the
- FOLDER the file is in. Inbetween, you should set ioDrMdDat to the
- current date&time. Code:
-
- *code*
- OSErr
- TouchFolder ( short vRefNum , long parID ) {
-
- CInfoPBRec rec ;
- Str63 name ;
- short err ;
-
- rec . hFileInfo . ioNamePtr = name ;
- name [ 0 ] = 0 ;
- rec . hFileInfo . ioVRefNum = vRefNum ;
- rec . hFileInfo . ioDirID = parID ;
- rec . hFileInfo . ioFDirIndex = -1 ;
- rec . hFileInfo . ioFVersNum = 0 ;
- err = PBGetCatInfoSync ( & rec ) ;
- if ( err ) {
- return err ;
- }
- GetDateTime ( & rec . dirInfo . ioDrMdDat ) ;
- rec . hFileInfo . ioVRefNum = vRefNum ;
- rec . hFileInfo . ioDirID = parID ;
- rec . hFileInfo . ioFDirIndex = -1 ;
- rec . hFileInfo . ioFVersNum = 0 ;
- rec . hFileInfo . ioNamePtr [ 0 ] = 0 ;
- err = PBSetCatInfoSync ( & rec ) ;
- return err ;
- }
- *end*
-
- 4.11) Q: Aren't we done with PBGetCatInfo soon?
-
- A: Well, it turns out that you can also find out whether an FSSpec is a
- file or a folder by calling PBGetCatInfo and check bit 4 (0x10) of
- ioFlAttr to see whether it is a folder. You may prefer to call
- ResolveAliasFile for this instead.
-
- You can also check the script of the file's title using PBGetCatInfo and
- check the ioFlFndrXInfo field if you want to work with other script
- systems than the Roman system.
-
- Another common use is to find out how many items are in a folder; the
- modification date of something or the correct capitalization of its name
- (since the Mac file system is case independent BUT preserves the case
- the user uses)
-
- 4.12) Q: How do I set what folder should initially be shown in the
- SFGetFile boxes?
-
- A: You stuff the dirID you want to show into the lo-mem global
- CurDirStore, and the NEGATIVE of the vRefNum you want into the lo-mem
- global SFSaveDisk.
-
- If you are using CustomGetFile and return sfSelectionChanged from an
- "init" message handler, you must remember to clear the script code, else
- the selection will not change.
-
- 4.13) Q: How do I find the folder my application started from? How do I
- find the application file that's running?
-
- A: Under System 7, you call GetProcessInformation using the
- ProcessSerialNumber kCurrentProcess with a pointer to an existing FSSpec
- in the parameter block. This will give you your file, and, by using the
- vRefNum and parID, the folder the application is in.
-
- *code*
- OSErr CurrentProcessLocation(FSSpec *applicationSpec)
- {
- ProcessSerialNumber currentPSN;
- ProcessInfoRec info;
-
- currentPSN.highLongOfPSN = 0;
- currentPSN.lowLongOfPSN = kCurrentProcess;
- info.processInfoLength = sizeof(ProcessInfoRec);
- info.processName = NULL;
- info.processAppSpec = applicationSpec;
- return ( GetProcessInformation(¤tPSN, &info) );
- }
- *end*
-
- Beware from writing to your applications resource or data forks; the
- former breaks on CDs/write protected floppies/file servers/virus
- checkers, the latter fails on PowerPC as well as in the above cases.
-
- 4.14) Q: When can I use those nifty, easy to use FSSpec calls?
-
- A: In Systems >= 7, in System 6 with QuickTime installed, in any system
- if you use the FSpCompat functions provided by MoreFiles [see below].
-
- 4.15) Q: I need to use
-
- *5* Imaging with QuickDraw and the Gang
-
- 5.1) Q: Why is CopyBits so slow?
-
- A: It is not. It just requires some hand-holding to get good results.
- The main rules are: Make sure the source and destination pixMaps are of
- the same depth.
-
- Make sure the front color is black and the back color is white.
-
- Use srcCopy and don't use a masking region, unless it's rectangular.
-
- Copy to an unclipped window (the frontmost window). Make sure the
- ctSeed values of the source pixMap and dest pixMap match.
-
- Copying few and large pixMaps is faster than copying many and small
- ones. Icon-sized sprites count as small ones.
-
- Make sure your source bitmap or pixelMap has the same alignment, when
- adjusted for the source and destination rect expressed in global screen
- coordinates. The necessary alignment is 32 bits (4 bytes), although 128
- bit (16 byte) alignment is probably even better on 68040 macs and won't
- hurt on other macs.
-
- Example of global alignment:
-
- Your window is positioned at (42,100) (H,V)
-
- Your destination rectangle is (10,20)-(74,52)
-
- The alignment coefficient of the rectangle in global coordinates is
- (42+10)*bitDepth where bitDepth is one of 1,2,4,8,16 or 32.
-
- Make sure your source pixmap rect has the same coeffecient modulo your
- alignment factor (in bits) For black&white macs, this is still true,
- although bitDepth is fix at 1. Offscreen pixMaps can calculate with a
- "global posistion" of 0,0 and get correct results.
-
- 5.2) Q: Why is CopyBits still too slow?
-
- A: Because there is always some overhead involved in calling QuickDraw;
- you have the trap dispatcher, clipping checks, and checking whether the
- CopyBits call is being recorded in a PICT handle (if you called
- OpenPicture)
-
- If you can't live with this, look at 4.8 below, but PLEASE try and make
- CopyBits work, and retain the CopyBits code in your application, so
- users with special monitors (accellerator cards, PowerBook color
- screens, Radius Pivot screens) can still play your game. (non-game
- applications don't need more speed than CopyBits can give at its max.
- Promise!)
-
- 5.3) Q: What is the fastest way to set one pixel?
-
- A: NOT SetCPixel()! Assuming you have the correct ForeColor() set, you
- can set the pen size to (1,0) and call Line (0,1)
-
- I have heard PaintRect is good for this but requires slightly more code.
- Using PaintRect eliminates a trap call.
-
- 5.4) Q: Why do pictures I record suddenly draw as empty space or not
- draw at all?
-
- A: When recording pictures, you have to set the clipping area to exactly
- the frame of the picture you are recording. This is because it is
- initally set at -32768,32727 in both directions, and offsetting the
- picture even one pixel when drawing it will result in the region
- wrapping around and becoming empty.
-
- When recording pictures, do this:
-
- *code*
- PicHandle h = OpenPicture ( & theRect ) ;
- ClipRect ( & theRect ) ;
- /* draw the picture */
- ClosePicture ( ) ;
- *end*
-
- 5.5) Q: Where can I find the format of picture files and
- resources?
-
- A: The format of a picture resource version 1 is defined in a
- technical note. This format is obsolete.
-
- The format of a picture resource version 2 is defined in Old Inside Mac
- vol V, with addenda in Old Inside Mac vol VI.
-
- Some things happen with QuickTime compressed pictures; try the Inside
- Mac: QuickTime book or turn to Inside Mac: Imaging with QuickDraw which
- is the definite reference on QuickDraw.
-
- The format of a picture file is the same as that of a picture resource
- with 512 added 0 bytes in front.
-
- 5.6) Q: GWorlds?
-
- A: What about them? They're great. Look them up in Old Inside Mac vol
- VI. Don't forget to SetGWorld back to what it was before calling
- WaitNextEvent.
-
- 5.7) Q: How do I find the current depth of the screen?
-
- A: My question to you is: What screen? Many macs have more than one
- screen attached. You can use GetDeviceList and walk the devices to find
- the screen you're looking for (use TestDeviceAttribute to see whether
- it's a screen) or you can call GetMaxDevice() to find the deepest device
- your window intersects.
-
- Once you have the device handle, finding the depth is just a
- matter of looking at the gdPMap pixMapHandle, and dereference it
- to the pmSize field. Done.
-
- 5.8) Q: Why is it a bad idea to draw directly to screen?
-
- A: Because of several reasons:
-
- - You will be incompatible with future display hardware.
-
- - You will be incompatible with some present-day display
- hardware, such as Radius Pivots and PowerBook color screens.
-
- - You have to think about a lot of things; testing it all on
- your own machine is not possible and the chances of crashing are
- great.
-
- - You will be incompatible with future hardware where devices
- may live in some unaccessible I/O space.
-
- 5.9) Q: But I really need to do it. I can't make my animation
- into a QuickTime movie, and CopyBits is too slow, even when
- syncing to the screen retrace.
-
- A: You have to prepare yourself, and ask these questions:
-
- 1) Do I want to support all screens, or just 8-bit devices?
-
- 2) Do I have a few weeks of free time to make it work?
-
- 3) Do I want to get nasty mail when I break on some hardware and
- have to rev the application - even if I may not be able to get
- ahold of the hardware that makes it break?
-
- If all you're doing is rendering an image pixel-by-pixel or
- line-by-line, maybe you can draw directly into an offscreen
- pixMap/GWorld and then CopyBits the entire GWorld to screen?
- That will be more compatible, especially if you use the
- keepLocal flag when creating the GWorld.
-
- 5.10) Q: Okay, so how do I get the base address of the screen?
-
- A: "The" screen? Which screen? There may be several. The base
- address may be on an accellerated screen card. There may be more
- than one screen covering the same desktop area.
-
- Due to unfortunate circumstances, there is a bug in
- GetPixBaseAddr() that causes it to return incorrect results for
- early versions of System 7. Instead, get the baseAddr directly
- from the gdPMap handle of the GDHandle for the screen you draw
- to. This address may need switching to 32bit mode to be valid.
-
- 5.11) Q: Quit stalling and give me code!
-
- A: Okay, but I'll let you sweat over Inside Mac to figure out
- what it does. All of it is important; believe me! To make this
- code run faster, a lot of the things it does can be done once
- before starting to draw.
-
- Make sure that you have a window that covers the area where you
- are drawing, so other windows will not be overdrawn. Also make
- sure that you do not do direct-to-screen-drawing while you are
- in the background.
-
- *code*
- /* This is presently untested code */
- /* Value is dependent on what depth the screen has */
- /* This code doesn't work on non-color-quickdraw Macs (i e the MacClassic) */
- /* "where" is in GLOBAL coordinates */
- void
- SetPixel ( Point where , unsigned long value ) {
-
- Rect r ;
- GDHandle theGD ;
- char * ptr ;
- long rowBytes ;
- short bitsPerPixel ;
- PixMapHandle pmh ;
- Boolean oldMode ;
-
- r . left = where . h ;
- r . top = where . v ;
- r . right = r . left + 1 ;
- r . bottom = r . top + 1 ;
- theGD = GetMaxDevice ( & r ) ;
- if ( theGD ) {
- where . v -= ( * theGD ) -> gdRect . left ;
- where . h -= ( * theGD ) -> gdRect . top ;
- pmh = ( * theGD ) -> gdPMap ;
- rowBytes = ( ( * pmh ) -> rowBytes ) & 0x3fff ;
- ptr = ( char * ) ( * pmh ) -> baseAddr ;
- bitsPerPixel = ( * pmh ) -> pixelSize ;
- oldMode = true32b ;
- ptr += where . v * rowBytes ;
- SwapMMUMode ( & oldMode ) ;
- switch ( bitsPerPixel ) {
- case 1 :
- if ( value & 1 ) {
- ptr [ where . h >> 3 ] |= ( 128 >> ( where . h & 7 ) ) ;
- } else {
- ptr [ where . h >> 3 ] &= ~( 128 >> ( where . h & 7 ) ) ;
- }
- break ;
- case 2 :
- ptr [ where . h >> 2 ] &= ( 192 >> 2 * ( where . h & 3 ) ) ;
- ptr [ where . h >> 2 ] |= ( value & 3 ) << 2 * ( 3 - ( where . h
- & 3 ) ) ;
- break ;
- case 4 :
- ptr [ where . h >> 1 ] &= ( where . h & 1 ) ? 0xf : 0xf0 ;
- ptr [ where . h >> 1 ] |= ( value & 15 ) << 4 * ( 1 - ( where . h
- & 1 ) ) ;
- break ;
- case 8 :
- ptr [ where . h ] = value ;
- break ;
- case 16 :
- ( ( unsigned short * ) ptr ) [ where . h ] = value ;
- break ;
- case 32 :
- ( ( unsigned long * ) ptr ) [ where . h ] = value ;
- break ;
- default :
- abort ( ) ; /* Should never get here */
- }
- SwapMMUMode ( & oldMode ) ;
- }
- }
- *end*
-
- *6* Text
-
- 6.1) Q: How do I get TextEdit to display more than 32k of text?
-
- A: You don't. Truly, it's not worth it. There's a call-for-call
- TextEdit replacement called TE32k which does > 32k text, and is
- available from any recent Info-Mac mirror. It doesn't do styled text,
- though.
-
- 6.2) Q: How do I get TextEdit to display more than 32k of __styled__
- text *and* embedded objects in the text (such as pictures)?
-
- WASTE, available at ftp://ghost.dsi.unimi.it/pub2/papers/piovanel, is a
- vast improvement over TextEdit. Version 1.0 does >32k styled text
- retains compatibility with the TextEdit style scrap (which is used to
- store styled text in files such as SimpleText's, as well as in the
- clipboard), includes source code and is freeware. Really worth the
- download. Version 1.1 adds embedded objects within the text, such as
- pictures, intelligent cut-and-paste, built-in Drag Manager support. 1.1
- is currently in alpha, but seems to be very stable.
-
- 6.3) Q: How do I include pictures in text using TextEdit?
-
- A: There's no really easy way (such as a TEAddPict() call), and it will
- be a nasty looking kludge if you do get it working, but if you can live
- with that, here's how to do it. I do recommend that you take a look
- at Q 6.2, above.
-
- Write an algorithm to get the position of a special marker character
- [Teach/SimpleText uses option-space] or text attribute that the user
- will insert wherever he wants a picture. Pass this position to a
- function similar to the one below.
-
- *code*
- /*
- TEDrawPicture
- Draw a picture within TextEdit's text.
-
- input:
- pos - the position of the special character in the text where the user
- wants a picture.
- r - size of picture
-
- output:
- r - frame in which picture was drawn
- */
-
- void TEDrawPicture(short pos,PicHandle pic,Rect &r,TEHandle theTE)
- {
- Point bottomLeft; //could be topleft, or whatever you want
-
- bottomLeft=TEGetPoint(pos,theTE);
-
- r.right=bottomLeft.h+(r.right-r.left);
- r.top=bottomLeft.v-(r.bottom-r.top);
- r.left=bottomLeft.h;
- r.bottom=bottomLeft.v;
-
- DrawPicture(pic,&r);
- }
-
- *end*
-
- I'll leave selection and hiliting as an exercise for the reader.
-
- Thereotically, it should be possible to kludge up TextEdit to the point
- where it would treat pictures as if they were actually letters (rather big
- letters, but letters just the same). That's what the width and word break
- hooks are for, after all. However, this would be a lot of Work, and I've
- never seen it done. One is lead to believe that it's less work to create
- an improved version of TextEdit from the ground up with picture support.
- One could probably modify WASTE for this purpose, since the source is
- available.
-
- 6.4) Q: I have all this money, and I want to get rid of it. How do I
- edit more than 32k of styled text now?
-
- A: There are at least two solutions.
-
- 1) The Galaxy application framework comes with a styled text editting
- engine which does more than 32k of text. It also happens to support
- cross-platform application development. Pricing starts at $10000.
- <galaxy@visix.com>
-
- 2) DataPak has a library called "PAIGE" in the works, and you can
- buy a late beta of it. It is written to be customizable to any extent,
- and you can do _anything_ in it (want quicktime movies that play and
- flow with the text while editting? Three pages of code; you can adapt
- their picture sample code.) Available for Mac, Windows and Power Mac.
- Pricing at $5000 ($25000 for source code) - it might be cheaper if
- you talk to them.
-
- *7* Communications and Networking
-
- 7.1) Q: How do I get at the serial ports?
-
- A: You call OpenDriver for the names "\p.AOut" and "\p.AIn" to get at
- the modem port, and "\p.BOut" and "\p.BIn" for the printer port. The
- function RAMSDOpen was designed for the original Mac with 128 kB of
- memory and 64 kB of ROM, and has been extinct for several years.
-
- However, many users use their serial ports for MIDI, LocalTalk, graphic
- tablets, or what have you and have installed an additional serial port
- card to get more ports. What you SHOULD do as a good application is to
- use the Comm Toolbox Resource Manager to search for serial resources;
- this requires that the Comms Toolbox is present (true on earlier System
- 6 with an INIT, on later System 6 and System 7 always, as well as on
- A/UX) and that you have initialized the comms resource manager. The
- exact code follows (adapted from Inside Mac Comms Toolbox):
-
- *code*
- #include <CommResources.h>
- OSErr
- FindPorts ( Handle * portOutNames , Handle * portInNames , Handle * names
- , Handle * iconHandles ) {
-
- OSErr ret = noErr ;
- short old = 0 ;
- CRMRec theCRMRec , * found ;
- CRMSerialRecord * serial ;
-
- * portOutNames = NewHandle ( 0L ) ;
- * portInNames = NewHandle ( 0L ) ;
- * names = NewHandle ( 0L ) ;
- * iconHandles = NewHandle ( 0L ) ;
- while ( ! ret ) {
- theCRMRec . crmDeviceType = crmSerialDevice ;
- theCRMRec . crmDeviceID = old ;
- found = ( CRMRec * ) CRMSearch ( ( QElementPtr ) & theCRMRec ) ;
- if ( found ) {
- serial = ( CRMSerialRecord * ) found -> crmAttributes ;
- old = found -> crmDeviceID ;
- PtrAndHand ( & serial -> outputDriverName , * portOutNames ,
- sizeof ( serial -> outputDriverName ) ) ;
- PtrAndHand ( & serial -> inputDriverName , * portInNames ,
- sizeof ( serial -> inputDriverName ) ) ;
- PtrAndHand ( & serial -> name , * names ,
- sizeof ( serial -> name ) ) ;
- PtrAndHand ( & serial -> deviceIcon , * iconHandles ,
- sizeof ( serial -> deviceIcon ) ) ;
- } else {
- break ;
- }
- }
- return err ;
- }
- *end*
-
- This will create four handles with the driver names, device names and
- driver icon handles for all of the available serial devices. Then let
- the user choose with a pop-up menu or scrolling list, and save the
- choice in your settings file.
-
- You can use OpenDriver, SetReset, SetHShake, SetSetBuf, SerGetBuf and
- the other Serial Manager functions on these drivers. To write to the
- serial port, use FSWrite for synchronous writes that wait until all is
- written, or PBWrite asynchronously for queuing up data that is supposed
- to go out but you don't want to wait for it. At least once each time
- through your event loop, you should call SerGetBuf on the in driver
- reference number you got from OpenDriver, and call FSRead for that many
- bytes - neither more nor less.
-
- If you are REALLY interested in doing the right thing, you will use the
- Communications Toolbox Connection Manager instead; this will give you
- access to modems, direct lines, and networks of various kinds using the
- same API! Great for stuff like BBSes that may be on a network as well
- etc. The Comms Toolbox also priovides modularized terminal emulation
- and file transfer tools, although the Apple-suplied VT102 tool is pretty
- lame, as is the VT102 mode of the VT320 tool.
-
- 7.2) Q: Where is a Berkley sockets library for the Mac?
-
- A: There are some problems with that. MacTCP, the Mac Toolbox
- implementation of TCP/IP, doesn't have an API that looks at all like
- Berkley sockets. For instance, there is ONE paramater-block call to do
- a combined listen()/accept()/bind() - sort of. I have heard that there
- may be a socket library available by ftp from MIT but haven't seen it
- myself.
-
- There is also a pretty good C++ TCP implementation called GUSI which is
- easily handled, and it also is callable from C using the Berkley socket
- API. Apart from TCP, it also handles "standard" Mac network protocols
- such as ADSP. The big disadvantage is that it is currently only
- implemented for MPW. The ftp site is nic.switch.ch,
- software/mac/src/mpw_c.
-
- I can also recommend the Communications Toolbox; for the price of using
- an API that is a bigger pain in the ass than using Windoze, you get the
- benefit of being able to use any kind of connection (TCP tools are
- available).
-
- Novell and Wollogong offer commercial socket-like libraries.
-
- 7.3) Q: Where do I find MacTCP?
-
- A: You can buy the MacTCP developers kit from APDA. It is also
- available on E T O, and if you want saner headers than those, try ftp to
- seeding.apple.com. MacTCP (the control panel) is included with System
- 7.5 and above.
-
- 7.4) Q: I'm trying to write to the serial port. It works fine on the
- following Machines, Quadra700, IIFX, Powerbook 170, Quadra 840av, but
- freezes on the Duo 230 and 280c.
-
- A: You need to call SerHShake. Otherwise you get screwed on some
- machines without a hardware handshaking cable because the port default to
- hardware handshaking.
-
- --------------------comp.sys.mac.programmer.info---------------------
- comp.sys.mac.programmer.info is primarily for distributing FAQs,
- tutorials, news, and similar documents related to programming the
- Macintosh. To post, email csmp_info@xplain.com
- -----------------------about MacTech Magazine----------------------
- PO Box 250055, Los Angeles, CA 90025, 310-575-4343, Fax:310-575-0925
- For more info, anonymous ftp to ftp.netcom.com and cd to /pub/xplain
- or email to the following @xplain.com : custservice, editorial,
- adsales, marketing, accounting, pressreleases, progchallenge,
- publisher, info
-