TweetFollow Us on Twitter

XCMD in App
Volume Number:9
Issue Number:7
Column Tag:C Workshop

XCMD’s in Standalone Applications

Here’s a way to write XCMD’s so they’re usable for more than HyperCard

By Gerry H. Kenner, Magna, Utah

Note: Source code files accompanying article are located on MacTech CD-ROM or source code disks.

About the author

Gerry Kenner is a professional electrical and computer engineering consultant, university researcher and sometimes writer who specializes in image analysis systems for investigative scientists.

INTRODUCTION

This paper shows how to access HyperCard XCMDs which have been incorporated into the resource file of a standalone application. This is done by creating a function named LoadXCMD which takes the name and parameters of an XCMD and provides glue code for accessing them. In addition, code is provided for responding to callbacks by the HyperCard utility functions.

HyperCard stacks are unequaled as dynamic front ends for interfacing with scientific instruments. Hypercard facilitates entering data and displaying results by using buttons and text fields. Elaborate front ends can be thrown together in a matter of hours and the resulting scripts can be altered within minutes when rapid changes in the interface are required.

One major problem with HyperCard stacks is the slow execution speed of the HyperTalk scripts. Fortunately, they can be speeded up by liberal use of XCMD’s and XFCN’s for time intensive operations.

A price is paid for these advantages. Most obvious is that HyperCard stacks can become very large. Another disadvantage is that they are susceptible to damage. One quickly learns to keep at least two back-up copies of working stacks. A more subtle problem is that of bullet-proofing large Hypercard programs so that the average technical person can run them.

Once the stacks become finalized, one alternative is to replace them with standalone applications developed using THINK C with objects. The THINK Class Libraries can be used to provide the replacement interface. The XCMD’a and XFCN’s could be modified into modules which could be called by the application or else incorporated directly using the system described in this paper. An application prototyper such as AppMaker or Marksman would be invaluable for this.

I obtained some insights on how to incorporate XCMD’s into standalone applications from a note in the October 1989 MacTutor by Peter B. Nagel of Denver, CO. With this information as a basis I proceeded to write the demo code published here.

Disclaimer

As in my previous articles I am only including the code necessary to understand the project. This code is enough for an intermediate programmer to fill in what is missing. Typically, I do not declare variables or state which header files must be included. A copy of the complete project is available on the MacTutor Disk.

STANDALONE APPLICATION

The standalone program passes the number 5 and the message “Return to application” to a modified version of Apple’s Flash XCMD demo which inverts the screen 5 times (flashes) and returns a message which is then displayed in a window.

The program requires two files, pTest and pXCMD. PTest is an entry file containing the main function which needs code for initializing the toolbox, creating a window, calling the XCMD and outputting the return value to the window. The XCMD function call is as follows.

/* 1 */

TempHdl = LoadXCMD(3, “pXFCN”, “5”, “Hello World!”);

Three is the number of parameters being passed, pXFCN is the name of the XCMD code resource, 5 is the number of beeps requested while “Hello World” is the string which will be returned by the XCMD. TempHdl points to the return string.

Although the memory allocated to TempHdl was assigned elsewhere, it must be deallocated with a call to DisposHandle.

The pXFCN.h file references HyperXcmd.h and declares prototypes of four functions. The function declarations are as follows.

/* 2 */

Handle LoadXCMD(short Count, ...);
void JumpToXCMD(XCmdPtr ParamPtr, Handle CodeAddr);
void SwitchXCMD(void);
char *StrCpy(char *s1, char *s2);

It also contains an enum list of Apple’s HyperCard request codes. Complete lists of these can be found in the pre 1988 HyperCard header files. To facilitate identification, I am including a partial list here.

enum {  
 xreqSendCardMessage = 1,
 xreqEvalExpr,
 xreqSendHCMessage = 5;
 xreqSendHCMessage = 8;
 
 ...

 xreqScanToReturn,
 xreqScanToZero = 39   // was suppose to be 29!  Oops!
};

The function LoadXCMD takes the parameters passed, converts them into XCMD readable form and then calls the code resource. The code is as follows.

/* 3 */

1. Handle LoadXCMD(short Count, ...)
2. {
3. void *ListPtr;
4. char *CharPtr;
5. Handle CodeAddr, TempHdl;
6. shorti, Err;
7. size_t Size;
 
8. Count = Count - 1;
9. ListPtr = &Count + 1;
10.CharPtr = *(*(char***)&ListPtr)++;
11.CtoPstr(CharPtr);
12.CodeAddr = GetNamedResource(‘XFCN’, CharPtr);
13.MoveHHi(CodeAddr);
14.HLock(CodeAddr);

15.ParamPtr = (XCmdPtr)NewPtr(128L);
16.ParamPtr->entryPoint = (Ptr)SwitchXCMD;

17.ParamPtr->paramCount = Count;
18.for (i = 0; i < ParamPtr->paramCount; ++i)
19.{
20.ParamPtr->params[i] = NewHandle(256);
21.HLock(ParamPtr->params[i]);
22.CharPtr = *(*(char***)&ListPtr)++;
23.strcpy((char*)*(ParamPtr->params[i]), CharPtr);
24.}
 
25.JumpToXCMD(ParamPtr, CodeAddr);
26.Size = strlen(*(ParamPtr->returnValue));
27.TempHdl = NewHandle((long)Size);
28.strcpy((char*)*TempHdl, 
 (char*)*(ParamPtr->returnValue));
29.HLock(TempHdl);
 
30.for (i = 0; i < ParamPtr->paramCount; ++i)
31.{
32.HUnlock(ParamPtr->params[i]);
33.DisposHandle(ParamPtr->params[i]);
34.}
35.HUnlock(CodeAddr);
36.HUnlock(ParamPtr->returnValue);
 
37.DisposHandle(ParamPtr->returnValue);
38.DisposPtr((XCmdPtr)ParamPtr);
39.ReleaseResource(CodeAddr);
 
40.return(TempHdl);
41.}

Instruction 8 retrieves the number of parameters passed. Instructions 9 through 12 get the name of the XCMD and load the resource code. The address of the XCMD is obtained by using GetResource to load the code resource into memory and get a handle to its location. Instruction 15 allocates memory for the XcmdBlock pointed to by ParamPtr. ParamPtr was declared as a global since it is used both here and by SwitchXCMD. Instruction 16 sets up the function SwitchXCMD as the entry point for HyperCard XCMD utility calls. Instructions 17 through 24 finish setting up the XcmdBlock for the XCMD call. Note that space was not allocated for returnValue even though the code disposes of a handle to this value before terminating. Variables were assigned to params[0] and params[1].

Instruction 25 calls the function JumpToXCMD which is an assembly lanquage glue routine for placing the address of the XCmdBlock on the stack and then jumping to the address of the XCMD (actually XFCN in this case). Instructions 26 through 29 prepare the contents of returnValue for passing back to the calling function. The final portion of the function disposes of the various handles and pointers created in the program. CodeAddr was disposed of with ReleaseResource.

After returning from JumpToXCMD, the function StrCpy was used to copy returnValue into a temporary string. StrCpy was used rather than the ANSI library routine strcpy to avoid the possibility of LoadSeg being called with attendent movement of memory. This is necessary because the compiler will not permit the locking of the handle returnValue, apparently because the handle was not created within the function.

Here is the code for JumpToXCMD.

/* 4 */

1. void JumpToXCMD(XCmdPtr ParamPtr, Handle CodeAddr)
2. {
3. asm
4. {
5. move.l ParamPtr(a6), -(a7)
6. move.l CodeAddr(a6), a0
7. move.l (a0), a0
8. jsr  (a0)
9. }
10.}

The address of the XCmdBlock is moved on to the stack in line 5 while the handle pointing to the code resource is moved into register A0, dereferenced twice and then jumped to in lines 6 to 8.

Remember that the address of the function SwitchXCmd was placed in the entryPoint field of the XCmdBlock. This is the code which is jumped to when HyperCard utility functions are called. It consists of a switch statement which identifies the code for each utility function. I am only going to show the code for PasToZero and SendHCMessage but the principal applies to accessing all the functions. The code itself is self-explanatory and doesn’t require a detailed explanation.

/* 5 */

void SwitchXCMD(void)
{
 WindowPtrTempWindow, OldPort;
 Handle TempHandle;
 long   TempLong;
 Str255 TempStr;
 Rect   TempRect;
 
 switch (ParamPtr->request)
 {
 case xreqZeroToPas:
 strcpy((char*)ParamPtr->inArgs[1], 
 (char*)ParamPtr->inArgs[0]);
 CtoPstr((char*)ParamPtr->inArgs[1]);
 break;
 
 case xreqSendHCMessage:
 GetPort(&OldPort);
 SetRect(&TempRect, 20, screenBits.bounds.bottom - 80, 
 480, screenBits.bounds.bottom - 20);
 TempWindow = NewWindow(0L, &TempRect, “\pHC Message”, 
 TRUE, plainDBox, (WindowPtr)-1L, TRUE, 0L);
 SetPort(TempWindow);
 MoveTo(10, 30);
 DrawString((char*)ParamPtr->inArgs[0]);
 Delay(90L, &TempLong);
 DisposeWindow(TempWindow);
 SetPort(OldPort);
 break;
 
 default:
 break;
 }
}

Writing to code for StrCpy is left as an exercise for the reader. My version is written in assembly lanquage.

THE XCMD (XFCN)

For completeness I have included a partial listing of CFlash, the modified XCMD which is called by pXFCN. This example uses the HyperCard utilites SendHCMessage and ZeroToPas. In addition it uses several Toolbox function calls and the C library call strcpy.

There is a problem with some of the C library calls. Functions which do not use globals referenced from A5 or A4 appear to work without problems. Thus, strcpy and strcat can be used. Routines such as atoi and atol which use globals will not run properly in the program as written and attempts to use them often result in crashs.

/* 6 */

 RememberA4();
 SetUpA4();
 
 HLock(paramPtr);
 paramPtr->returnValue = NewHandle(256L);
 StrPtr = (StringPtr)NewPtr(256L);
 
 ZeroToPas(paramPtr, (char*)*(paramPtr->params[0]), StrPtr);
 StringToNum(StrPtr, &TempLong);
 flashCount = (int)TempLong;
 
 GetPort(&port);
 for (again = 1; again <= flashCount; again++) 
 {
 InvertRect(&port->portRect);
 InvertRect(&port->portRect);
 }
 
 SendHCMessage(paramPtr, 
 (StringPtr) ”\pput \”This is a message\” into msg”);
 Delay(60L, &TempLong);
 
 strcpy((char*)*(paramPtr->returnValue), 
 (char*)*(paramPtr->params[1]));
 DisposPtr(StrPtr);
 RestoreA4();
 HUnlock(paramPtr);

ADDING XCMD CODE RESOURCES TO THE .RSRC FILE

This can be done directly in THINK C 5.0 by using the merge option when building the code resource. For other versions of C use ResEdit to add the files.

DISCUSSION

Initially I was disturbed to discover I could not use some of the C library routines in XCMD’s which I eventually planned to use in standalone applications. Upon reflection, combined with some insights gained while writing the programs for this article, I finally decided that for me at least the problem was minor, if not non-existent.

The insights referred to above were the discovery that the inclusion of atoi increased the size of the XCMD from 3k to 10k. This is catatrophic if one hopes to write a large program which includes perhaps 100 XCMD’s. It is a nuisance with smaller routines.

The reflection says that the complete object code of a C library routine would have to be included in every XCMD which made use of it. The redundancy would quickly get out of hand.

The Toolbox and the SANE library have functions for almost everything that needs to be done in a program or code resource. This code is in the ROM and is always available for use without adding to the overhead. Portability considerations aside, it is desirable to take advantage of it whenever possible while writing Macintosh specific applications.

CONCLUSION

A practical method of using XCMD’s in standalone C applications was presented. An evaluation of the memory size problems encountered while developing this procedure would indicate that high-level lanquage library routines (C, Pascal, etc.) should be avoided in XCMD’s used by Hypercard as well as those written for standalone applications.

I can be reached on internet at ghkenner@cc.utah.edu, on Prodigy at BSSX14B and Apple Link at UUTL.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Affinity Designer 1.5.5 - Vector graphic...
Affinity Designer is an incredibly accurate vector illustrator that feels fast and at home in the hands of creative professionals. It intuitively combines rock solid and crisp vector art with... Read more
djay Pro 1.4.3 - Transform your Mac into...
djay Pro provides a complete toolkit for performing DJs. Its unique modern interface is built around a sophisticated integration with iTunes and Spotify, giving you instant access to millions of... Read more
Jamf Pro 9.98 - Powerful sysadmin/enterp...
Jamf Pro (formerly Casper Suite) is the EMM tool that delights IT pros and the users they support by delivering on the promise of unified endpoint management for Apple devices. At Jamf, connecting... Read more
Airmail 3.2.4 - Powerful, minimal email...
Airmail is an mail client with fast performance and intuitive interaction. Support for iCloud, MS Exchange, Gmail, Google Apps, IMAP, POP3, Yahoo!, AOL, Outlook.com, Live.com. Airmail was designed... Read more
RapidWeaver 7.3.1 - Create template-base...
RapidWeaver is a next-generation Web design application to help you easily create professional-looking Web sites in minutes. No knowledge of complex code is required, RapidWeaver will take care of... Read more
PopChar 7.7 - $16.99 (51% off)
PopChar helps you get the most out of your font collection. With its crystal-clear interface, PopChar provides a frustration-free way to access any font's special characters. Features Expanded... Read more
Apple iTunes 12.6 - Play Apple Music and...
Apple iTunes lets you organize and stream Apple Music, download and watch video and listen to Podcasts. It can automatically download new music, app, and book purchases across all your devices and... Read more
MacPilot 9.0.6 - Enable over 1,200 hidde...
MacPilot gives you the power of UNIX and the simplicity of Macintosh, which means a phenomenal amount of untapped power in your hands! Use MacPilot to unlock over 1,200 features, and access them all... Read more
Sparkle Pro 2.1.4 - $79.99
Sparkle Pro will change your mind if you thought building websites wasn't for you. Sparkle is the intuitive site builder that lets you create sites for your online portfolio, team or band pages, or... Read more
TextSoap 8.3.3 - Automate tedious text d...
TextSoap can automatically remove unwanted characters, fix up messed up carriage returns, and do pretty much anything else that we can think of to text. Save time and effort. Be more productive. Stop... Read more

Death Road to Canada (Games)
Death Road to Canada 1.0 Device: iOS Universal Category: Games Price: $7.99, Version: 1.0 (iTunes) Description: Get it now at the low launch price! Price will go up a dollar every major update. Update news at the bottom of this... | Read more »
Bean's Quest Beginner's Guide:...
Bean's Quest is a new take on both the classic platformer and the endless runner, and it's free on the App Store for the time being. Instead of running constantly, you can't stop jumping. That adds a surprising new level of challenge to the game... | Read more »
How to rake in the cash in Bit City
Our last Bit City guide covered the basics. Now it's time to get into some of the more advanced techniques. In the later cities, cash flow becomes much more difficult, so you'll want to develop some strategies if you want to complete each level.... | Read more »
PixelTerra (Games)
PixelTerra 1.1.1 Device: iOS Universal Category: Games Price: $.99, Version: 1.1.1 (iTunes) Description: The world of PixelTerra is quite dangerous so you need to build a shelter, find some food supply and get ready to protect... | Read more »
Tokaido™ (Games)
Tokaido™ 1.0 Device: iOS Universal Category: Games Price: $6.99, Version: 1.0 (iTunes) Description: Discover the digital adaptation of Tokaido, the boardgame phenomenon that has already sold more than 250,000 copies worldwide, and... | Read more »
Card Thief (Games)
Card Thief 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: Card Thief is a solitaire style stealth game played with a deck of cards. In Card Thief you move through a deck of cards as a... | Read more »
Smilegate’s crafting battler Super Tank...
Super Tank Rumbleputs you in the seat of your very own, handcrafted tank. You can choose from over 100 different parts to create your Super Tank before taking it out to wreak havoc on your opponents in glorious PVP combat. Now, Smilegate is upping... | Read more »
The best games to play while you wait fo...
Mass Effect: Andromeda arrives this coming Tuesday and people are getting understandably antsy. There's a whole weekend standing between us and a brand new Bioware adventure. What's a geek to do? Well, you could certainly give these fine mobile... | Read more »
Here are the best indie games that debut...
The App Store has been running a pretty spectacular promotion of indie games over the past few days, featuring a selection of indie games quite prominently on the storefront while releasing a brand new indie game each day. The promotion is running... | Read more »
Pavilion: Touch Edition (Games)
Pavilion: Touch Edition 1.0 Device: iOS iPhone Category: Games Price: $3.99, Version: 1.0 (iTunes) Description: Pavilion requires at least an iPhone 5 or iPod touch 6. Pavilion, the multiple award winning & IMGA nominated game... | Read more »

Price Scanner via MacPrices.net

13-inch Touch Bar MacBook Pros on sale for up...
B&H Photo has the Apple 13″ Touch Bar MacBook Pros in stock today and on sale for up to $150 off MSRP. Shipping is free, and B&H charges NY sales tax only: - 13″ 2.9GHz/512GB Touch Bar... Read more
Today only! 15-inch 2.7GHz Space Gray Touch B...
B&H Photo has the new 2016 15″ 2.7GHz Space Gray Apple Touch Bar MacBook Pro in stock today and on sale for $300 off MSRP for today only. Shipping is free, and B&H charges NY sales tax only... Read more
New $329 iPad A Fabulous Value; 10.5-Inch iPa...
Part of the iPad upgrade/new model puzzle is now in place. Yesterday, as KGI Securities financial services group analyst Ming-Chi Kuo last summer predicted they would, Apple released a new low-cost 9... Read more
New 9.7-Inch iPad Features All Of The Fun...
Apple today updated its most popular-sized iPad, featuring a brighter 9.7-inch Retina display and best-in-class performance at its most affordable price ever, starting at $329 (US) with 32GB of... Read more
Apple Introduces iPhone 7 and iPhone 7 Plus (...
Apple today announced iPhone 7 and iPhone 7 Plus (PRODUCT)RED Special Edition in a vibrant red matte aluminum finish, in recognition of more than 10 years of partnership between Apple and (RED). This... Read more
Apple now offering Certified Refurbished 15-i...
Apple is now offering Certified Refurbished 2016 15″ Touch Bar MacBook Pros for $360-$420 off original MSRP. An Apple one-year warranty is included with each model, and shipping is free: - 15″ 2.6GHz... Read more
Apple Introduces Clips: A Free Innovative Way...
Apple today introduced Clips, a new app that makes it quick and fun for anyone to create expressive videos on iPhone and iPad. The app features a unique design for combining video clips, photos and... Read more
Urban Armor Gear Unveils Case For 4th Generat...
Orange County, California based Urban Armor Gear (UAG), designers of rugged, lightweight protective cases for phones, tablets and laptops, has released its latest drop-tested cases for Apple’s 4th... Read more
Most Users Continue To Prefer 5.0 to 5.3 Inch...
In the first half of 2016, US and UK smartphone users were most likely to be interested in purchasing a device with a 5.3″ or 5.0″ display. Findings in a new report from the User Experience... Read more
12-inch 1.2GHz Retina MacBooks on sale for up...
B&H has 12″ 1.2GHz Retina MacBooks on sale for up to $200 off MSRP. Shipping is free, and B&H charges NY sales tax only: - 12″ 1.2GHz Space Gray Retina MacBook: $1439.99 $160 off MSRP - 12″ 1... Read more

Jobs Board

*Apple* Retail - Multiple Positions - Apple,...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
Fulltime aan de slag als shopmanager in een h...
Ben jij helemaal gek van Apple -producten en vind je het helemaal super om fulltime shopmanager te zijn in een jonge en hippe elektronicazaak? Wil jij werken in Read more
Starte Dein Karriere-Abenteuer in den Hauptst...
…mehrsprachigen Teams betreust Du Kunden von bekannten globale Marken wie Apple , Mercedes, Facebook, Expedia, und vielen anderen! Funktion Du wolltest schon Read more
Starte Dein Karriere-Abenteuer in den Hauptst...
…mehrsprachigen Teams betreust Du Kunden von bekannten globale Marken wie Apple , Mercedes, Facebook, Expedia, und vielen anderen! Funktion Du wolltest schon Read more
*Apple* Retail - Multiple Positions - Apple,...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.