HYPERCARD IIGS 1.1 ERS c 1991-92 Apple Computer, Inc. All Rights Reserved Summary of HyperCard IIGS Version 1.1 Version 1.1 is an enhanced version of HyperCard IIGS version 1.0. As such, it includes all the features of HyperCard IIGS version 1.0 (referred to hereafter as version 1.0) as well as new features specific to version 1.1. Stacks created with version 1.0 are 100% compatible with version 1.1. Stacks created with the later version will continue to function with version 1.0 provided the stacks do not take advantage of features specific to version 1.1. Stacks that use the new HyperTalk features of 1.1 will generate HyperTalk errors if run under version 1.0. HyperCard IIgs 1.1 is designed to function with the same memory requirements as version 1.0. It requires an Apple IIGS with at least 1.5 megabytes of memory and a hard disk. Version 1.1 is System Software 6.0 aware and takes advantage of several new system software features. Version 1.1 will continue to run with System Software 5.0.4 as did HyperCard IIgs version 1.0. The new features of version 1.1 are designed to provide easier access to commonly used scripting techniques, implement the most useful/practical of the Macintosh HyperCard 2.1 features, provide a further implementation of color, and take advantage of new features in System Software. Bugs fixed in version 1.1 consist of all known crashing bugs as well as any bugs fixable within the scope of the 1.1 release. Version 1.1 Features This section describes all the new features of HyperCard IIgs 1.1 as well as comparing them to similar or identical features of Macintosh HyperCard 2.0/2.1. The list below is comprised of visual changes as well as discernible feature changes. It does not include changes such as speed enhancements or bug fixes which are included in a separate section. New property - "ItemDelimiter" This new property allows the scripter to define any single character as the delimiter character used to separate items in HyperTalk containers. For example, the scripter wishes to locate the filename from within a container that contains a complete pathname. Using version 1.1 and the itemDelimiter property, the scripter can do this: Variable "bucket" contains: :Barney:HyperCard:Stacks:MyOwnStack The user executes the following script: set the itemDelimiter to colon put last item of bucket Version 1.1 responds with: MyOwnStack The itemDelimiter property resets to the comma character at idle time so as not to affect compatibility with stacks that assume the itemDelimiter character is always a comma. This property is identical to HyperCard 2.1. New constants - "Comma" and "Colon" Version 1.1 contains two new HyperTalk constants. They are "colon" and "comma." These constants are designed to compliment the new itemDelimiter property. The user can now script: Set the itemDelimiter to colon or Set the itemDelimiter to comma Instead of: Set the itemDelimiter to ":" or Set the itemDelimiter to "," Note that the scripter is not restricted to using these constants and can use any HyperTalk character or expression to define the itemDelimiter character. Feature enhancement - "Compact Stack" Compacting a stack with free space in the resource fork caused by adding and deleting resources will now compact the resource fork as well as the data fork when the user chooses the Compact Stack menu item if: (a) the user holds down the option key, (b) the free space is > 50K, or (c) the free space is > 10% of the resource fork size. Command enhancement - "Ask" The "Ask" command has been enhanced to return "Cancel" if the user clicks the cancel button in addition to returning empty in the variable "it." The user can now script: ask "Please enter your name:" if the result is not "Cancel" then put it into userName end if Property change - "Rect, top, topLeft, location" The rect property of windows has been altered to be compatible with Macintosh HyperCard. HyperCard IIGS 1.0 would return a rect with the top left corner starting at the top left of the window frame. HyperCard IIgs 1.1 and all versions of Macintosh HyperCard return the top left corner of the content region. The same applies when setting the top, location, or topLeft of a window. The coordinates specified define the top left of the content region. Scripts from HyperCard IIGS 1.0 that specifically set a window to a certain location will cause the window to appear six pixels higher than it did running under HyperCard IIgs 1.0. This can be easily changed in the particular script. New property - "BackColor" A new property named "BackColor" has been added to fields and buttons. This property determines the background color of a button or field. HyperCard IIGS 1.0 is restricted to white backgrounds. The user can access this new property with the following: set the backColor of button 1 to 15 or set the backcolor of last field to 5 The backColor property is limited to an integer between 1 and 16 representing one of the sixteen colors available to user on that particular card/background. This property can also be accessed and changed from the revised object color dialog boxes. Changed dialog boxes - "Field Colors" and "Button Colors" The dialog boxes which allow the user to view and modify the color attributes of buttons and fields have been altered significantly. Included on the next page are screenshots of the new dialog boxes. Open File "HCGS.1" to see Figure 1 - HyperCard IIGS Field Colors Dialog Open File "HCGS.2" to see Figure 2 - HyperCard IIGS Button Colors Dialog Feature Enhancement - "Transparency" The new backColor property interacts with transparent buttons and fields to provide "tinted" buttons/fields similar to a stained glass effect. Setting the backColor of a transparent button or field causes the background of the part to be translucent, allowing objects behind the part to show through to the foreground. The choice of backColor determines how the objects underneath show through and how they are tinted. Transparent objects created with version 1.0 always have a backColor of white which is not affected by this feature. Transparent objects with a white background color will function identically to version 1.0. New Functions - "ClickLine" and "ClickChunk" Version 1.1 contains two new functions that allow the scripter to easily determine where in a particular field a user clicked. Syntax for the clickLine, clickChunk functions: put the clickLine put the clickChunk Or put clickLine() put clickChunk() ClickLine returns the line clicked in this format: line 3 of card field 1 ClickChunk returns a chunk expression defining the text clicked on in this form: char 5 to 9 of bkgnd field 6 ClickLine returns the line clicked relative to the actual text of the field, not the way the text is word wrapped. Therefore, a user can click on the text on the second line of a field and have line one returned since the first line of the field was long enough to wrap to the second display line. These functions are identical in implementation to these functions in Macintosh HyperCard 2.0/2.1. System Software 6.0 support HyperCard IIgs 1.1 contains several features specific to the 6.0 environment. If running under System Software 5.0.4, these features will not be available. Detect disk insertions Version 1.1 will now detect disk insertions and respond appropriately at idle time. If the disk is unreadable, a dialog box will be displayed asking the user if they wish to format the disk. Launching under System Software 6.0 HyperCard IIgs 1.1 will not drop out of the SHR screen while launching, executing another GS/OS application, or quitting to the Finder. Finder support Version 1.1 contains Finder "info" resources containing icon, version, and copyright information as well as document types and paths. Command enhancement - "Play" The Play" command has been enhanced to work in conjunction with the new 6.0 Sound Control Panel. If 6.0 is in use and the user attempts to play a sound that is not present in the current resource heirarchy, version 1.1 will query the Sound Control Panel to determine if a sound with that name exists in the Sounds folder of the boot disk. If it does, version 1.1 will play the sound just as if it was present in a resource. This process will be transparent to the end user. XWindows HyperCard IIgs 1.1 implements a subset of the XWindow concept from Macintosh HyperCard 2.0/2.1. Certain concepts such as those dealing with an externally based script editor as in 2.0/2.1 are not implemented. The list below details the XWindow implementation of HyperCard IIgs version 1.1. HyperTalk Extensions HyperCard IIgs 1.1 HyperTalk has been extended to include support for moving, hiding, showing, and otherwise manipulating XWindows as easily as the built-in windows such as the Tool, Pattern, and Go palettes. In addition, HyperTalk support for the built-in windows is improved and expanded. All the original methods of dealing with windows remain intact and unchanged. New Method of Referencing Windows - by Name, Number, or Ordinal. Version 1.1 now supports referencing windows, both built-in and external, in several new ways. These new ways of referencing the windows are compatible with 2.0/2.1. Referencing a window in HyperCard IIGS 1.0/HyperCard 1.2.5 was restricted to this: show tool window Although this still functions, it is now possible to reference a window in any one of the following methods: show tool window hide window tool show window "tool" close window "Fred" <---- Assuming there is a window named "Fred" set the location of first window to 50,50 get the visible of sixth window show last window show window 3 show window id 69341 at 50,30 hide any window All of the existing commands and functions dealing with windows as well as all new commands and functions now support this method of referencing windows. Note that only the built-in windows (Tool, Pattern, Card, and Go) can be referenced in the old form of " window." Open File "HCGS.3" to see Figure 3 - HyperCard IIGS Windows New Function - "windows" Version 1.1 implements a new function which returns a return-delimited list of all windows currently available. This is 2.0/2.1 compatible. A typical result of this function is below: Message Home <------ The name of the card window is the current stack. Pattern Tool Go Extension to Existing Function - "number of windows" In addition to being able to determine the number of cards, bkgnds, parts, etc. version 1.1 can now report the number of available windows. This is 2.0/2.1 compatible. This number is the number of HyperCard windows, it does not include DA windows or any others. The user can script: put the number of windows HyperCard IIgs 1.1 responds with: 5 Extension to Existing Command "set" Version 1.1 implements all of the properties previously supported for built-in windows for external windows as well. This includes location, topLeft, location, visible, etc. This is identical to 2.0/2.1. Extension to Existing Command "Dial with Modem" Executing the dial with modem command now attempts to dial the phone with a serial or modem card if the built-in modem port is disabled. The logic for the dial command is this: 1) Look for the modem port, if slot 2 is set to "modem", send the modem dialing string out the built-in port. 2) If the built-in modem port is disabled, look for a character device in slot 2. If found, send the modem dialing string to that card. 3) If the built-in port is disabled and slot 2 does not contain a character device, scan for a character device beginning at slot 1 and send the dialing command to the first one found. Extension to Existing Command "Play" Version 1.1 will now play any sound in the Sounds folder when using System 6.0. If a play command is given using a sound that is not in the current resource heirarchy, HyperCard IIGS v.1.1 will call the Sound CDEV of System 6.0 to determine whether a sound of that name exists in the folder. If so, it is loaded and used just as any sound resource would be. New Window Property - "Name" Version 1.1 now supports the read-only window property "name." This allows the user to determine a window name. Commonly used when the user only knows the window number. The user can script: put the name of HyperCard IIgs version 1.1 responds with something like: Pattern New Window Property - "Number" Version 1.1 now supports the read-only window property "number." This allows the user to determine a window number. Commonly used when the user only knows the window name. The user can script: put the number of HyperCard IIgs version 1.1 responds with something like: 5 New Window Property - "ID" Version 1.1 now supports the read-only window property "ID." This allows the user to determine the ID of a given window. There are several things to note regarding window IDs. IDs for the built-in windows are assigned when HyperCard IIgs starts up and will not change. XWindow IDs are assigned when the window is created and released when the window is closed. Window IDs may vary for any window from machine to machine. The user can script: put the id of HyperCard IIgs version 1.1 responds with something like: 69341 Extension to Existing Command - "Close" The Close command has been extended to included support for closing external windows as well as closing text files and printing jobs. Only external windows may be closed. Attempting to close a built-in window will result in the error message "Can't close that window." Syntax for closing external windows is: close The Close command supports all forms of window references and is HyperCard 2.0/2.1 compatible. Extensions to the XCMD Interface Version 1.1 contains several new callbacks dealing with the implementation of XWindows as well as related utility callbacks. These callbacks are accessed with a set of new HyperXCMD interfaces files providing access to the callbacks from Pascal, C, and Assembly Language. As many of the new callbacks as possible are modeled after their Macintosh HyperCard 2.0/2.1 counterparts within the scope of our XWindow implementation. Following is a list and general description of the new callbacks. New Callback - "StrToRect" PROCEDURE StrToRect(str: Str255; VAR rct: Rect); Inputs str String containing text to convert to a rect Outputs rct Rect containing specified coordinates This callback converts a Pascal string containing alphanumeric characters delimited by commas designating a rectangle to a true, four integer rect record. Pascal interface is above. New Callback - "RectToStr" PROCEDURE RectToStr(rct: Rect; VAR str: Str255); Inputs rct Rect containing coordinates to convert Outputs str String containing alphanumeric representation of rect The complement of StrToRect, this callback converts a rect record back to a string. New Callback - "StrToPoint" PROCEDURE StrToPoint(str: Str255; VAR pt: Point); Inputs str String containing text to convert to a point Outputs pt Point containing specified coordinates This callback converts a Pascal string containing alphanumeric characters delimited by commas designating a point to a true, two integer point record. New Callback - "PointToStr" PROCEDURE PointToStr(pt: Point; VAR str: Str255); Inputs pt Point containing coordinates to convert Outputs str String containing alphanumeric representation of point The complement of StrToPoint, this callback converts a point record back to a string. New Callback - "NewXWindow" FUNCTION NewXWindow(boundsRect: Rect; windName: Str31 visible: BOOLEAN, windowStyle: INTEGER): WindowPtr; Inputs boundsRect Rect for newly created window windName Name used for HyperTalk references to the window and, optionally, displayed depending on the window type. visible Whether to create the new window initially visible windowStyle Style of the XWindow. 0 = windoid, 1 = rectangle, 2 = shadow, 3 = dialog box. Outputs windowPtr Pointer to a standard window record defining the new window. This callback allows an external command to create and register a window. In addition to creating the window, HyperCard also adds the new window to its internal list of external windows and keeps the XCMD in memory after it terminates so that it can respond to events concerning the window. The windows created are standard IIGS windows and can be manipulated in the same way as a window created from within a stand- alone application with two exceptions. (1) The XCMD must never call the toolbox routine CloseWindow on the XWindow. External commands MUST use the CloseXWindow callback to dispose of a window. (2) External commands must not alter the wRefCon field of the window record. This field is reserved for HyperCard. External commands needing to save or restore data associated with a particular window can use the SetXWindowValue and GetXWindowValue callbacks. New Callback - "CloseXWindow" PROCEDURE CloseXWindow(window: WindowPtr); Inputs window Pointer to a window record designating the window to be closed Outputs This callback send an xCloseEvt to the owner external, closes the window, and disposes of all memory HyperCard has allocated for the window. XCMDs that create windows are responsible for disposing of any memory they have allocated when they receive an xCloseEvt. New Callback - "SetXWindowValue" PROCEDURE SetXWindowValue(window: WindowPtr; customValue: LongInt); Inputs window Pointer to window associated with the value customValue Four byte value containing data to store with the window Outputs This callback allows an external command to store a four byte value along with any XWindow. This value will typically be a pointer or handle to a block of memory containing information the external command wishes to keep intact regarding the contents of the XWindow. Because external commands can execute and terminate many times in response to events, data cannot be kept in standard variables. New Callback - "GetXWindowValue" FUNCTION GetXWindowValue(window: WindowPtr): LongInt; Inputs window Pointer to window associated with the value Outputs customValue Four byte value containing the data stored with the window New Callback - "HideHCPalettes" PROCEDURE HideHCPalettes; Inputs Outputs This callback hides all currently visible windows, both built-in and XWindows. Additionally, it stores internally which windows were visible at the time it was called so that a subsequent call to ShowHCPalettes will display the same set of windows. This callback is commonly used when an external command needs to clear the screen such as when using the video overlay card. New Callback - "ShowHCPalettes" PROCEDURE ShowHCPalettes; Inputs Outputs This callback displays all windows hidden with the HideHCPalettes callback. If HideHCPalettes was not called, this callback does not display any windows. New Callback - "SetXWIdleTime" PROCEDURE SetXWIdleTime(window: WindowPtr; interval: LongInt); Inputs window Pointer to owner window interval Length (in ticks) between idle events Outputs External commands that create XWindows will normally receive xIdleEvt events periodically. Because HyperCard IIgs must spend time generating and sending these events, an external command can tell HyperCard IIgs how often it wants these events. Setting the interval to zero will cause HyperCard IIgs to not send any idle events. Setting the interval to a very small number will cause HyperCard IIgs to send xIdleEvt events as quickly as possible. Because of the overhead involved in generating and sending an event, an external command should not depend on receiving xIdleEvt events at exact intervals. In addition, xIdleEvt events are only sent at HyperCard IIgs idle time and may be postponed for lengthy intervals while scripts are running. New Callback - "XWAllowReEntrancy" PROCEDURE XWAllowReEntrancy(window: WindowPtr; allowSysEvts: BOOLEAN; allowHCEvts: BOOLEAN); Inputs window Pointer to owner window allowSysEvts Whether to allow reentrant system events allowHCEvts Whether to allow reentrant HyperCard events External commands have control over whether to allow reentrant events. That is, whether to allow an event to be sent to an external that is still executing in response to another event. The default is not to allow recursive calls to an external command. Events Dealing with XWindows External commands that create XWindows are kept in memory after they terminate so that they may be called in response to events concerning the XWindows they created. An XCMD can determine whether it has been called from a script or the message box or in response to an event by checking the paramCount field of the parameter block. If this value is negative, the XCMD has been called in response to an event. The following Pascal code fragment illustrates this concept. BEGIN {SampleXCMD} { If the paramCount is negative, we have been called in response to an event } IF paramPtr^.paramCount < 0 THEN BEGIN HandleEvents; EXIT(SampleXCMD); END; {if} { program continues... } The Events an External Command Can Receive The following is a list of all events an external command can receive along with a description of the event. Some of the events are standard system events while others are generated by HyperCard. HyperCard Event - "xOpenEvt" xOpenEvt is the first event sent to any XWindow. This event is sent to any new XWindows immediately after the parent XCMD terminates. No events will be sent to an XWindow before this event. HyperCard Event - "xCloseEvt" This is HyperCard's method of notifying the XCMD that a window that it created is being closed. At the time of the event, the window is still present and visible. The window will be closed immediately following the event. The owner XCMD should not call CloseXWindow or close the window in any other means when it receives this event. HyperCard will handle closing the window when the XCMD returns control. XCMDs will typically use this event to dispose of any additional memory they have allocated for the XWindow. HyperCard Event - "xHidePalettesEvt" This event is sent to all XWindows when an external command executes the HideHCPalettes callback. An external command may wish to deallocate memory or take other action when the user hides their window in this manner. HyperCard Event - "xShowPalettesEvt" This event is sent to all XWindows when an external command executes the ShowHCPalettes callback. An external command may need to prepare itself to handle update events, etc, if it has deallocated the memory when being hidden. HyperCard Event - "xCursorWith" This event is sent to an XWindow when the mousecursor enters therect of their window. The owner XCMD can then set the cursor to a custom shape if desired using the GS Toolbox. If they do not wish to handle the changing of the cursor shape, the external command should set the passFlag of the parameter block to TRUE so that HyperCard IIgs will handle the cursor itself. Since this message is sent repeatedly, as long as the cursor is within the window, the XCMD should determine whether it has already changed the cursor shape before doing so again to avoid flickering of the cursor and slowing down the CPU. System Event - "UpdateEvt" This event indicates the all or part of the specified window needs to be updated. It is the responsibilty of the owner external of each window to handle redrawing the contents of the window in response to this event. System Event - "MouseDownEvt" The user has pressed the mouse button while the mouse pointer was within an external window. The external command will commonly handle tracking the mouse click manually, or call FindControl and have the control manager do so. System Event - "NullEvt" This event will only be sent if the XCMD/XFCN has enabled idle events by setting the idle interval to a value other than zero with the SetXWIdleTime callback. See the description of this callback above for more information regarding using null events. Care and Feeding of Your New XWindow An XCMD that creates an XWindow is treated differently from an XCMD that doesn't. The following section details differences the XCMD author needs to be aware of. 1) XCMDs that create external windows are kept in memory as long as any XWindows that XCMD created are open. 2) XWindow XCMDs should not assume that they own only one window. Subsequent calls to the XCMD may create additional windows. The XCMD should use the windowPtr passed and the GetXWindowValue and SetXWindowValue calls to determine the appropriate action to take in response to a particular event. 3) The same Memory Manager user ID is passed to an XWindow owner XCMD as long as any of the XWindows the XCMD owns are open. The XCMD should not perform a DisposeAll on its memory ID because other windows that the XCMD is responsible for could still be open. 4) The wFrameBits field of an XWindow is inaccessible to an XCMD, XCMDs should not attempt to modify the standard window attributes of a windoid. 5) XWindow owners that close all of their XWindows will be disposed of when there are no more pending calls to them. Major Bug Fixes in HyperCard IIgs 1.1 This section lists the bugs present in version 1.0 that are addressed in HyperCard IIgs 1.1. This is not a complete list of all bug fixes but rather a guide to major differences in version 1.0 and version 1.1 that a user could encounter. Project Area Bug Description Scope of Bug Fix Memory Mgmt. Last sound played is left in Version 1.1 now memory locked and unpurgeable cleans up until another sound is played sounds at idle at which point that sound is time. left locked and unpurgeable. Externals If an XCMD is passed an argument Added error check that necessitates leaving the and recovery for this stack which contains the XCMD, situation. version 1.0 would crash. Interpreter Internal hash values were not Localized assembly being generated correctly, fix. slowing HyperTalk execution speed. Read Command Read command could orphan a 4K Rewrite of Read handle in out of memory conditions. command. Command is also wasteful of memory and inefficient. Clipboard Version 1.0 was using an Change to using undocumented scrap type documented type. for palettes. Cursors Several cases where version Modified problem 1.0 wasn't restoring the cursor routines to shape correctly. save/restore cursor correctly. Edit Menu Edit Menu IDs off-by-one for DAs. Modified to use Copy would be Cut, Paste would be correct values. Copy, etc. HyperTalk Saving a copy of a stack from Now save the wet HyperTalk while in the Paint paint on the correct tools with wet paint present card before the would result in the paint being copy. saved on the first card of the source stack being copied. Paint Tools Fonts loaded or generated when Correctly set fonts using paint text were not as purgeable after released. use. Visual Effects Using visual effect dissolve No longer crashes. with a completely obscured card window causes a crash. HyperTalk The Dial command would not Version 1.1 now utilize a modem or serial card. looks for a character device, preferrably in slot 2, if the built-in modem port is overridden. Memory Mgmt. Internal PLib routine that copies Patched out PLIB blocks of memory contained a bug routine with fixed that would overwrite a word of version. memory if the area being copied was an odd number of bytes and crossed a bank. HyperTalk Using the "write at" syntax of the This 1.0 bug is fixed write command to write at a point within Version 1.1 beyond the eof of a file would not so that it zeros clear the data between the the data. previous eof and the new mark when writing to an AppleShare or HFS volume. Screen Update Scrolling a field then moving Fixed. windows over top of it would cause the field to refresh incorrectly. Renaming a Stack Changing the case of a character Fixed. of the name of a stack would not rename the stack. HyperTalk Opening a ProDOS 8 application Now correctly using "with"a document was incorrectly slashes. using colons to specify the document path. HyperTalk Executing an invalid callback Now call number would execute a brk SysFailMgr. instruction, exiting to the debugger or monitor. Speed Improvements Listed below are specific areas that have been improved as far as execution speed. While many improvements within the program as far as overall speed and responsiveness have been implemented, this section details speed improvements local to a specific area. Project Area Description of Speed Improvement Icon Picker Time to display the icon picker when choosing an icon for a button has been drastically reduced. Most apparent when displaying many icons as in the Button Ideas stack. Interpreter (Also listed in bug fixes.) Internal hash values were being generated incorrectly, reducing execution speed. Hash values now generated correctly. Interpreter Internal interpreter routines rewritten in assembly. Graphics Internal picture unpacking algorithm rewritten in assembly for improved speed. Button Hiliting Version 1.0 writes the hilite of auto-hilite buttons to disk every time they are clicked regardless of whether the button actually changed state. HyperCard IIGS version 1.1 only writes auto-hilite buttons to disk if the state actually changes, saving a disk access for every mouse click. Button/Fields Button and field drawing code is now all assembly. Code Size/Memory Usage HyperCard IIgs version 1.1 is smaller in code size than HyperCard IIGS version 1.0 even with the addition of the new features because version 1.1 is compiled with a later version of the Pascal IIGS compiler which generates smaller/faster code and because of routines rewritten in assembly which is inherently smaller than most compiled Pascal code as well as more efficient. Optimizing of Pascal code has also resulted in smaller code size and memory usage. Version 1.1 manages memory more efficiently and will work better than version 1.0 in low memory situations because of the memory management bugs fixed as noted above and because of reorganized global variable usage and new code segmentation used throughout the program. Sample XWindow Code (Pascal) Included below is the source code for a sample XCMD. This is a much simplified version of the Picture XCMD that appears in the Scripter's Tools stack. The complete source to that XCMD is also available as sample source code. {--------------------------------------------------------------------- file Picture.p Part of HyperCard IIGS 1.1 Copyright c 1991 Apple Computer, Inc. This XCMD has the following syntax: Picture resName [, windowStyle] INPUTS: resName Name of pict resource to draw in the window windowStyle (Optional) Defines the appearance of the picture window. Can be rect, rectangle, shadow, or dialog. Any other text or not specified results in a standard windoid. This XCMD creates and maintains an XWindow. The XWindow contains a picture retrieved from a resource with a name specified by the caller. If the resource cannot be found, the XWindow is still created and the text "Unable to draw picture." is displayed. Author: Darin Acquistapace Created: 5/22/91 Modified: See Mod History Below Modification History: 5/22/91 - New today. 5/30/91- Updated for revised XWindow callbacks 6/04/91 - Added HyperCard version check. 6/12/91 - Changed from wInContent to mouseDownEvt for mouseDowns. 6/14/91 - Added XWAllowReEntrancy for release with 1.1d10. 6/24/91 - Modified to work with "real" custom defProc XWindows. 6/31/91 - Added support for xCursorWithin message. 8/19/91 - Added support for multiple window styles. ---------------------------------------------------------------------} UNIT DummyUnit; {$Z+ } {$N+ } INTERFACE USES Types, Memory, MiscTool, GSOS, QuickDraw, Resources, QDAux, Events, Controls, Windows, Menus, HyperXCMD; PROCEDURE EntryPoint(paramPtr: XCmdPtr); IMPLEMENTATION PROCEDURE XPicture(paramPtr: XCmdPtr); FORWARD; PROCEDURE EntryPoint(paramPtr: XCmdPtr); BEGIN XPicture(paramPtr); END; PROCEDURE XPicture(paramPtr: XCmdPtr); CONST ScriptErrStr = 'Can''t understand arguments of XCMD Picture.'; CopyrightStr = 'Picture XCMD v1.0d7" & return & "by Darin Acquistapace, 5/22/91" & return & "c 1991 Apple Computer, Inc.'; HelpStr = 'FORM: Picture ResourceName [, windowStyle]'; WrongVersionStr = 'Picture XCMD requires HyperCard IIGS 1.1'; CreateErrStr = 'Unable to create window'; CantDrawStr = 'Unable to draw picture.'; RectStr1 = 'rect'; RectStr2 = 'rectangle'; ShadowStr = 'shadow'; DialogStr = 'dialog'; VAR pCount: INTEGER; windowStyle: INTEGER; sampleXWindow: WindowPtr; windRect: Rect; str: Str255; styleStr: Str255; PROCEDURE HTError; { Puts the specified string into the result and terminates with a HyperTalk error} BEGIN ParamPtr^.ReturnValue := PasToZero(ScriptErrStr); ParamPtr^.ReturnStat := 1; EXIT(XPicture); END; {HTError} PROCEDURE ReturnResult(str: Str255); { Puts the specified string into the result and terminates } BEGIN ParamPtr^.ReturnValue := PasToZero(str); EXIT(XPicture); END; {ReturnResult} PROCEDURE CommandInfo(Msg : str255); { Puts the specified string into a dialog box and terminates } BEGIN SendHCmessage(concat('answer "', Msg, '"')); EXIT(XPicture); END; {CommandInfo} PROCEDURE UpdatePicture(whichWindow: WindowPtr); { This draws our picture into the XWindow } VAR myPictureHndl: LongInt; destRect: Rect; BEGIN { Retrieve the handle to our picture } myPictureHndl := GetXWindowValue(whichWindow); { Display message if unable to load the picture } IF myPictureHndl = 0 THEN BEGIN WITH whichWindow^.portRect DO SetRect(destRect, 0, 0, right, bottom); EraseRect(destRect); MoveTo(10,13); DrawString(CantDrawStr); EXIT(UpdatePicture); END; {if} { Draw picture in upper left corner } WITH PicHndl(myPictureHndl)^^.picFrame DO SetRect(destRect, 0, 0, right-left, bottom-top); DrawPicture(PicHndl(myPictureHndl), destRect); END; {UpdatePicture} PROCEDURE CleanUpMemory(whichWindow: WindowPtr); { Remove our picture from memory when we close } VAR myPictureHndl: LongInt; BEGIN myPictureHndl := GetXWindowValue(whichWindow); IF myPictureHndl = 0 THEN EXIT(CleanUpMemory); KillPicture(PicHndl(myPictureHndl)); SetXWindowValue(whichWindow, 0); { Just to be safe - clear this value } END; {CleanUpMemory} PROCEDURE HandleWindowClick(whichWindow: WindowPtr; ourEvent: EventRecord); { The user has clicked in our window, handle tracking the click } FUNCTION MouseUpInWindow: BOOLEAN; { Handle tracking a mouseClick in our window } VAR mouseLoc: Point; oldInWind: BOOLEAN; inWind: BOOLEAN; targetRect: Rect; BEGIN oldInWind := FALSE; inWind := TRUE; WITH whichWindow^.portRect DO SetRect(targetRect, 0, 0, right, bottom); REPEAT IF oldInWind <> inWind THEN BEGIN InvertRect(targetRect); oldInWind := inWind; END; {if} GetMouse(mouseLoc); inWind := PtInRect(mouseLoc, targetRect); UNTIL NOT Button(0); IF oldInWind THEN InvertRect(targetRect); {Turn off hilite} MouseUpInWindow := inWind; { Return whether mouseUp occurred in the rect } END; {MouseUpInWindow} BEGIN IF MouseUpInWindow THEN SendHCMessage('play "Harpsichord" tempo 400 "c d e"'); END; {HandleWindowClick} PROCEDURE HandleEvents; { Handle events specific to our XWindow } VAR myEventInfo: XWEventInfoPtr; window: WindowPtr; event: EventRecord; BEGIN myEventInfo := XWEventInfoPtr(paramPtr^.params[1]); window := myEventInfo^.eventWindow; event := myEventInfo^.event; CASE event.what OF xOpenEvt: XWAllowReEntrancy(window, TRUE, TRUE); updateEvt: UpdatePicture(window); mouseDownEvt: HandleWindowClick(window, event); xCloseEvt: CleanUpMemory(window); xCursorWithin: paramPtr^.passFlag := TRUE; { Let HC change our cursor } END; {case} END; {HandleEvents} PROCEDURE SetUpContents(resName: Str255); { Create the contents of our window } VAR myPictureHndl: PicHndl; homeFile: INTEGER; pictureID: LongInt; BEGIN IF NOT FindNamedResource(rPicture, resName, homeFile, pictureID) THEN EXIT(SetUpContents); Handle(myPictureHndl) := LoadResource(rPicture, pictureID); IF _toolErr <> 0 THEN EXIT(SetUpContents); DetachResource(rPicture, pictureID); IF _toolErr <> 0 THEN BEGIN ReleaseResource(3, rPicture, pictureID); EXIT(SetUpContents); END; {if} { Have HyperCard save handle to our picture resource } SetXWindowValue(sampleXWindow, LongInt(myPictureHndl)); END; {HandleEvents} FUNCTION CorrectVersion: BOOLEAN; { This returns true if the version of HyperCard is >= minVersion } CONST minVersion = '1.1'; VAR tempHandle: Handle; tempStr: Str255; BEGIN tempHandle := EvalExpr('the version'); ZeroToPas(tempHandle^, tempStr); IF temphandle <> NIL THEN DisposeHandle(tempHandle); CorrectVersion := tempStr >= minVersion; END; {CorrectVersion} BEGIN pCount := paramPtr^.paramCount; { If the paramCount is negative, we have been called in response to an event } IF pCount < 0 THEN BEGIN HandleEvents; EXIT(XPicture); END; {if} { Display help or copyright info in response to "?" or "!" } IF pCount >= 1 THEN BEGIN ZeroToPas(paramPtr^.params[1]^, str); IF str = '!' THEN CommandInfo(CopyrightStr); IF str = '?' THEN CommandInfo(HelpStr); END; {if} { We''ll take one or two parameters } IF (pCount < 1) OR (pCount > 2) THEN HTError; {Make sure we are running at least version 1.1 of HyperCard IIGS} IF NOT CorrectVersion THEN ReturnResult(WrongVersionStr); IF pCount = 1 THEN windowStyle := xWindoidStyle ELSE BEGIN ZeroToPas(paramPtr^.params[2]^, styleStr); IF StringEqual(styleStr, RectStr1) THEN windowStyle := xRectStyle ELSE IF StringEqual(styleStr, RectStr2) THEN windowStyle := xRectStyle ELSE IF StringEqual(styleStr, ShadowStr) THEN windowStyle := xShadowStyle ELSE IF StringEqual(styleStr, DialogStr) THEN windowStyle := xDialogStyle ELSE windowStyle := xWindoidStyle; END; {else} SetRect(windRect, 50, 76, 250, 140); sampleXWindow := NewXWindow(windRect, str, FALSE, windowStyle); IF sampleXWindow = NIL THEN ReturnResult(CreateErrStr); SetUpContents(str); { Create the contents for the window } ShowWindow(sampleXWindow); END; END. { of the dummy unit }