home *** CD-ROM | disk | FTP | other *** search
Wrap
ΓòÉΓòÉΓòÉ 1. Cover ΓòÉΓòÉΓòÉ The Developer Connection News The Developer Connection for OS/2 ΓêÖ Volume 2 "The complete source of information for all of your OS/2 development efforts." ΓòÉΓòÉΓòÉ 2. Publisher's Note ΓòÉΓòÉΓòÉ The Developer Connection News November 1993 Volume 2 Number 2 Publisher Barbara Britt Editor, The Developer Connection News Stacey Miller Editorial Advisor Suzanne Gagnon Technical Advisors David Kenner, Jay Tunkel Art Director Brian Black Graphics Design Studio East Ft. Lauderdale, Florida The Developer Connection News is a technical newsletter published quarterly by The Developer Connection, Stacey Miller, Editor. The newsletter contains product, strategy, and technical information for software developers. To correspond with The IBM Developer Connection News, please write to the Editor at IBM Corp., P.O. Box 1328, Internal ZIP 1599, Boca Raton, Florida 33431-1328. IBM may use or distribute any of the information you supply in any way it believes appropriate without incurring any obligation whatever. The terms OS/2, OS/2 2.0, and OS/2 2.1 are used in this publication as abbreviations for the full term OS/2 operating system. OS/2 is a registered trademark of the IBM Corporation. Titles and abstracts, but no other portions, of information may be copied and distributed by computer-based and other information service systems. Permission to republish information from this publication in any other publication of computer-based information systems must be obtained from the Editor, The Developer Connection News. IBM believes the statements contained herein are accurate as of the date of publication of this document. All specifications are subject to change without notice. However, IBM, hereby disclaims all warranties, either expressed or implied, including with out limitation any implied warranty of merchantability or fitness for a particular purpose. In no event will IBM be liable to you for any damages, including any lost profits, lost savings, or other incidental or consequential damage arising out of the use or inability to use any information provided through this publication even if IBM has been advised of the possibility of such damages, or for any claim by any other party. Some states do not allow the limitation or exclusion of liability for incidental or consequential damages so the above limitation or exclusion may not apply to you. This publication may contain technical inaccuracies or typographical errors. Also, illustrations contained here may show prototype equipment. Your configuration may differ slightly. This publication may contain articles by non-IBM authors. These articles represent the views of their authors. IBM does not endorse any non-IBM products that may be mentioned. Questions should be directed to the authors. This information is not intended to be an assertion of future action. IBM expressly reserves the right to change or withdraw current products that may or may not have the same characteristics or codes listed in this publication. It is possible that this material may contain reference to, or information about, IBM products (machines and programs), programming or services that are not to be construed to mean that IBM intends to announce such products, programming, or services in your country. IBM takes no responsibility whatsoever with regard to the selection, performance, or use of the products advertised herein. All understanding, agreements, or warranties must take place directly between the software vendors and perspective users. IBM, OS/2, PS/2, Micro Channel, Presentation Manager, Workplace Shell, AS/400, and ES/3090 are registered trademarks of IBM Corp. AIX, C/2, CUA, SAA, WIN-OS/2, AS/400, ES/390, C Set/2, WorkSet/2, WorkFrame/2 , Pen for OS/2, MMPM/2, and Multimedia Presentation Manager/2, Ultimotion, and M-Audio Capture are trademarks of IBM Corp. Microsoft, MS-DOS, Code View, and Windows are trademarks of Microsoft Corp. CompuServe is a trademark of CompuServe Incorporated. UNIX is a trademark of UNIX System Laboratories. Apple, Macintosh, and System 7 are trademarks of Apple Computer, Inc. Intel, DVI, Indeo, and Pentium are trademarks of Intel Corporation. SmallTalk/V is a trademark of the Digitalk, Inc. HockWare and VisPro/REXX are trademarks of HockWare, Inc. WATCOM and Vx_Rexx are trademarks of WATCOM. C + + is a trademark of AT&T, Inc. Motorola is a trademark of Motorola, Inc. ProAudio Spectrum is a trademark of Media Vision. Sound Blaster is a trademark of Creative Labs, Inc. Performance 2.1 is a trademark of Clear & Simple, Inc. Taligent is a trademark of Taligent, Inc. All other products and names may be trademarks and/or registered trademarks of their respective holders. ΓòÉΓòÉΓòÉ 3. LIFE AFTER MAXIMUM ENTROPY or Operating Systems Unification at Last ΓòÉΓòÉΓòÉ by Scott L. Winters and Jeri Dube ΓòÉΓòÉΓòÉ 3.1. Days Gone By... ΓòÉΓòÉΓòÉ The ordered world of PC hardware and software in the 1980s has been fractured in the 1990s. Simplistically viewed, in the 1980s all an entrepreneur had to do was write a good application on DOS and market it well. If he did that, then everyone would buy the application and use it on their IBM PC or PC clone. Since that kinder, gentler, and simpler time, a lot has changed. Today, there are numerous software platforms with different API sets that are still evolving. These different API sets are all competing for viability. Until the ultimate winner or winners are declared, the software developer is left to either take his chances with his choice of the long term winner or hedge his bets by supporting multiple software platforms. The cost of supporting the various API sets are high. The development costs include the time, energy, and money it takes to migrate from one API set to another plus add the features to take advantage of the additional functionality. The cost also include s the effect of not using resources to improve the application itself to further meet the requirements of the application users. The risk of supporting only one platform is that the investment will be lost due to insufficient sales of the selected platform. The anarchy and confusion in today's PC world is not all created by the software. The entire hardware paradigm is changing. Until recently, the CISC and RISC worlds were separate and distinct. With the invention of the PowerPC chip set and hardware reference platform, RISC is moving into the realm of desktop computing. Similarly, the capabilities and robustness of Intel's Pentium chip moves CISC even further into the server and workstation realm. In addition, the distinguishing software requirements between different hardware systems are blurring as systems from PDAs to super computers are required to be on one continuum. Further complicating the world, is the pending movement from today's 32-bit machines to tomorrow's 64-bit machines. Additionally, computers are leaving homes and offices and moving onto the road and into the air. People want and now expect their applications to be able to work anywhere. What we have in the current world of computing is a state of maximum entropy. The industry is evolving, churning and fracturing. The complexity of choices needs to be simplified, even more than they have been already by the introduction of a multi-personality, integrated platform like OS/2, because the complexity is too draining of resources. ΓòÉΓòÉΓòÉ 3.2. A New Order ΓòÉΓòÉΓòÉ The Workplace OS family (WPOS) is IBM Personal Software's vehicle to bring order back to the world of computing. In this article, we will show the features of the system and how those features allow application developers to minimize their resource expenditures on retrofitting code while maximizing the number of platforms on which an application can run. ΓòÉΓòÉΓòÉ 3.3. A Modular Operating System ΓòÉΓòÉΓòÉ The Workplace OS family provides a modular approach to allow different operating system personalities to share physical hardware resources and system software components that are architecturally positioned as support elements. Looking at the system from the bottom up, we start with the hardware platforms. WPOS runs on the CISC environment of the Intel x86 and Pentium family of chips and the RISC-based IBM/Motorola PowerPC Architecture. Our approach is to introduce a UNIX personality of WPOS (WPIX) on the Intel platform and a Workplace OS/2 (WP-OS/2) personality on the PowerPC platform with a DOS/WIN personality on both platforms. As time passes, all three personalities will run on both platforms, and the WPOS family will extend onto other RISC-based platforms with more personality choices as well. ΓòÉΓòÉΓòÉ 3.4. Putting it Together ΓòÉΓòÉΓòÉ The WPOS interface to the hardware platform is the IBM Microkernel, which is an extended and industrialized version of the Mach microkernel originally written at Carnegie Mellon University. Some of the IBM-written extensions include out-of-kernel devic e drivers, security, and additional performance enhancements. The microkernel is what allows WPOS to be portable between hardware platforms. Also contained in the interface is a set of system services called Personality Neutral Services (PNS) that are required by all traditional operating systems. These services are considered personality neutral because they are: o Written in an endian-neutral, processor-neutral fashion o Common to all operating systems in an implementation-neutral way. o Able to share APIs with all other neutral services within the system. These services are provided by five separate servers. The Name Server ensures the uniqueness of each system entity's name so that there is no confusion between elements in the system. The Master Server is responsible for the initial system loading and address resolution. The Default Pager handles memory allocation and anonymous paging. The Hardware Resource Manager (HRM) does the peripheral device management as well as handling basic Boot support. The Security Server manages access rights and handles security tokens. WPOS physical device drivers will also be personality neutral, so once a device driver is designed and written in a neutral way, it can be reused by many operating systems personalities. The combination of the hardware interface, physical device drivers, and the above services comprise the IBM Microkernel. The microkernel is not an operating system by itself, but rather a set of components on which operating systems can be constructed. The microkernel is the foundation of Workplace OS and also will be available as a product for operating system developers to use as building blocks. Using the microkernel as the foundation of WPOS gives it the flexibility to be used on hardware systems ranging from PDAs to supercomputers. Common Personality Services (CPS) are an optional set of elements within Workplace OS. A CPS is shared among different operating system servers, as described previously, except that a CPS has fewer rules to follow within the system structure and architecture. The value of a CPS is in its ability to be shared partially or fully within the system architecture. A CPS: o May be common to a subset of operating system personalities in its function or architecture. o May export its APIs to other PNS/CPS libraries and servers but may not need to be common to all. o Is an optional element of the Workplace OS, not an element of the microkernel product. A prime example of a CPS is the OS/2-styled multimedia subsystem and server. In this CPS, you find the current OS/2 2.1 and Windows 3.1 multimedia architectures, exporting the Media Control Interface and the Multimedia I/O (MMIO) API. Although these interfaces are important to traditional Intel-based PC's, they mean less in other worlds like Unix or System 7. Since this MM layer is common to only a subset of WPOS personalities, and it is not in the Microkernel, it is a CPS rather than a true PNS. The File Server (FS) is also a product and a CPS. The File Server supports the management of a client/server file system model. The FS client code is dynamically linked in the same address space of a WPOS application and supports traditional API sets. The Server side of the product embodies the Logical File System (LFS). The Server hosts the Service Provider Interface (SPI) to the Physical File Systems and also talks to the microkernel and the Name Server. Physical File Systems planned to be included in WPOS are FAT, CD-ROM, JFS, HPFS and others. Some subset of these will be in the initial release of the file server. JFS is planned for the first release because it is functionally robust and extensible. The design is stable and a proven architecture currently used in the open standards world. In addition to the two CPS's listed, there will be more CPS's offered by IBM and others. These Common Personality Servers will provide functions such as database, communications, and LAN servers. In WPOS, operating system environments are known as personalities. These personalities provide the user interface and the complete operating system function not included in the microkernel for that personality. The end user of WPOS will choose which version of the Workplace OS family to use for their applications, compatibility requirements, and so on. Workplace OS/2 is functionally compatible with OS/2 2.1. What this means is that every 32-bit API that exists in Version 2.1 will exist in this operating system. The OS/2 text-based, 16-bit APIs will be functionally replaced with 32-bit equivalent APIs. In addition, our goal is to maintain source compatibility between OS/2 32-bit applications on WP-OS/2 for Intel and WP-OS/2 for PowerPC, with binary compatibility between OS/2 32-bit applications on WP-OS/2 for Intel and OS/2 2.1 on Intel. Extensions beyond OS/2 2.1 functionality, besides the obvious advantage of more hardware platforms include the following list: o System management o Human-centric exploitation o Scalability o Security o User-friendly installation o Improved developer productivity ΓòÉΓòÉΓòÉ 3.5. The Beginning of the End of Maximum Entropy ΓòÉΓòÉΓòÉ Workplace OS is a microkernel-based operating system that embodies the Workplace family of architected technologies and open industry standards. Many products will be based on Workplace technologies and standards, because they give customers and developers flexibility to adopt new technologies while protecting their current investment. The Workplace Shell is one of these technologies. By virtue of the Workplace Shell, WPOS will not be foreign to users of other IBM Personal Software products. The Workplace Shell is a common GUI on top of the traditional operating system environment. The immediate value of such an environment is obvious: enhanced user productivity within a heterogeneous PC office environment. Employees fluent on the Workplace Shell would be able to use any office equipment available, independent of the Workplace family member. The value to developers is the standardization of a GUI API set. Since the Workplace Shell on OS/2 2.1 is available and robust today, there is an existing path from which to grow to in the future. The beginning of the end of maximum entropy is here today. The addition of Workplace OS diminishes the entropy by isolating applications from hardware, so developers can create source code without regard to hardware differences. Furthermore, with an architecture that enables concurrent execution of applications w ritten for several OS platforms, by providing multiple OS services on a microkernel, a developer will find it less critical to develop applications for multiple software platforms. Common Personality Services provide the mechanisms that subsystem developers use to create products for multiple microkernel-based operating environments. The computing environment will never return to the simplicity of the early days for personal computers. IBM's goal is to provide technical innovations and advanced architectures that can simplify the choices and minimize the expense of developing applications while satisfying customers' requirements. WPOS meets these goals by being both portable and scalable, as well as an extension and complement to IBM's current operating systems portfolio. ΓòÉΓòÉΓòÉ 3.5.1. About the Authors ΓòÉΓòÉΓòÉ Jeri Dube is an Advisory Planner for the Workplace OS products. Previously, Jeri was a Planning Group Manager for Engineering Systems Test for Enterprise Systems. During her eclectic career at IBM, Jeri has held a variety of roles. Scott L. Winters is an IBM Senior Technical Staff Member. His current assignment is Chief Architect of Workplace OS/2. Previously, Scott was the Lead Architect in the OS/2 Multimedia Systems Software group, where the MMPM/2 product was created. Look to future issues of The Developer Connection News for in-depth articles on: o Common Personality and Personality Neutral Servers. o Extensions beyond Os/2 2.1 o The Workplace Shell ΓòÉΓòÉΓòÉ 4. OpenDoc: An Idea Whose Time has Come! ΓòÉΓòÉΓòÉ by Robert Tycast When Brad Cox coined the term "software IC", he foresaw a day when software building would move from the realm of hand-crafted monoliths to a world of composites. These new-age solutions would be assembled from parts by skilled application builders using and reusing software components in ways that the original designers didn't and couldn't have conceived of. OpenDoc represents an important first step in that direction. It provides the technology to break up an application into parts. ΓòÉΓòÉΓòÉ 4.1. OpenDoc - What's In a Name? ΓòÉΓòÉΓòÉ "Open" - OpenDoc is a programming architecture for creating, storing, and sharing compound-documents. It is open, vendor-neutral, language-independent, and cross-platform. Born of work by Apple Computer, Inc., and supported by major vendors such as IBM, Novell, Oracle, WordPerfect Corporation, Xerox Corporation, and Taligent, OpenDoc is changing the way applications are built and used. "Doc" - OpenDoc is document-centered programming. By a suitable change of mind-set, virtually all applications in use today can been seen as a document. And, the definition is expanded. In OpenDoc, documents include more than text - audio, video, graphics, charts, spreadsheets - virtually anything that a computer can output is fair game. The document must be alive and not static - animation, background music, and a dynamically changing content are all part of the OpenDoc document. You will no longer decide which applications to launch to solve a problem or to do work on your computer. Instead, you'll start with blank stationery and compose a document by collecting and combining "parts in standard or novel ways, depending on your need, inclination, or experience-level." The most simple documents, ones that traditionally would use a text editor or word processor simply will include a text part. If, however, you wish to spice up your memo or letter with some graphics, simply include a graphics part using your favorite graphics editor. Or, if you want to include up-to-the-minute sales data, then a bar graph linked to a spreadsheet will do the trick. Contrast this with an application-centered model, where you can't decide to include graphics in your document as an afterthought. You have to choose a word-processor which has all of the capabilities that you'll eventually want. With OpenDoc you are limited only by your imagination and not by the capabilities of the application selected. ΓòÉΓòÉΓòÉ 4.2. Is That ALL? ΓòÉΓòÉΓòÉ Not by a long shot. OpenDoc documents are scriptable. That means that developers can provide unique solutions by gluing OpenDoc parts together with a script language such as ObjectRexx. And users benefit, because they can tinker and customize their documents to their heart's content. ΓòÉΓòÉΓòÉ 4.3. An Amalgam of Technologies ΓòÉΓòÉΓòÉ OpenDoc will consist of four distinct technologies: o Compound documents This is OpenDoc proper. o System Object Model (SOM) SOM provides the CORBA-compliant capabilities of OpenDoc, including a language-neutral interface and the ability to access parts across a network. o Open Scripting Architecture (OSA) OSA provides the ability to script a document at the part level. o Bento This is the persistent storage model. It is available to developers to use to write OpenDoc documents to permanent store. ΓòÉΓòÉΓòÉ 4.4. But How Will These Technologies Be Made Available To The Industry? ΓòÉΓòÉΓòÉ Enter CIL. Apple Computer, Inc., IBM, Novell, Oracle, WordPerfect Corporation, Xerox Corporation, and Taligent have agreed to license these technologies to a jointly-funded consortium. To that end, Component Integration Laboratories (CIL) was founded. Modeled after the successful X Window System Consortium, CIL will receive the rights to OpenDoc, SOM, and related technologies. It will, then, license them back, royalty-free, to the industry. Members will contribute reference implementations and other donated software. CIL will also develop certification programs as a service to the industry to verify the completeness and correctness of OpenDoc implementations, as well as offer training for developers who want to use CIL technologies. ΓòÉΓòÉΓòÉ 4.5. What? You Want More Information? ΓòÉΓòÉΓòÉ For more information, contact the Component Integration Laboratories. They can be reached at: Component Integration Laboratories (CIL) 688 Fourth Avenue San Francisco, California 94118 (415) 750-8352 (voice) (415) 757-4829 (fax) "The Components Integration Laboratory....is a nonprofit association dedicated to software plug-and play interoperability across multiple computer platforms." Watch for more information on OpenDoc in successive Newsletters, as well as on The Developer Connection for OS/2 CD-ROM. ΓòÉΓòÉΓòÉ 4.5.1. About the Author ΓòÉΓòÉΓòÉ Robert Tycast is an Advisory Programmer in the OS/2 Development group. Over the last 15 years, Robert has had project experience in XII, AI Technology (LISP and OPS5 support), and technical workstations (VMS and ULTRIX). ΓòÉΓòÉΓòÉ 5. Side by Side Comparison - OpenDoc vs. OLE2 ΓòÉΓòÉΓòÉ ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ ΓöéOpenDoc ΓöéOLE2 Γöé Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ ΓöéOpen System - Freely licensed ΓöéProprietary - Owned and Γöé Γöéto the industry through the Γöécontrolled by Microsoft. Γöé ΓöéComponent Integration Γöé Γöé ΓöéLaboratories. Γöé Γöé Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ ΓöéSOM - Based on industry ΓöéCOM - NOT CORBA compliant; no Γöé Γöéstandard for object-oriented Γöéinheritance; aggregation Γöé Γöéprogramming (CORBA). Γöéproposed as alternative. Γöé Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ ΓöéDistributed - OpenDoc parts ΓöéNot Distributed - Can only Γöé Γöécan be embedded from anywhere Γöéembed objects from local OLE Γöé Γöéin the network. Γöéservers. Γöé Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ ΓöéCross-platform support - ΓöéOnly available on Microsoft Γöé ΓöéOpenDoc will be available on ΓöéWindows. Γöé ΓöéApple, OS/2, UNIX, and Γöé Γöé ΓöéMicrosoft Windows. Γöé Γöé Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ ΓöéLanguage Neutral - SOM ΓöéDifficult to use with Γöé Γöébindings make OpenDoc readily Γöélanguages other than C++. Γöé Γöéavailable from any language. Γöé Γöé Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ ΓöéSource code available. ΓöéSource code NOT available. Γöé Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ ΓöéAny part can be at the "root" ΓöéIn OLE, only specialized Γöé Γöéof the document. Γöécontainers can be at the Γöé Γöé Γöé"root". Γöé Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ ΓöéParts can be any shape. ΓöéOLE objects must be Γöé Γöé Γöérectangular Γöé Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ ΓöéOpenDoc maintains multiple ΓöéNo support for multiple draftsΓöé Γöédraft versions of a document. Γöéon OLE. Γöé Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ ΓöéOpenDoc parts can overlap. ΓöéOLE objects CANNOT overlap. Γöé Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ ΓöéOpenDoc parts can be edited byΓöéOLE objects must be activated Γöé Γöéclicking on them directly. Γöéand the content selected in Γöé Γöé Γöéorder to edit it; when nested,Γöé Γöé Γöémultiple levels have to be Γöé Γöé Γöéactivated. Γöé Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ ΓöéDevelopment effort: 50 ΓöéDevelopment effort: 14 Γöé Γöémandatory functions for a Γöédifferent interfaces must be Γöé Γöébasic part. Γöéprovided with a total of 136 Γöé Γöé Γöéfunctions mandatory. Γöé ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ ΓòÉΓòÉΓòÉ 6. Insights ΓòÉΓòÉΓòÉ Barbara Britt, Product Manager of OS/2 Development Tools including The Developer Connection for OS/2, took time out of her busy schedule to talk to Stacey Miller, Editor of The Developer Connection News, about the future of OS/2 Development Tools and specifically The Developer Connection program. The following is an edited transcript of that conversation. SM: Barbara, beside being Product Manager for The Developer Connection for OS/2, what other development tools are you responsible for? BB: I'm also responsible for the OS/2 Developer's Toolkit and the OS/2 Device Driver Source Kit (DDK). In addition, I have responsibility for the Workplace OS development tools, And, in the future you'll be seeing pre-release copies of those toolkits that support our Workplace OS development as we move that development onto the PowerPC. SM: You said "in the future." Can you project how long in the future? BB: Information has already been starting to go out about Workplace OS, the types of tools needed, and the development environment to the development communities. We will start rolling out the Workplace OS toolkits early next year on The Developer Connection for OS/2 CD-ROM. SM: The Developer Connection for OS/2 has been creating a lot of excitement since its announcement in August. Why do you believe this to be the case? BB: I think The Developer Connection for OS/2 is receiving this good response because we've been listening to the customers, and we are providing what they've asked for. They've asked for the latest tools and latest pre-release versions of the Operating Systems as soon as they are available and the Developer Connection does that. We also provide the latest information in The Developer Connection News. They also like all the other extra things on the CD-ROM, such as the demo products. SM: What steps are you taking to make sure that The Developer Connection for OS/2 is meeting the needs of developers? BB: We are continuing to get feedback For example, we've put a CompuServe forum together exclusively for people who have purchased The Developer Connection, so we can get that feedback. Also, we are talking to people at conferences. We take all of the feedback back here [to the development lab] to work on getting the right tools and levels of information on the CD-ROM to answer the requests of our customers. SM: A lot of folks are comparing The Developer Connection to Microsoft's Developer Network. How do you respond to this comparison? BB: I think our focus is different than Microsoft's Developer Network, and I think that just because they're both delivered on a CD-ROM will invite comparison. I believe that the key purpose of the Developer Network is to provide information. We are not only providing information, but the toolkits, pre-release software, demos, and samples. I believe we're striving to satisfy a different market; to solve a different problem. SM: The Developer Connection for LAN Systems was pre-released in Orlando; what is the difference between that Developer Connection and The Developer Connection for OS/2? BB: The Developer Connection is a program; it is not just a product. The program is designed to get the right set of tools out to the right customers. In the future, you'll be seeing more announcements of other Developer Connections. Now, the Developer Connection for OS/2 is the one for base OS/2 development. If you're specifically developing in the LAN environment, you would need the Developer Connection for LAN Systems. Since it is a program, the user interface, the browser, and the catalog functions will all be the same. Also, ordering information and support will come from one common area. Therefore, each additional program will be an extension of The Developer Connection for OS/2. SM: What about other Developer Connection programs? BB: We're looking at providing a Developer Connection for Objects, which may or may not be part of the base system, because objects is such an important part of the whole base. So if its not a separate offering, it will be a separate section to The Developer Connection for OS/2. I've also talked about the Developer Connection for Workplace OS, which will run on the PowerPC. We're also looking at expanding The Developer Connection program to run on some of the UNIX-based boxes to provide tools for UNIX developers. SM: What are the plans to have these additional Developer Connection programs available? BB: Most of these programs will be available next year. We're rolling them out over time. Workplace OS will be delivered first, with the rest of the programs to follow. You'll eventually see The Developer Connection as a family of programs. SM: Some of the developers are saying that the first CD-ROM did not contain enough sample code. How would you respond to that? BB: Everyone needs more samples, and we would agree that we need to provide more samples. But what we're trying to do right now is to put together a list of the most-requested samples. Then, we'll either ask people in IBM development to write them; or we'll ask people outside of IBM to donate them. For instance, if you had a particular favorite sample to solve a problem, we'd like to evaluate putting it on the CD-ROM. We are developing a sample architecture to ensure that the programmer gets consistent information on how to use the sample, as well as the problem that the sample is solving. We would like to put the sample architecture on the CD-ROM, so if you are writing a sample, you could follow that architecture. That way, everybody has the same base to work from. SM: What other improvements can you tell us about? BB: We want to improve the Browser. We want to add phrase and Boolean searches. We want to improve the on-line information, as well as the Catalog functions. We also want to look at adding more books. SM: What about hardware? Is there any plan to tie the Device Driver Source Kit program in with The Developer Connection for OS/2, or do you feel that these will stay two separate offerings? BB: We've made tremendous strides in providing the Device Driver Source Kit for OS/2. In fact, we've just delivered the first update to that system. We're getting tremendous response that we're providing the right kinds of device driver source code that they need to do their device driver development. This will help hardware support. We are also looking at providing the DDK as part of the Developer Connection program. Again, not everyone is doing device driver development, so it would be just a way to consolidate support and have more of a one stop shopping place for all of the Development Tools. SM: The success of Independent Software Vendors (ISVs) is crucial to IBM's success with OS/2. How will being a part of The Developer Connection family help them, and at the same time help IBM? BB: What we want to do with The Developer Connection is to provide pre-release operating systems to both our ISVs and Corporate customers, so that they can develop and exploit new operating system functions in their applications. Then, they can have the applications ready at the same time the operating system ships. So, when OS/2 comes out with a new function applications will be available that can exploit these new functions right away. This will not only help OS/2, but it will also help the ISVs. They will be able to say, for example, when OS/2 supports OpenDoc, their application will also support OpenDoc. There will be no lag time between a new release of an operating system and applications that exploit those new functions. SM: Do you believe that The Developer Connection for OS/2 is critical to the success of OS/2? BB: Tools and programs like The Developer Connection are critical to the success of OS/2. We need to provide software developers with what they need to write applications that support OS/2. And, those applications running on OS/2 are a key to its success. SM: Thank you, Barbara! Barbara Britt, Product Manager -- The Developer Connection for OS/2 Stacey Miller, Editor -- The Developer Connection News ΓòÉΓòÉΓòÉ 7. The OS/2 Graphics Subsystem in the Workplace OS Family ΓòÉΓòÉΓòÉ by Kelvin R. Lawrence In recent articles published in The Developer Connection News, we have presented an overview of Workplace OS. One of the key features of Workplace OS is its ability to run all of today's 32-bit OS/2 applications, which includes those written to the OS/2 Presentation Manager. In this article, we will explore the graphical and presentation service capabilities that Workplace OS/2 (WP-OS/2) will provide for OS/2 applications - focusing on the port of the OS/2 Graphics Subsystem to the WP-OS/2 environment. All of the components present in the graphics subsystem of today's OS/2 2.1 will be ported to the WP-OS/2 IBM Microkernel environment. Presentation Manager applications that are written in a 32-bit, high-level language (such as C or C++) will port to WP-O S/2 with little more than a recompile. And, depending on the target hardware platform even the recompile might be unnecessary. For example, today's 32-bit applications that run on Intel hardware will continue to run on WP-OS/2 on Intel hardware. In ad dition, today's 32-bit, assembler code will port potentially unchanged to WP-OS/2 when running on an Intel hardware platform, but not to non-Intel hardware. However, applications written in a 16-bit, high-level language today, will, at a minimum, require a port to a 32-bit compiler. Ideally, they should be modified to take full advantage of a 32-bit flat memory model that OS/2 2.1 provides today and that the WP-OS/2 will provide. The reality is that on WP-OS/2, 32-bit applications will be easier to port and will realize greater performance. All of the interfaces provided by the PM Window Manager (PMWIN) and PM Graphical Programming Interface (PMGPI) will be available in 32-bit form on WP-OS/2. This is very important for application programmers who want to maintain one set of source code and have it run unchanged on a variety of hardware platforms (for example, Intel and RISC). The Graphics Subsystem under WP-OS/2 ΓòÉΓòÉΓòÉ 7.1. The PM Window Manager ΓòÉΓòÉΓòÉ When we talk about the PM Window Manager (PMWIN) component of OS/2 2.1, we are referring to that piece of Presentation Manager that provides the support for the displaying and manipulating of windows and controls. As many of you know, even under OS/2 2.1 today, some pieces of 16-bit code and data are present in the Window Manager. As part of the port of the Window Manager to WP-OS/2, all of the remaining restrictions imposed by the presence of 16-bit code and data will be removed. This will yield advan tages for 32-bit applications. No longer will any thunk (or conversion) layers be needed to convert 32-bit data provided by applications to 16-bit format, so that the Window Manager can work with the data. Also, the control window classes provided by PMWIN, such as the listbox, will no longer have a 64KB constraint on the amount of data they can maintain. The technology used to upgrade PMWIN for WP-OS/2 will be rolled back to the OS/2 2.x arena. Therefore, 32-bit applications will realize the benefits of a fully 32-bit Window Manager on any platform where the OS/2 2.1 application programming interface (API) is available. ΓòÉΓòÉΓòÉ 7.2. Graphical Programming Interface ΓòÉΓòÉΓòÉ Since its inception in the days of OS/2 1.1 back in 1987, the Graphical Programming Interface (GPI) has had a 32-bit API. In other words, all of the parameters that get passed to GPI functions are 32-bit LONGs. In the OS/2 2.1 environment, the internal library of the GPI is fully 32-bit. Because of this, applications written to the GPI today will see exactly the same environment when running under either WP-OS/2 or OS/2 2.1. ΓòÉΓòÉΓòÉ 7.3. Graphics Engine ΓòÉΓòÉΓòÉ OS/2 2.1 already contains a powerful, 32-bit, graphics engine. The graphics engine is the graphical kernel of PM. It sits between the GPI and the presentation drivers that support hardware devices. The engine contains the algorithms and functions that implement the OS/2 imaging (or drawing) model. It handles and manipulates all aspects of the graphics subsystem - from rendering line primitives, such as arcs and splines, to performing coordinate transformations to managing fonts to calculating clipping. In the same way that 32-bit applications can be ported easily to the WP-OS/2, the graphics engine also is a simple port. This is because it is written almost entirely in 32-bit C code. ΓòÉΓòÉΓòÉ 7.4. Presentation Driver Model ΓòÉΓòÉΓòÉ The term presentation driver refers to the piece of code that sits between the graphics engine and a hardware device such as a screen or a printer. Presentation drivers are really dynamic link libraries (DLLs) that can be dynamically loaded when required. A typical OS/2 2.1 system has one display presentation driver and one or more printer presentation drivers loaded at any one time. The graphics engine maintains a dispatch table of functions for each device it has loaded. When an application makes a GPI call such as GpiPartialArc, the GPI calls the engine's function dispatcher, which jumps to the address of the PartialArc function in the dispatch table. When the engine initially loads a presentation driver, the driver has the chance to replace the address of functions in the default dispatch table with the address of its functions. For example, if the driver provides the address of a function that implements the PartialArc function, the engine jumps directly to the driver's function - whenever the application makes a call to GpiPartialArc. Otherwise, the engine breaks the arc down into simpler graphics primitives that the device indicates it can handle by hooking out those functions, such as PolyLine. Today, in OS/2 2.1, presentation drivers have to hook out (or support) between 59 (printer drivers) and 75 (display drivers) mandatory functions. That is, the engine provides no support for a range of functions that it expects all presentation drivers to provide routines for. Therefore, presentation drivers are more complex and take longer to write than perhaps should have be necessary. As well as the current level of function it provides, the graphics engine is being further enhanced to make the writing of presentation drivers much easier. Existing drivers that hook large numbers of functions are still supported. However, the number of mandatory (must hook) functions is greatly reduced. Under the new model, the minimum that a presentation driver will have to do to get up and running is to notify the engine of a flat frame linear address where the engine can place a ready-for-display bitmap image of the picture generated by the application. For a display device, this could be simply the address of video memory in the hardware. For a printer device, this could be a large linear address space within the printer or an address space allocated by the presentation driver. To achieve the new presentation driver model, the graphics engine will now provide support for functions that it required drivers to support in the past. The engine will also provide more built-in support for palette management and generation of rasterized images, so presentation drivers do not have to provide that support themselves. The new presentation driver model means that it will be very easy and take very little time to get a presentation driver up and running. This is especially good when producing drivers for a new hardware device, as it is highly desirable to get a driver up and running quickly. By allowing Presentation drivers to hook out more than a minimum set of functions from the Engine's dispatch table, they will still be able to exploit built-in algorithms and features of hardware device that are provided to help spee d up the graphics rendering process. In other words, presentation drivers will focus on the hardware specific portions of their drivers (the parts that are unique) and can allow the Engine and the rest of the presentation manager video subsystem to do the rest of the work. It is possible to port existing OS/2 2.1 presentation drivers to WP-OS/2. The new model does not replace the old one, rather it complements it. To port a presentation driver to WP-OS/2, it will first of all need to be converted to 32-bit code if it is currently 16-bit code. A high-level language should be used to enable porting of code across hardware platforms. As presentation drivers, by their very nature (especially in the case of display drivers), have hardware-dependent portions, some changes wi ll be needed to that part of the driver if it is being ported to a non-Intel platform. The new presentation driver model will also be made available in the OS/2 2.x arena so that presentation drivers can be developed to the new model to work both under OS/2 2.x and WP-OS/2. ΓòÉΓòÉΓòÉ 7.5. Keyboard/Video/Mouse APIs ΓòÉΓòÉΓòÉ OS/2 2.1 provides a set of functions that character mode (non-PM) applications can use to manipulate the keyboard, mouse, and screen. Under WP-OS/2, the majority of these functions will be provided in 32-bit form. ΓòÉΓòÉΓòÉ 7.6. Summary ΓòÉΓòÉΓòÉ In summary, the WP-OS/2 environment provides a fully-functional, 32-bit, Presentation Manager across a wide variety of hardware platforms. To the OS/2 application developer, simply put, this means a large increase in potential end users and target machines. As it is a simple task to port the Micokernel to new hardware platforms, and as WP-OS/2 is built on top of the Microkernel, the number of hardware platforms where the OS/2 2.1 API is available will continue to grow and grow. At the same time, PM applications will continue to port very easily to each of the new platforms requiring, in most cases, no more than a recompile. ΓòÉΓòÉΓòÉ 7.6.1. About the Author ΓòÉΓòÉΓòÉ Kelvin R. Lawrence is an Architect working on the design of IBM's Workplace OS Graphical Subsystem. He was the Lead Programmer for the development of the OS/2 2.1 Presentation Manager. Kelvin has been a key member of OS/2 development and support since 1986. ΓòÉΓòÉΓòÉ 8. Cool Stuff on This Month's CD-ROM ΓòÉΓòÉΓòÉ (This month we review Clear & Simple's new product - Performance 2.1. - ed.) Performance 2.1 is a unique product consisting of both a book and a set of utilities. Note: The Developer Connection CD-ROM contains an online version of the book. The gneralized section of the book clearly describes performance issues, such as 32-bit preemptive multitasking, multithreading, and virtual memory operating systems. The detail section provides information about the meaning and allowable values for many of OS/2's CONFIG.SYS commands and parameters. The REXX utilities will help you implement the suggestions in the book. These utilities are categorized into: o Optimizers that assist your system's CONFIG.SYS parameters o Tools that help you specifically tune individual parts of your system o Eliminators that help you reclaim hard disk space occupied by currently unused OS/2 options. Eliminators provide you with a selective uninstall o Performers that help you improve your individual performance, rather than system performance Performance 2.1 also includes 3000+ public-domain icons in a zipped format to save you time and communication charges needed to download these icons from bulletin boards. Performance 2.1 is for a wide range of users that will benefit from the sample configurations outlined for minimum, average, and power systems. This, the utilities, REXX source code, and the 3000+ icons make it a great value. ΓòÉΓòÉΓòÉ 9. Snap! Crack! Bang! With OS/2 2.1 Multimedia Support (Part 2) ΓòÉΓòÉΓòÉ by Gary G. Allran In the previous issue of The Developer Connection News, we described the user interface aspect of the Audio portion to the OS/2 2.1 operating system's multimedia support. This quarter we continue with the description of the Video portion of multimedia. and conclude with an overview of programming for OS/2's rich multimedia platform. To access the Video Support, select either the Digital Video or Digital Video 2 object from the Multimedia folder. ΓòÉΓòÉΓòÉ 9.1. Video Support ΓòÉΓòÉΓòÉ Video has been available in the personal computer arena for quite some time. The major drawback up to now has been cost. Most of the video delivery solutions have either relied on expensive video sources, such as laser video disc, or have required expen sive video co-processor, such as the Digital Video Interactive (DVI) chips from Intel. For quite some time, the search has been on for an inexpensive method for delivering quality video on desktop systems. Recent breakthroughs in this area have been fueled by dramatic increases in processor speed and advances in operating system technology. The Software Motion Video Playback software that is included with OS/2 2.1 has been designed to allow pluggable Compressor/Decompressors, also known as CODECs. We have included two CODECs with OS/2, one for Indeo and the other for Ultimotion. Both of the se video formats can be found in files with the .AVI extension. Indeo is a CODEC that was developed by Intel and is based on the algorithms used in the DVI products. Much of the design of the Indeo CODEC was dictated by the existing algorithms used in the DVI chips. Ultimotion is a CODEC developed by IBM. Ultimotion was designed specifically for software motion video playback, and was optimized for the personal computer instruction set. Both of these algorithms are loosely based on a technique known as delta-frame encoding, a method of video compression. This video compression method compares each frame of video with the previous frame. As frames advance, only those pels that change nee d be stored. For example, in a head shot of someone reporting the evening news, only the area of the video window around the reporter's face change from frame to frame. The pels that make up the backdrop need only be stored once at the beginning of the clip, and then simply left in place as the rest of the video is played. If something in the background does change, it is noted during the video-compression phase and those changed pels are included in the delta frames along with the facial gestures. Generally, the more motion in a video clip, the more pel change there is from frame to frame. Ultimotion, for example, can easily handle a 320x240 frame size video clip at 15 frames per second on a standard desktop system. ΓòÉΓòÉΓòÉ 9.2. Multimedia Programming with OS/2 ΓòÉΓòÉΓòÉ What we've seen so far are all features of the sample applications that are shipped with OS/2. It is also quite easy to exploit all of the powerful underlying multimedia support in your own applications. The key to writing code to use OS/2 multimedia is a programming interface known as the Media Control Interface. Media Control Interface is a high-level application programming interface (API) that allows easy access to all of the multimedia features described previously The concept behind the design of Media Control Interface was to provide a simple, consistent int erface that allows control of a variety of multimedia devices. The same basic PLAY API is used for playback of Digital Audio, CD-DA, MIDI, and Software Motion Video. The Media Control Interface commands are all also available as a string interface. This creation of a prototype allows for easy inclusion of multimedia content in existing applications. For example, the following string "PLAY CDAUDIO FROM 10000 TO 20000" would caus e the CD-ROM player to start playing at the 10-second point (10 seconds = 10,000 milliseconds) and stop at the 20-second point. A REXX interface to Media Control Interface has also been included with the OS/2 multimedia support. Documentation, as well as some sample REXX command files, are included. ΓòÉΓòÉΓòÉ 9.3. Summary ΓòÉΓòÉΓòÉ This article presents just a sample of the multimedia features available in OS/2 2.1. The OS/2 2.1 Developer's Toolkit, MMPM/2, and MMPM/2 Developer's Toolkit are available on your Developer Connection CD-ROM. In addition, an evaluation copya of the Video IN product is also included on the CD-ROM. So, install the appropriate components and have a good time! ΓòÉΓòÉΓòÉ 9.3.1. About the Author ΓòÉΓòÉΓòÉ Gary G. Allran is the Manager of OS Technical Marketing and Support. Gary has held a variety of roles since joining IBM in 1982, including OS/2 Multimedia Evangelist and Audio Subsystem Architect. ΓòÉΓòÉΓòÉ 10. Modifying Your PM Programs for Pen for OS/2 ΓòÉΓòÉΓòÉ by Vera Dulaney and Kevin Lee Last quarter, we provided an overview of how to best use Pen for OS/2. This quarter, we pick up on that concept and describe how to modify a Presentation Manager (PM) program to be pen-aware and, if modification is not possible, we also describe how to write a gesture command handler for an existing PM program. ΓòÉΓòÉΓòÉ 10.1. To Recap... ΓòÉΓòÉΓòÉ Pen for OS/2 gives the computer users a much more intuitive pointing device over a mouse. Existing Presentation Manager (PM) applications can easily be modified to make use of the pen interface. When a menu item is selected from a PM application window, the WM_COMMAND message is sent to its window procedure. Similarly, in a Pen for OS/2 system, when a gesture is given on a PM window, the WM_RECO message is sent to its window procedure. Therefore, Pen for OS/2 performs the actions specified by the gesture. If your application wants to handle the gesture by itself, it must process the WM_RECO message, returning to PM with the RECO_PROCESSED message. If you do not want to modify your PM application to handle a gesture, your application was already distributed, or no way exists to recall, modify, or redistribute it, but you still want to handle a gesture within your application, you can write a separate command handler. Then, put this command handler name in the gesture setting of your application. When a gesture is given on your application window, Pen for OS/2 initiates this command handler to take care of the gesture. ΓòÉΓòÉΓòÉ 10.2. Recognizing the Pen ΓòÉΓòÉΓòÉ For all gestures given on an PM window (even if the gesture is not recognized by Pen for OS/2), the WM_RECO message is sent to the window program. Like other PM messages, the WM_RECO message has 2 parameters, mp1 and mp2. The mp1 parameter has the window coordinate of the hot spot of a gesture; the mp2 parameter has the address of RECODATA structure. Each gesture has its own hot spot. The WM_RECO message is sent to the window that has the hot spot. The RECODATA structure has 13 fields; however, this article explains only the two most common, HRECO and RECOID. For an explanation of the other fields, please see the PENPM.H file in Pen for OS/2 Developer's Toolkit, which is on your accompanying Developer Connection CD-ROM. The HRECO field is the Recognition subsystem handle. Pen for OS/2 Version 1.0 supports only the Gesture subsystem. Future Pen for OS/2 releases might also include support for the Voice subsystem. The RedQueryRecoSubsystem API takes the handle as input and returns the subsystem name, as well as the number of events in the subsystem. The RECOID field is an Event ID of the recognition subsystem. The RedRecoNameFromID API uses the HRECO and RECOID fields, and returns the event name. For example, if the HRECO is 1 and RECOID is 6, the Pigtail gesture name is returned. The application writer can do whatever is needed with the subsystem and its event ID. For the unrecognized gesture, a NULL event name will be returned by the RedRecoNameFromID API. While you process the WM_RECO message, do not give a message or a dialog box. This will cause a deadlock to occur. If you have to give the box, simply post a message to yourself, then give the box while you process the message. After you process the WM_RECO message, return to PM with RECO_PROCESSED. Then, Pen for OS/2 knows that the application has handled the gesture. The sample code shows the WM_RECO message handler in the client window. For more information, please check the WMRECO program in the Pen for OS/2 Developer's Toolkit sample program. #define RECO_MSG WM_USER + 1 MRESULT EXPENTRY ClientWndProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) { USHORT usXpos, usYpos; ULONG ulEventCnt; CHAR achRecoSubsys[15], achRecoEvent[15]; static RECODATA rcData; switch ( msg ) { case WM_RECO: /********************************************************************* * The MP1 has hot spot in window coordinate, NOT in screen * * coordinate. * *********************************************************************/ usXPos = SHORT1FROMMP( mp1 ); usYPos = SHORT2FROMMP( mp1 ); /********************************************************************* * The MP2 has pointer to RECODATA and copy it to local memory * * because it is good while the WM_RECO message is processed. * *********************************************************************/ rcData = * ( RECODATA * ) PVOIDFROMMP( mp2 ); /********************************************************************** * There are 3 pointers in RECODATA pointing to command, * * argument, and prefix command. You have to allocate memory * * to retrieve them while the WM_RECO message is processed. * **********************************************************************/ /********************************************************************* * Get the Reco subsystem name and number of events from handle. * *********************************************************************/ RedQueryRecoSubsystem( rcData.hReco, achRecoSubsys, &ulEventCnt ); /********************************************************************* * Get the Event Name. * *********************************************************************/ RedRecoNameFromID( hReco, rcData.rID, achRecoEvent ); /********************************************************************* * You can do whatever you would like to do with the gesture. * * If you have to give a message box, post a message to yourself * * Do NOT send the message. * *********************************************************************/ WinPostMsg( hwnd, RECO_MSG, mp1, mp2 ); return( ( MRESULT ) RECO_PROCESSED ); case RECO_MSG: /********************************************************************* * A message box can be given here without deadlock. * *********************************************************************/ } } ΓòÉΓòÉΓòÉ 10.3. Writing a Pen for OS/2 Command Handler ΓòÉΓòÉΓòÉ You can write a command handler for an application and put the handler name in the gesture setting of the application. When a gesture is given on the application window, Pen for OS/2 initiates the command handler, retrieve the RECODATA, and perform an action required for the gesture. For a subsequent gesture given on the application window, WM_RECO_COMMAND is sent to the command handler window procedure. In this way, any actions required for the gestures can be done by the handler, not by Pen for OS/2. The following explains how to assign the command handler to the gesture setting of the application: o On the Workplace Shell desktop, click the right mouse button on the application icon. o Select the right arrow in Open item, and then select Settings. The settings dialog window appears and the Gesture setting page is added by Pen for OS/2. In this page, from the listbox of all gestures, you can give your command handler name to any gestures. o To set a command handler to a gesture, highlight the gesture and select the Edit button. Another dialog window appears with Command and Parameters fields. You can put the command handler name (without the .EXE extension) in the Command field. If the command handler is not in a directory identified on the PATH= parameter in your CONFIG.SYS file, you must include its full path name. Any parameters put in the Parameters field are in argv of command handler. Several gestures can share one command handler or each gesture can have its own command handler. Up to 20 command handlers can run at any time. When the command handler is initiated, it registers itself as a command handler using the RedRegisterRecoCommand API. Pen for OS/2 saves the command handler name in its internal table. After the registration, it calls the RedRecoDataFromEnv API to retrieve the RECODATA structure. The Command, Parameter, and Prefix Command fields pointed to by three pointer fields in RECODATA are attached after the RECODATA, so this API must have a large buffer. Like a Pen-aware application, the command handler can use the HRECO and RECOID in RECODATA to retrieve subsystem and event names. When subsequent gesture is given on the application window, Pen for OS/2 checks the gesture setting of the subsequent gesture to get the command handler name and, if it cannot find the command handler in its internal table, it initiates another command handler. Otherwise it sends the WM_RECO_COMMAND message to the running command handler. The processing of this message is same as the WM_RECO message, except for the mp1 parameter. If any file is accessed inside the command handler, use the full path name of the file. The DosQueryCurrentDisk and DosQueryCurrentDir APIs usually give a root directory of the boot disk, but not always. An example of the Client Window procedure of a command handler follows. For command handler details, please see the RECODISP sample program in the Pen for OS/2 Developer's Toolkit. #define WM_RECO_INFO WM_USER + 2 #define CMD_STR "recocmd" #define ID_CMD 1 MRESULT EXPENTRY ClientWndProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) { ULONG nLen; static RECODATA *pRecodata; switch( msg ) { case WM_CREATE: { /***************************************************************** * Register Reco command handler in PenPM. * * If you have another command handler running and if you want to * * remove it, the RedQueryRecoCommand and * * RedDeregisterRecoCommand API's can be used. * *****************************************************************/ RedRegisterRecoCommand( CMD_STR, ID_CMD, hwnd ) ; /***************************************************************** * Retrieve RECODATA from environment. * * First put NULL for the buffer pointer to get the actual size. * * If NULL is given as buffer pointer, then NO error returned. * *****************************************************************/ nLen = 0; RedRecoDataFromEnv( NULL, &nLen ); /****************************************************************** * The actual length of data is returned in nLen. * ******************************************************************/ pRecodata = ( RECODATA * ) malloc( nLen ); RedRecoDataFromEnv( pRecodata, &nLen ); /******************************************************************* * When the RECODATA is retrieved from environment, the Command, * * Argument, and PrefixCommand are attached after the RECODATA. * * So, the pszCmd points after the RECODATA, the pszArg points * * after the command data, and so forth. * * All three data are terminated by NULL character. * * But the retrieval of RECODATA by WM_RECO_COMMAND message is * * quite different. Please check the message below. * *******************************************************************/ break; } case WM_RECO_COMMAND: { /******************************************************************* * Replace this message handling code with yours for your own * * command handler. Handling of this message is similar to that of * * the WM_RECO message for Pen for OS/2 aware application. * *******************************************************************/ /******************************************************************* * Copy the RECODATA. * *******************************************************************/ *pRecodata = * ( RECODATA * ) PVOIDFROMMP( mp2 ); /******************************************************************* * The RECODATA is retrieved, but the command, argument, and * * prefix command must be copied too. These data are valid * * while the WM_RECO_COMMAND message is processed. * *******************************************************************/ /******************************************************************* * Do NOT call WinMessageBox or WinDlgBox because deadlock can * * occur. Post a message to yourself, do NOT send it. * *******************************************************************/ WinPostMsg( hwnd, WM_RECO_INFO, NULL, NULL ); return( ( MRESULT ) ( TRUE ) ); } case WM_RECO_INFO: /******************************************************************* * A message or dialog box can be given here. * *******************************************************************/ return FALSE; } return FALSE; } ΓòÉΓòÉΓòÉ 10.3.1. About the Authors ΓòÉΓòÉΓòÉ Vera Dulaney is the Manager of Pen Development, where she manages both the development of Pen for OS/2 and the delivery of Pen and Speech to the Workplace OS platform. Kevin Lee is a Staff Programmer in the Mobil, Voice, and Pen Development. Keven has worked on Compilers, Toolkit Sample programs, and OS/2. ΓòÉΓòÉΓòÉ 11. Maximizing the Audio Support in OS/2 2.1 ΓòÉΓòÉΓòÉ by Linden deCarmo ΓòÉΓòÉΓòÉ 11.1. Introduction ΓòÉΓòÉΓòÉ One of the most notable additions to the OS/2 2.1 operating system is its exciting multimedia capabilities. This multimedia support, called MMPM/2, includes a robust, multihreaded transportation layer, seamless data translation support, and an ever-growing number of media drivers. Because considerable number of machines now come with audio cards, application developers must either take advantage of the new hardware or risk losing market share. This article describes how you can incorporate key audio features to enhance your product - whether it's a REXX utility, shareware game, or mission critical application ΓòÉΓòÉΓòÉ 11.2. Easy As a VCR ΓòÉΓòÉΓòÉ MMPM/2 uses the Media Control Interface as the primary method of incorporating multimedia into OS/2 programs. These commands are very similar to your VCR (for example, play, record, rewind, and stop), and if you use this 32-bit API set, your application will run not only on the current Intel x86 platform, but also RISC-based systems (such as the PowerPC) under Workplace OS. This portable API set has two primary interfaces: the string interface and the procedural interface. The string interface lets applications send command strings to OS/2 without having to write any C or Pascal code. This method is excellent for batch languages, as well as for quickly creating programs in C or C++ (MMPM/2 even comes with some excellent REXX command examples). For instance, the string in quotes below can be used with REXX to play an audio file. mciRxSendString("play \mmos2\sounds\laser.wav wait", 'RetSt', '0', '0') If you want to experiment with the string interface without the overhead of compiling a program or writing a command file the MMPM/2 toolkit comes with an excellent testing application, MCISTRNG, that lets you send string commands. Check out the MMPM/2 Toolkit that is available on your CD-ROM. ΓòÉΓòÉΓòÉ 11.3. Can REXX Learn New Tricks? ΓòÉΓòÉΓòÉ All string interface commands can be used from REXX through the mciRxSendString call. Syntax and theory of the string interface can be found in the Multimedia Presentation Programming Reference or Multimedia with REXX online reference provided with MMPM/2. The example command file that follows shows how to modify a makefile to boo if the compile is unsuccessful and cheer if things went well. nmake :main if ERRORLEVEL 1 goto error play FILE=\mmos2\sounds\cheer.wav goto quit :error play FILE=\mmos2\sounds\boo.wav :quit You can use the new Multimedia Control Interface clipboard functions with PMREXX, VisPro/REXX, or VX REXX programs to communicate with other programs and edit audio files with very little code. These clipboard commands also work on Ultimotion or Indeo v ideo files, if you have the Ultimedia Video IN product (the Video IN beta was included on the last Developer Connection and an evaluation copy is available on this quarter's CD-ROM). The following REXX example copies the start of the waveform (.WAV) file onto the clipboard and pastes that information repeatedly at the end of the file to create a Max Headroom effect. RXFUNCADD ( 'mciRxInit', 'MCIAPI', 'mciRxInit') InitRC=mciRxInit (); mciRxSendString("open \mmos2\sounds\laser.wav alias a wait", 'RetSt', '0', '0') mxiRxSendString("copy a from 0 to 3000 wait", 'RetSt', '0','0') mciRxSendString("seek a to end wait", 'RetSt', '0','0') mciRxSendString("paste a wait", 'RetSt', '0','0') mciRxSendString("paste a wait", 'RetSt', '0','0') mciRxSendString("paste a wait", 'RetSt', '0','0') ΓòÉΓòÉΓòÉ 11.4. Procedural Interface ΓòÉΓòÉΓòÉ The procedural interface is the traditional means for accessing MMPM/2. It is available from C, C++, Smalltalk, and other languages that support dynamic link libraries. The procedural interface (or the string interface from C or C++) gives the developer complete access to all multimedia commands and messages, notification of all events, and the ability to maximize the multithreaded nature of MMPM/2. ΓòÉΓòÉΓòÉ 11.5. Full Multimedia API ΓòÉΓòÉΓòÉ MMPM/2 contains a very sophisticated resource manager and is the first multimedia environment that lets an infinite number of applications simultaneously open an audio device. As a contrast to Windows, MMPM/2 does not force you to open and close the device on a constant basis to allow other applications to share the .WAV device. A good MMPM/2 program opens the device in a shareable mode and processes the MM_MCIPASSDEVICE message. If the MCI_OPEN_SHAREABLE flag is not passed to MCI_OPEN,other devices cannot use the device while you have it open. Unless you need the device exclusively, use the shareable flag when opening. If you must have the device exclusively for a period of time (for example, recording audio data), always open the device in shareable mode, send an MCI_ACQUIRE to obtain it exclusively, and perform the necessary action. Use MCI_RELEASE to release the device. If your application receives the MM_MCIPASSDEVICE message (with MCI_LOSING_USE in ulMsgParam2 field), another application has taken the device from you. Reacquire the device using MCI_ACQUIRE before sending another command. The following example illustrates this. /* * The next two messages are handled so that the audio recorder * application can participate in device sharing. We keep track of this device passing in * the fPassedDevice boolean variable. * * If we do not have access to the device when we receive an WM_ACTIVATE * message, then we will issue an acquire device command to gain * access to the device. * * For applications that are more complex * than this sample program, developers may wish to take * advantage of a more robust method of device sharing. * This can be done by using the MCI_ACQUIRE_QUEUE flag on * the MCI_ACQUIREDEVICE command. Please refer to the MMPM/2 * documentation for more information on this flag. */ case MM_MCIPASSDEVICE: if (SHORT1FROMMP(mp2) == MCI_GAINING_USE) /* GAINING USE */ { fPassed Device = FALSE /* Gaining control of device.*/ // Once we receive the gaining use message, we can send commands to the device. See the MMPM/2 // toolkit for more information. } else /* LOSING USE */ { fPassedDevice = TRUE; /* Losing control of device */ // Once we receive the losing use message, we can no longer send commands to // the device until we re-acquire it. } return ( WinDefSecondaryWindowProc( hwnd, msg, mp1, mp2 ) ); Although most Media Control Interface commands are available from the string interface, some are not. They require pointers or other items which don't translate into English. An example of such a command is MCI_COPY. The basic MCI_COPY command is available via the string interface; however, a more advanced version lets you actually transfer the contents of a buffer to the clipboard. The following code segment reads part of a .WAV file into a buffer so it can be copied into the clipboard. HMMIO hmmio; MCI_EDIT_PARMS mep; PVOID pBuffer; MMAUDIOHEADER mmaudioheader; USHORT usDeviceID; /* usDeviceID was obtained via MCI_OPEN */ /* mmaudioheader was filled in with mmioGetHeader call */ /* Read the info necessary to copy into the clipboard */ lReturnCode = mmioRead( hmmio, ( PSZ ) pBuffer, 60000 ); if ( lReturnCode == MMIO_ERROR ) { ulrc = mmioGetLastError( hmmio ); return ( ulrc ); } A final advantage of using the procedural interface (or the string interface from C or C++) over REXX is the ability to take advantage of the multithreaded nature of the MMPM/2. In the DOS world, programmers must constantly poll the device to find out it s current position in the file. By contrast, MMPM/2 offers a significant alternative to the polling approach - MCI_SETPOSITIONADVISE and MCI_SETCUEPOINT. Using MCI_SETPOSITIONADVISE, MMPM/2 informs applications on a periodic basis the device's media position when playing or recording an audio or video file (this is similar to the WM_TIMER message, but much more accurate, because it is media based). MCI_SET CUEPOINT lets you set up single a notification, rather than recurring notifications, about the media position of the audio device. ΓòÉΓòÉΓòÉ 11.6. Adventure is Just Beginning ΓòÉΓòÉΓòÉ We have only touched on the myriad of audio features available in the OS/2 2.1 operating system (not to mention the exciting software motion video support that will be covered in a future article). I encourage you to explore the multimedia toolkit and us e the appropriate APIs in order to bring your application into the exciting age of multimedia computing! ΓòÉΓòÉΓòÉ 11.6.1. About the Author ΓòÉΓòÉΓòÉ Linden deCarmo is a Senior Associate Programmer in the Workplace OS multimedia development and has been with IBM since 1991. He is an active supporter of multimedia developers on Internet, CompuServe, and the IBM BBS. He can be reached at lad@vnet.ibm.com. ΓòÉΓòÉΓòÉ 12. Looking for a great sound card? ΓòÉΓòÉΓòÉ Look no further...OS/2 2.1 comes with support for the following sound cards: Media Vision: Proaudio Spectrum, Proaudio Studio, Proaudio Basic IBM: Maudio adapter Creative Labs: SoundBlaster, SoundBlaster Pro, SoundBlaster 16 and SoundBlaster 16ASP ΓòÉΓòÉΓòÉ 13. 32-Bit OS/2 Exception Management ΓòÉΓòÉΓòÉ by Monte Copeland Under 16-bit OS/2 architecture, a process cannot handle access violations and certain other exceptions; the system invariably terminates the process. The only choice a program has is to register an exit-list function using the DosExitList() API. Then, at process-termination time, OS/2 calls each of the registered exit-list functions, and they perform cleanup before the termination of the process. This approach is process-granular. It allows for cleanup, but not recovery. Under the 32-bit OS/2 environment, the approach is thread-granular. OS/2 keeps a chain of exception handler functions for every thread. When a thread causes an exception, OS/2 walks the chain and calls each of the functions until one reports "handled". If no function handles the exception, the system takes default action. For many exceptions, the default action is process termination. The exception management APIs are new in the 32-bit OS/2 operating system. They are available to 32-bit executables and dynamic link libraries (DLLs). OS/2 designers intend for 32-bit exception management to be hardware-independent, to be a superset of traditional 16-bit exit-list processing, to encompass 16-bit signals, and to provide thread-granular recovery of exceptions. Figure 1. Chain of Exception Registration Records. A pointer to the first record in the chain is stored in the thread information block (TIB) structure. This article describes the following exception handler scenarios: o A function recovers from the error and reports "handled" by returning XCPT_CONTINUE_EXECUTION. The function continues to execute. o A function does not handle the exception and reports "not handled" by returning XCPT_CONTINUE_SEARCH. Other handlers in the chain get a chance to handle the exception. o The third option is graceful failure. This approach is nicely suited for worker functions in EXEs and DLLs that must remain robust in spite of bad parameters or killed threads. ΓòÉΓòÉΓòÉ 13.1. Adding a Handler to the Chain ΓòÉΓòÉΓòÉ Use the API DosSetExceptionHandler() to insert an exception handler for the calling thread. This API performs an insert-at-head operation; therefore, the last handler inserted is the first one called at exception time. It is quite possible for one handler to serve numerous threads, but each thread must call DosSetExceptionHandler(). The OS/2 Developer's Toolkit defines a exception registration record structure called EXCEPTIONREGISTRATIONRECORD, but you can define your own. See Figure 1. (More later on why that is a good thing to do.) The absolute minimum exception registration record is a structure that contains two 32-bit pointers: a pointer to the next exception registration record in the chain and a pointer to the handler function. // Bare-bones exception registration record // See also \toolkt20\c\os2h\bsexcpt.h typedef struct _regrec { PVOID pNext; PFN pfnHandler; } REGREC; typedef REGREC *PREGREC; // A prototype for an exception handler function ULONG _System HandlerFunction( PEXCEPTIONREPORTRECORD p1, PREGREC p2, PCONTEXTRECOR D p3, PVOID p4 ); Figure 1. REGREC definition and handler function prototype Assign the pointer regrec.pfnHandler then call the DosSetExceptionHandler() API. The system assigns regrec.pNext. See Figure 2. REGREC regrec; . . . regrec.pfnHandler = (PFN)HandlerFunction; rc = DosSetExceptionHandler( (PEXCEPTIONREGISTRATIONRECORD)®rec ); assert( 0 == rc ); Figure 2. Code fragment shows REGREC declaration and use. ΓòÉΓòÉΓòÉ 13.2. Recoverable Exceptions ΓòÉΓòÉΓòÉ When an exception handler returns handled, the handler has recovered from the exception, and execution resumes at the point of the exception. One scenario involving recoverable exceptions is NPX (80387) emulation. For example, compile a program with hardware floating-point instructions, and run it on a system without a floating-point coprocessor. Executing the floating-point instruction causes OS/2 to raise a coprocessor-not-available exception. An exception handler emulates the floating-point instruction in software. In fact, this scenario describes one of OS/2's default exception handlers. Code compiled with floating-point instructions runs under OS/2 on systems without a math coprocessor. Another scenario involves sparse allocation of memory. In 32-bit OS/2, DosAllocMem() allocates memory in a collection of 4K pages. (The size of every DosAllocMem allocation is always rounded up to the next higher multiple of 4K.) The pages within a memory allocation can have different attributes: notable ones are committed and invalid. The DosSetMem() API lets you commit individual pages within a memory allocation. Sample Program 1 uses the DosSetMem() API in an exception handler to commit memory as it is referenced. The sample program allocates a memory object such that no pages are committed. Then, it writes to the memory. This causes a page fault, and the system delivers an exception to the handler. The handler commits the memory, returns handled, and the system restarts the instruction. /* SPARSE.C. This program allocates a one MB memory object but commits no pages. */ The program then writes to that memory which is invalid, and this causes a trap. The handler commits the invalid page and resumes execution. /* Compile and link this program with: icc /Ss sparse.c */ // os2 includes #define INCL_DOS #define INCL_ERRORS #include <os2.h> // c includes #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> // Exception handler registration record typedef struct _regrec { PVOID pNext; PFN pfnHandler; } REGREC; typedef REGREC *PREGREC; // ---------------------------------------------------------------------- ULONG _System Handler( PEXCEPTIONREPORTRECORD p1, PREGREC p2, PCONTEXTRECORD p3, PVOID pv ) { // Interested in access violation if( p1->ExceptionNum == XCPT_ACCESS_VIOLATION ) { assert( p1->ExceptionInfo[0] == XCPT_WRITE_ACCESS ); // Try to commit the referenced page if( 0 == DosSetMem( (PVOID)p1->ExceptionInfo[1], 1, PAG_COMMIT|PAG_WRITE )) { // Successful commit; resume execution return XCPT_CONTINUE_EXECUTION; } } // Not handled, let other handlers in the chain have the exception return XCPT_CONTINUE_SEARCH; } // ---------------------------------------------------------------------- int main ( void ) { APIRET rc; PCHAR pchar; PSZ psz; PVOID pvBase; REGREC regrec; // Insert exception handler into the chain of handlers for this thread regrec.pfnHandler = (PFN)Handler; rc = DosSetExceptionHandler( (PEXCEPTIONREGISTRATIONRECORD) ®rec ); assert( rc == 0 ); // Allocate a memory object without committing any of it; // Note lack of PAG_COMMIT flag rc = DosAllocMem( &pvBase, 1048576, PAG_WRITE ); assert( rc == 0 ); // This causes an exception since the page is not committed pchar = (PCHAR)pvBase; *pchar = 'a'; // This string copy causes two more exceptions psz = (PSZ)pvBase + (4096 + 4092); strcpy( psz, "This string crosses a 4K page boundary." ); // Reference the memory printf( "%c\n", *pchar ); printf( "%s\n", psz ); // Free memory object rc = DosFreeMem( pvBase ); assert( rc == 0 ); // Unlink handler before returning rc = DosUnsetExceptionHandler( (PEXCEPTIONREGISTRATIONRECORD) ®rec ); assert( rc == 0 ); return 0; } Sample Program 1: sparse.c ΓòÉΓòÉΓòÉ 13.3. Graceful Failure - When Good Threads Go Bad ΓòÉΓòÉΓòÉ Some exceptions are not so easy to restart. Can an exception handler fix a bad pointer during a general protection fault? Probably not. Should an exception handler choose a new divisor after division by zero? No. The operation must fail - but gracefully. Graceful failure is important to APIs. API worker functions must return sensible, failing result codes to the caller in error situations. Worker functions use an exception handler like a safety net. If a thread goes bad while executing a function, the safety net is there to catch it. For the net to be in place, the worker function registers a handler at function entry and removes it at function exit. The overhead is small, and it is worth the robustness gained. ΓòÉΓòÉΓòÉ 13.4. Getting There from Here ΓòÉΓòÉΓòÉ In Sample Program 1, OS/2 lifts the thread from the point of the exception, makes it call the exception handler, then drops it back on the faulting instruction. This is no good for graceful failure. Yes, it is desirable to jump back to the worker function, but not at the point of the exception! Instead, the thread must jump from the exception handler function to a known point in the worker function. This is an interfunctional GOTO. Debates still rage about GOTO, but most programmers accept them when it comes to exception management. Code interfunctional GOTO's in C, using setjmp() and longjmp(). Use setjmp() to record the state of the thread at the beginning of the worker function. Later, from the exception handler function, use longjmp() to return the thread to the saved state. State information is stored in a variable of type jmp_buf. The exception handler function must have addressability to the jmp_buf to use it on the call to longjmp(). The stack frame of the worker function is the ideal place to hold the jmp_buf and the exception registration record. Also, a pointer to the except ion registration record is one of the parameters to the exception handler function. Therefore, the way for an exception handler function to get the address of a jmp_buf is to put a jmp_buf at the end of the exception registration record. See Figure 3. // User-extended exception registration record typedef struct _regrec { PVOID pNext; PFN pfnHandler; jmp_buf jmpWorker; } REGREC; typedef REGREC *PREGREC; Figure 3. Extended REGREC definition Sample Program 2 consists of the main() function, a worker function, and an exception handler function. It shows how the worker function always returns a sensible result code in spite of bad parameters. /* WORKER.C. This program shows how a worker function can use an exception */ /* handler like a safety net for calling threads. Compile and link this */ /* program with: icc /ss worker.c */ // os2 includes #define INCL_DOS #define INCL_ERRORS #include <os2.h> // c includes #include <stdio.h> #include <stdlib.h> #include <string.h> #include <setjmp.h> #include <assert.h> // User-extended exception registration record typedef struct _regrec { PVOID pNext; PFN pfnHandler; jmp_buf jmpWorker; } REGREC; typedef REGREC *PREGREC; // ---------------------------------------------------------------------- ULONG _System Handler( PEXCEPTIONREPORTRECORD p1, PREGREC p2, PCONTEXTRECORD p3, PVOID pv ) { switch( p1->ExceptionNum ) { case XCPT_ACCESS_VIOLATION: case XCPT_INTEGER_DIVIDE_BY_ZERO: case XCPT_INTEGER_OVERFLOW: case XCPT_PROCESS_TERMINATE: // Killed thread case case XCPT_ASYNC_PROCESS_TERMINATE: // Killed thread case // Interested in this one longjmp( p2->jmpWorker, p1->ExceptionNum ); default: break; } // Not handled return XCPT_CONTINUE_SEARCH; } // ---------------------------------------------------------------------- // Returns TRUE for success, FALSE for failure LONG _System WorkerFunction( PCHAR pch ) { LONG rc; LONG rcResult; ULONG ulException; REGREC regrec; // Set a handler regrec.pfnHandler = (PFN)Handler; rc = DosSetExceptionHandler( (PEXCEPTIONREGISTRATIONRECORD) ®rec ); assert( rc == 0 ); // Store a known thread state ulException = setjmp( regrec.jmpWorker ); if( ulException ) { // Clean up here: free memory allocations, release mutex sems, etc. // Get the handler off the chain rc = DosUnsetExceptionHandler( (PEXCEPTIONREGISTRATIONRECORD) ®rec ); assert( rc == 0 ); // Check for the killed-thread case switch( ulException ) { case XCPT_PROCESS_TERMINATE: case XCPT_ASYNC_PROCESS_TERMINATE: // Clean up done above and thread really wants to die DosExit( EXIT_THREAD, 0 ); break; } // Set a failing result code rcResult = FALSE; goto depart; } // Dereference the supplied pointer *pch = 'a'; rc = DosUnsetExceptionHandler( (PEXCEPTIONREGISTRATIONRECORD) ®rec ); assert( rc == 0 ); rcResult = TRUE; depart: return rcResult; } // ---------------------------------------------------------------------- int main ( void ) { CHAR szWork[ 16 ]; LONG rc; // Try worker function with a good pointer rc = WorkerFunction( szWork ); printf( "Good pointer returns %d\n", rc ); // Try worker function with a bad pointer rc = WorkerFunction( NULL ); printf( "Bad pointer returns %d\n", rc ); return 0; } Sample Program 2: worker.c Notes about Sample Program 2: o The Killed Thread: The code in Sample Program 2 shows how to handle the killed thread case. Even though there are no killed threads in Sample Program 2, the technique is critical to exported worker functions in DLLs where the client process may use DosKillThread with abandon. o Nested Exceptions: At exception time, OS/2 inserts a handler at the head of the chain before it invokes the remaining handlers on the chain in order to detect nested exceptions. (A nested exception is one that occurs in an exception handler.) The IBM C Set/2 implementation of longjmp() correctly unwinds the system's nested exception handler. o Sparse Allocations in OS/2: When there is no COMMIT option on the MEMMAN statement in CONFIG.SYS, OS/2 handles every memory allocation in a sparse manner similar to Sample Program 1. This technique is called lazy commit. When the COMMIT option is present on MEMMAN, commits are never deferred. ΓòÉΓòÉΓòÉ 13.5. Future Considerations ΓòÉΓòÉΓòÉ Rest assured that this exception management strategy is portable to future versions of OS/2. It uses 32-bit APIs, ANSI C runtime routines, and no assembler code. ΓòÉΓòÉΓòÉ 13.5.1. About the Author ΓòÉΓòÉΓòÉ Monte Copeland is a Staff Programmer in OS/2 Print Driver Development. He has been programming OS/2 applications since 1987 when he joined IBM. Monte frequently speaks about OS/2 programming at IBM's OS/2 technical conferences. ΓòÉΓòÉΓòÉ 14. Communication between OS/2 and Windows Processes ΓòÉΓòÉΓòÉ by David Kenner As part of The Developer Connection team, part of my job is to travel to the technical seminars and talk to the development community. Frequently, I give a presentation on the architecture of virtual device drivers (VDDs), how they fit into the OS/2 architecture, and how to build them. During the Question and Answer session that follows my presentation, the same question would consistently come up: What is the recommended interprocess communication (IPC) mechanism for Windows and OS/2 processes to communicate? The answer: Use named pipes. Several named pipe APIs exist that would be appropriate for this. Typically, the OS/2 process creates the pipe, and the DOS or Windows process opens the other end of the pipe to read or write to it. This mechanism is used in OS/2 2.0 for dynamic data exchange (DDE) support. It became clear after talking to developers that a better mechanism is needed to allow for larger amounts of data to go back and forth between the processes. Because named pipes use the file system, the transfer rate was limited by the speed of the target system. So I set off to investigate how we could improve on the existing mechanism. ΓòÉΓòÉΓòÉ 14.1. The Journey ΓòÉΓòÉΓòÉ First, my research took me into the bowels of a OS/2 VDD named VWIN.SYS. Within VWIN.SYS, a lot of the logical interprocess communication (IPC) that I needed to do already resides. VWIN.SYS is the VDD that allows for windowed WIN-OS/2 sessions or seamless OS/2. Since VWIN.SYS was a proven mechanism for accomplishing this, I followed the logic of this VDD. What we must do was to use our new VDD (based on VWIN.SYS) as the interface layer between our WIN-OS/2 process and our OS/2 process. We construct a VDD that lets us send messages in either direction, and receive responses back to the originating process, if required. We wanted our VDD to be fairly generic; that is, it must be structured to queue up messages and notify the destination process that a message is waiting. Part of the message data includes the originating process identification (PID), so we optionally can return a message to the originator. Our VDD allocates memory from the system arena for each new message in the queue. Because each message put into or extracted from our message queue is performed in the context of the currently executing thread, the copy is performed while the correct LDT is active. During message posting, each process copies the message data from a portion of its own address space to the the global data space of the VDD. If the process is extracting a message, it copies the message data into its local data space. This allows us to avoid the same context issue. Start off with the OS/2 side of the interface. We have to set up a way for the OS/2 application to be able to talk to the VDD. Do this by exporting an interface using the VDHRegisterVDD service. In our VDD, we will set up an interface that our OS/2 application can use to wait for any message data. Now our OS/2 process can use the DosOpenVdd and DosRequestVDD to talk to the VDD. It's up to the application developer to define the interface between the OS/2 process and the VDD. Typically, the interface mechanism is contained in another thread. This thread is blocked until messages are sent. The thread will block on the DosRequestVDD when the command packet that the VDD receives specifies WAITE. ΓòÉΓòÉΓòÉ 14.2. The Details ΓòÉΓòÉΓòÉ We will use a set of logical interfaces that can be mapped to the set of OS/2 and VDH services as follows: OpenVirtQueue: Within our OS/2 application, we will use two system APIs to accomplish this. Our application will use the DosOpenVdd API and the DosRequestVDD API. Start, by opening our VDD with the DosOpenVDD. From this call, we get a handle to our VDD. Now that we have the handle to our VDD, we can use the DosRequestVDD service to call into the VDD and perform any preprocess initialization for us. In our VDD, for example we will configure a message queueing mechanism. The OpenVirtQueue routine is shown in Sample Program 1. /****************************************************************************/ /*OpenVirtQueue */ /* */ /* */ /*A service routine that will allow us to do our initilization with the VDD */ /****************************************************************************/ APIRET OpenVirtQueue(VOID) { APIRET apiRet; /* *See if our VDD is alive and if so get *a handle that we may use later */ if(apiRet = DosOpenVDD(VDDNAME,&HandleToVDD) ) { return(apiRet); } /* *Call into our VDD so we perform any initialization *we need to do at this time. */ if(apiRet = DosRequestVDD(HandleToVDD, 0, INIT_COMMAND, 0, NULL, 0, NULL) ) { return(apiRet); } return(apiRet); } Sample Program 1. OpenVirtQueue. WriteVirtQueue: This is the mechanism in the VDD that lets us send information back to the WIN-OS/2 process. Again, we will use the DosRequestVDD service to call into our VDD. We will send a command that corresponds to our worker routine inside our VDD. Our worker routine will post a message to our internal queue, and in turn, post a message back to the Windows message queue. (See Sample Program 2.) /****************************************************************************/ /*WriteVirtQueue */ /* */ /* */ /*A service routine that will allow us to send our message data to the VDD */ /* */ /* */ /* */ /****************************************************************************/ APIRET WriteVirtQueue(PVOID pvMessageToSend, ULONG ulCount, SGID SessionId) { APIRET apiRet; if(apiRet = DosRequestVDD(HandleToVDD, SessionId, POST_MESSAGE, ulCount, pvMessageToSend, 0, NULL) ) { return(apiRet); } return(apiRet); } Sample Program 2. WriteVirtQueue ReadVirtQueue: This is our mechanism in the VDD that lets our thread block and wait for any message data. We will set up a protocol with the VDD, so that when the application calls into the VDD using the DosRequestVDD API, the VDD will block using the VDHWaitEventSem. When we have a message from the WIN-OS2 side, we clear the semaphore and copy the data into the buffer that was passed by the OS/2 application using DosOpenVdd. See Sample Program 3. /****************************************************************************/ /*ReadVirtQueue */ /* */ /* */ /*This routine is set up as separate thread that will read messages,process */ /*them,and then continue to block until additional messages come in.The */ /*block mechansim is accomplished through the semaphore in our VDD. */ /* */ /*Note: */ /*There is no error return. All error messages are handled before the */ /*thread terminates. */ /* */ /****************************************************************************/ VOID ReadVirtQueue(VOID) { APIRET apiRet; PVOID pvMessage; CHAR CommandToSend[SIZ_COMMAND_BUF]; do { /* *Block until we get any message *data */ if(apiRet = DosRequestVDD(HandleToVDD, 0, READ_QUEUE, strlen(CommandToSend), CommandToSend, sizeof(MessageBuffer), &MessageBuffer) ) { break; } /* *Do all of our message processing */ apiRet = ProcessMessageData(MessageBuffer); }while(!apiRet); /* *Handle any error that was encountered *during our polling */ /* *Do any other clean up we need to do *and get out */ _endthread(); } Sample Program 3. ReadVirtQueue We now have a mechanism to call into our VDD, receive messages, and post messages. Our worker routines that do most of our work for us are within the VDD. Stay tuned to the next issue where we'll discuss the internal routines that we will use in our VDD and our interfaces in the WINOS/2 process. Till then... ΓòÉΓòÉΓòÉ 14.2.1. About the Author ΓòÉΓòÉΓòÉ David Kenner is the Project Leader for The Developer Connection for OS/2. David frequently speaks at IBM's OS/2 technical conferences on Virtual Device Driver Design. ΓòÉΓòÉΓòÉ 15. Migrating Windows Applications to OS/2: Making it Work ΓòÉΓòÉΓòÉ by Jeff English One Up Corporation Migrating Windows source code to OS/2 is doable! It is, however, an involved process that requires knowledge of both the Windows and OS/2 environments, as well as the many differences in the APIs. The right set of tools can make the porting process easier. With the increasing success of OS/2, it is becoming paramount to many application developers to have native applications on multiple platforms. For many, this means migrating their existing Windows application source to OS/2. Cross-platform conversion of source code is a doable, albeit time-consuming process. ΓòÉΓòÉΓòÉ 15.1. Windows to OS/2 Porting - The Programming Perspective ΓòÉΓòÉΓòÉ Both Windows and OS/2 are message-based environments. However, the formats of these messages, as well as the APIs, differ substantially between the two. To solve the porting problem, one must handle those areas that do not overlap. There are also some conceptual differences in how things operate. For example, Windows relies on the concepts of brushes and pens for many of its drawing primitives. OS/2 relies on the concepts of bundles and attributes. A line bundle defines the drawing attributes and an area or image bundle defines the fill attributes. A conceptual difference such as this can significantly alter the logic of the application when ported to OS/2. The following is a list of some of the most common major issues: o Conversion from 16- to 32-bit application code o Preemptive multitasking o Multiple Document Interface (MDI) o GDI (Windows) vs. GPI (OS/2) o Printing and Device Driver dependencies o Window class styles and use of the class device context o Message notification and message order dependencies o Resource and data sharing among instances of an application or DLL o Conversion from 16-bit segmented memory model to 32-bit flat memory model o OLE support How much the application exploits and depends on these items will affect how easy the migration will be. Separating these features into platform dependent objects is one solution to reducing the effort of porting. ΓòÉΓòÉΓòÉ 15.2. Porting Tools ΓòÉΓòÉΓòÉ Many tools are available today that assist in some of the phases of the porting process. Tools, such as GREP and Seek-and-Scan, can help identify individual features in the source. Basic text editors can perform simple replacement of text. More sophisticated editors, such as SourceLink, provide hyper-link access for source replacement. A suite of tools developed by One Up Corporation and currently being enhanced and expanded, greatly assist the migration process in all phases of the porting process. ΓòÉΓòÉΓòÉ 15.3. Summary ΓòÉΓòÉΓòÉ Porting of source code is much more than attempting to map APIs from one platform to another. The port can become more difficult if the source code includes features that must be redesigned on the target platform. However, with the a complete understand ing of both the Windows and OS/2 programming environments and right tools, this process can be much easier. ΓòÉΓòÉΓòÉ 15.3.1. About the Author ΓòÉΓòÉΓòÉ Jeff English is a Staff Programmer for One Up Corporation and the co-author of the book Real-World Programming for OS/2 2.1. One Up Corporation is a leader in OS/2 products, education, and application expertise. One-Up produces the SMART (Source Migration and Reporting Tool) Toolset, which is a collection of advanced porting tools. For more information, call 1-800-678-0187. ΓòÉΓòÉΓòÉ 16. The Five Phases of the Porting Process ΓòÉΓòÉΓòÉ The process of porting source code is comprised of five phases, some of which overlap: Analysis, Automated Code Replacement, Computer-Assisted Code Replacement, Implementation of Unsupported Features, and Addition of Platform Specific Features. Automated tools can help process the first three phases; while additional tools can assist with the last two. ΓòÉΓòÉΓòÉ 16.1. Phase 1: Analysis ΓòÉΓòÉΓòÉ Analysis of the code to identify and report all environment specific issues and amount of porting effort required. This includes a breakdown of all API calls, type definitions, symbols, and messages. This also includes their frequency of occurrence and difficulty of porting. The analysis provides a detailed look at your source and what specific features of the environment are being used. ΓòÉΓòÉΓòÉ 16.2. Phase 2: Automated Code Replacement ΓòÉΓòÉΓòÉ This phase includes automated code replacement of those items that have a one-to-one mapping from the source to target environment. Also included in this phase is the conversion of resource files. ΓòÉΓòÉΓòÉ 16.3. Phase 3: Computer-Assisted Code Replacement ΓòÉΓòÉΓòÉ This phase includes interactive code replacement with input from an application developer for those source items that have an equivalent feature in the target environment, yet require a decision as to either the original intent of the source or which of several choices to use in the target environment. ΓòÉΓòÉΓòÉ 16.4. Phase 4: Implementation of Unsupported Features ΓòÉΓòÉΓòÉ There will ultimately be some features of the source environment that are not directly supported in the target environment. In some cases it may be possible to simulate it, and in other cases it will not be possible. The developer will have to provide input in order to make the changes. ΓòÉΓòÉΓòÉ 16.5. Phase 5: Addition of Platform Specific Features ΓòÉΓòÉΓòÉ Tighter integration of the application with the target environment might be desirable from a marketing or even coding standpoint. This adds features that might make it more difficult to port to other platforms, but can add significant benefit to the end user. ΓòÉΓòÉΓòÉ 17. New Tricks for Dynamic Linking On The OS/2 2.x Operating System ΓòÉΓòÉΓòÉ by John Keenleyside Dynamic linking is not a new concept. Now, IBM has added some new features for 32-bit dynamic link libraries (DLLs). It is to build and use 32-bit DLLs on the OS/2 2.x operating system, especially if you use the IBM C Set ++ compiler. ΓòÉΓòÉΓòÉ 17.1. Building 32-bit DLLs ΓòÉΓòÉΓòÉ Building DLLs is straightforward in OS/2 once you understand the constraints. You build from source files containing the data or functions you want to include in the DLL. Each function or data item you want to export from the DLL must have external scope. You also need a module definition file. The OS/2 linker uses this file while linking the compiled objects to create a DLL. Basically, it's a plain text file that describes the name, attributes of segments, exported names or ordinals, imported names or ordinals, and other characteristics for the DLL. (Ordinals are numbers you can assign to exported functions.) ΓòÉΓòÉΓòÉ 17.2. Using 32-bit DLLs ΓòÉΓòÉΓòÉ Dynamic linking comes in two flavors: o Load-time dynamic linking, which resolves external references within a segment at the time the segment is loaded o Runtime dynamic linking, which does not resolve references within a code segment until the actual code is executed. To use a DLL, write the source file for the program or DLL that will use it. Refer to the functions or variables as if they were going to be statically linked into the program or DLL. Then, at link-edit time, tell the linker that some function or variable reference is a dynamic reference to a DLL and will be resolved at runtime. OS/2 2.x lets you communicate this information to the linker as follows: o Create a module definition file for the program or DLL that is going to use the DLL. Specify the imported names or ordinals under the keyword IMPORTS. o Use the IMPLIB utility from the OS/2 Developer's Toolkit to create an import library for the linker. It will contain a list of the exported names or ordinals for the DLL. Create the import library from the module definition file or the DLL itself. This is the preferred approach, because it eliminates the need to create a module definition file. It also keeps the DLL independent from your application programs, so you can use it again. o Even easier, IBM C Set ++ will do it all automatically. Like many C/C++ compilers, the IBM C Set ++ compiler supports the _Export keyword. But it also supports the import and export pragmas. This lets you specify exports and imports within the source code itself - especially useful for C++ programmers who want to export classes from their DLLs but don't want the hassle of figuring out all the mangled names to export. The following shows a bit-counting function you can build into a DLL. It also provides a small application source (Main.C) file that shows you how to call the bitcount() function. Using the C Set ++ compiler, the command file builds the DLL and the application program. /* From BITS.C */ /* This function will count the number of 1 bits in n. */ unsigned int bitcount(unsigned int n) { unsigned int count; for (count = 0; n; n >>= 1) if (n & 1) count++; return count; } /* From BITS.DEF */ LIBRARY BITS INITINSTANCE TERMINSTANCE DATA MULTIPLE NONSHARED EXPORTS bitcount /* From MAIN.C */ #include <stdio.h> unsigned int bitcount(unsigned int n); int main(void) { printf("The number of 1 bits in %u is %u\n", 123, bitcount(123)); return 0; } /* From BUILD.CMD */ /* This is a REXX command file. */ /* Compile and link-edit BITS.C to create BITS.DLL */ 'ICC /Ge- /O+ BITS.C BITS.DEF' /* Create the import library for BITS.DLL */ 'IMPLIB BITS.LIB BITS.DEF' /* Compile and link-edit MAIN.C to create MAIN.EXE */ 'ICC /O+ MAIN.C BITS.LIB' Sample Program 1. Simple Bit-Counting Function ΓòÉΓòÉΓòÉ 17.3. Initialization and Termination ΓòÉΓòÉΓòÉ When you load a DLL in OS/2 2.x, you might need to allocate memory and initialize data and other resources before you can call code within the DLL. Then, after an application is finished using a DLL, you might need to free up resources such as memory. The C Set ++ libraries provide functions to initialize and terminate the C/C++ runtime environment. The function _CRT_init() initializes the C runtime environment, and the function __ctordtorInit calls any C++ constructors that are required. The __ctordt orTerm function calls the C++ destructors, and the _CRT_term function terminates the C runtime environment. You can export the initialization and termination functions from the DLL, so each application can call them. The initialization functions are called before any other functions within the DLL. The termination functions are called just before the applicati on is finished with the DLL. This makes the DLL dependent on the applications that use it. Fortunately, another way exists for OS/2 to call a function within the DLL when it is loaded and when an application tells the operating system that it is finished with a DLL. A DLL can have an entry point just like an executable. This entry point is called when the DLL is loaded and when it is unloaded. This process is called global initialization and termination. The entry point also can be called each time a new process acc esses a DLL or is finished with the DLL. This process is called instance initialization and termination. The whole initialization and termination routine becomes automatic. ΓòÉΓòÉΓòÉ 17.4. A New Way to Use Entry Points ΓòÉΓòÉΓòÉ The OS/2 2.x operating system also provides a new feature for the termination of 32-bit DLLs. In OS/2 1.x, the entry point was called only for initialization. But if the entry-point routine is in a 32-bit code segment (as in OS/2 2.x), it also will be called for termination. For the DLL entry point function to determine whether it is being called for initialization or termination, the loader passes a flag value to it. If the flag is 0, it is being called for initialization. If the flag is 1, it is being called for termination. The module handle for the DLL also is passed to the entry-point function. The following describes the contents of the stack and the values of the 80x86 registers when the entry-point function is called. Register values at LX format DLL initialization and termination: EIP = DLL entry point address ESP = Current stack pointer for thread that is loading the DLL EAX = EBX = ECX = EDX = ESI = EDI = EBP = 0 CS = Code selector for base of linear address space DS = ES = SS = Data selector for base of linear address space FS = Data selector of base of the Thread Information Block (TIB) for the thread that is loading the DLL GS = 0 Stack contents at DLL initialization: [ESP+0] = Return address to system where the value of EAX is the return code [ESP+4] = Module handle for the DLL [ESP+8] = 0 which means that the DLL entry point is being called for initialization Stack contents at DLL termination: [ESP+0] = Return address to system where the value of EAX is the return code [ESP+4] = Module handle for the DLL [ESP+8] = 1 which means that the DLL entry point is being called for termination Note: The stack contents at DLL initialization and termination follows the system calling convention except that AL is not set to the number of DWORDS of parameters passed. The entry-point function can be written in a high-level language like C, but it must have system linkage, because it is called from the operating system. Also, because the return value of this function is returned in the EAX register, an unsigned long return type is appropriate. If you are using the C Set ++ compiler, the prototype for this function is simple: unsigned long _System entry(unsigned long hModule, unsigned long ulFlag) OS/2 automatically confirms your results. A non-zero return value tells the loader that the DLL initialization was successful. A zero return value tells the loader that an error occurred. ΓòÉΓòÉΓòÉ 17.5. A New Way to Specify and Set Entry Points ΓòÉΓòÉΓòÉ The entry point is typically specified by the module end record within an object module that is linked into the DLL. With most compilers, you generate the module end record using a small assembler module, as follows. TITLE DLLSTUB.ASM .386 .387 CODE32 SEGMENT DWORD USE32 PUBLIC 'CODE' CODE32 ENDS DATA32 SEGMENT DWORD USE32 PUBLIC 'DATA' DATA32 ENDS CONST32 SEGMENT DWORD USE32 PUBLIC 'CONST' CONST32 ENDS BSS32 SEGMENT DWORD USE32 PUBLIC 'BSS' BSS32 ENDS DGROUP GROUP CONST32, BSS32, DATA32 ASSUME CS:FLAT, DS:FLAT, SS:FLAT, ES:FLAT EXTRN entry:PROC END entry C Set ++ makes it easier to specify the entry point. It gives you the object module to set the entry point in its runtime libraries. All you do is name the entry-point function _DLL_InitTerm. A default _DLL_InitTerm() function calls the initialization an d termination functions. C Set ++ also provides the pragma, #pragma entry. This new feature lets you set the entry point for a module using the C language rather than assembler, so you can pick the entry-point function name. It also means that you don't have to use the DLL genera tion option (/Ge-) when compiling the source files for the DLL. You decide at link-edit time, rather than at compile time, whether to put the objects into a DLL or into an application. The following shows you how to write a DLL entry-point function using the features of C Set ++. The application program provided in the listing uses runtime dynamic linking. /* From DLLENTRY.C */ #pragma strings(readonly) #define INCL_DOSFILEMGR #define INCL_DOSMODULEMGR #include <os2.h> #include <string.h> int _dllentry = 1; /* just in case an object is compiled with /Ge- */ char name[CCHMAXPATH]; #pragma entry(entry) unsigned long _System entry(unsigned long hModule, unsigned long ulFlag) { APIRET rc; unsigned long ulBytesWritten; rc = DosQueryModuleName(hModule, CCHMAXPATH, name); if (!rc) { if (ulFlag == 0) { rc = DosWrite(1, name, strlen(name), &ulBytesWritten); rc = DosWrite(1, " initialized.\r\n", 15, &ulBytesWritten); } else { rc = DosWrite(1, name, strlen(name), &ulBytesWritten); rc = DosWrite(1, " terminated.\r\n", 14, &ulBytesWritten); } } return !rc; /* non-zero means DLL init/term was successful */ } void hello(void) { unsigned long ulBytesWritten; DosWrite(1, "Hello there\r\n", 13, &ulBytesWritten); return; } /* From SIMPLE.DEF */ LIBRARY SIMPLE INITINSTANCE TERMINSTANCE EXPORTS hello /* From RUNTIME.C */ #pragma strings(readonly) #define INCL_DOSMODULEMGR #define INCL_DOSPROCESS #include <os2.h> char pszErrorBuf[CCHMAXPATH]; void hello(void); int main(void) { APIRET rc; HMODULE hDLL; PFN pHello; rc = DosLoadModule(pszErrorBuf, CCHMAXPATH, "SIMPLE", &hDLL); if (!rc) { rc = DosQueryProcAddr(hDLL, 0, "hello", &pHello); if (!rc) pHello(); rc = DosFreeModule(hDLL); } return rc; } /* From BUILD.CMD */ /* Build a simple DLL that shows how the DLL entry point function works. */ 'ICC /C /Rn /O+ DLLENTRY.C' 'ICC /Rn /Ge- /FeSIMPLE.DLL DLLENTRY SIMPLE.DEF' 'ICC /Rn /O+ RUNTIME.C' ΓòÉΓòÉΓòÉ 17.6. Ordering Issues ΓòÉΓòÉΓòÉ Sometimes the initialization part of the entry-point function for DLL A depends on DLL B being initialized first. For instance, DLL B could be a C runtime DLL, and the entry point function in DLL A could be using some C runtime functions. In this case, you should initialize the C runtime DLL before DLL A. To handle this, DLL B exports a function that performs the initialization required. This function can be called by the entry-point function in DLL B or the entry-point function in DLL A. Use the _CRT_init() and __ctordtorInit() functions that are provided in the C Set ++ libraries. Ordering constraints also can be a problem at termination. There is no way to determine whether a DLL has been unloaded or not, you can't solve the problem by calling the termination function of another DLL. If you call a function in an unloaded DLL, you' ll get an access violation. You can use the DosExitList() API to register a termination function within the DLL that will be called when a process terminates. DosExitList() takes a function-order parameter, allowing termination functions to be called in a specific order. If you register more than one termination function using the same order number, these functions are called in last-in first-out order. When a process terminates, OS/2 calls all the termination functions registered with DosExitList() before any of the DLL entry-point functions are called for termination processing. A different termination problem exists when DLLs are unloaded using the DosFreeModule() API. In this case, the termination function registered by the DLL with DosExitList() is not called since a process is not terminating. OS/2 cannot unload the DLL sin ce an exit list contains a reference to a function within the DLL. Fortunately, OS/2 2.x provides a new, improved solution to this problem. It calls a 32-bit entry-point function in a DLL whenever the DLL is about to be unloaded. The entry-point function can call DosExitList() to remove the registered termination functio n and instead perform the termination processing itself. The DLL can then be unloaded, and all of the resources it was using will have been freed. ΓòÉΓòÉΓòÉ 17.7. Summary ΓòÉΓòÉΓòÉ In the next issue of The Developer Connection News, the discussion of DLLs will continue. Topics such private or shared databased DLLs, exception handling within DLLs, and resource DLLs will be covered. ΓòÉΓòÉΓòÉ 17.7.1. References: ΓòÉΓòÉΓòÉ 1) OS/2 Version 2.0 - Volume 4: Application Development GG24-3774-00 ΓòÉΓòÉΓòÉ 17.7.2. Notes: ΓòÉΓòÉΓòÉ 1) All sample code has been compiled using the GA version of IBM C Set ++ compiler. It has been tested on the GA level of OS/2 2.0 . ΓòÉΓòÉΓòÉ 17.7.3. About the Author ΓòÉΓòÉΓòÉ John Keenleyside is a software developer working on IBM's C Set ++ product. He may be reached at IBM Software Solutions Toronto Laboratory via Email at jkeenley@vnet.ibm.com. ΓòÉΓòÉΓòÉ 18. Why DLLs? ΓòÉΓòÉΓòÉ It's no accident that all OS/2 APIs are provided through DLLs. They're simply the most efficient way to share code and data across any number of OS/2 applications. Normally code in libraries is linked into the application that uses it; DLLs are actually loaded into memory. As a result, linking an application takes less time, because you don't have to copy the library code into the application. You need only copy an import reference. Dynamic linking offers two other advantages. o You need less hard disk space and memory to run applications because code and data are shared. o You can modify the code in a DLL without needing to relink the application. With dynamic linking, you resolve references (calls) to external routines in DLLs at the time the application program is loaded, rather than at link-edit time. Note: When we are talking about an executable or DLL, an object refers to one or more segments that have been grouped. This grouping can either be specified explicitly, or can happen by default if the segments have the same attributes. For example, the group DGROUP is an object in the context of an executable or DLL. ΓòÉΓòÉΓòÉ 19. KwikINF (Quick Information Access into Online References) ΓòÉΓòÉΓòÉ by Paul Brightly One of the most time-consuming efforts in developing code is locating and accessing the correct API Reference. These references come in both hard- and soft-copy. Yet , there are drawbacks to each. Using hard-copy, you can end up with a cluttered desk; soft-copy requires you to identify the correct information object on your desktop (most likely buried several folders deep). With softcopy, there is the additional dilemma that once you find the information object, you must then search through the contents or do a string search to find the item you need. Enter KwikINF. KwikINF lets you look up an API, while editing source code, with the cursor sitting on the API in question. It is a utility that uses keyboard monitors in full-screen sessions and a system message queue hook in PM to detect user-defined hot-key sequences. Pressing this key, extracts the text string under the cursor (presumably an API call) and launches the appropriate online reference, displaying help on that API. The KwikINF utility comes with the OS/2 2.1 Developer's Toolkit (that is available on your Developer Connection CD-ROM). Look for it in the online tools reference, as well as the toolkit desktop folder. Launching online books lets your editor be run in full-screen, a VIO/AVIO window, MLE, or PM window. Unfortunately, in a graphical PM window, we can't extract the word under the cursor, because it's a bitmap and we don't have access to the string used to create it. WIN-OS2 sessions aren't monitored at all. KwikINF determines which online reference to launch by using an index table that maps APIs to the books in which they reside. This mapping is specified by index files that are shipped with the OS/2 Developer's Toolkit as well as the C Set++ product. ΓòÉΓòÉΓòÉ 19.1. Interface ΓòÉΓòÉΓòÉ Start KwikINF from a command prompt by typing KwikINF. If you have the 2.1 toolkit installed, a corresponding program object is created in the Toolkit information folder. Once started, the configuration menu is minimized to an icon on your desktop. You can configure the tool by double-clicking on this icon. The configuration screen in Figure 1 lets you change the behavior of KwikINF. The Activation Key Sequence (hot-key) activates KwikINF from any session. You can change the default (Alt+Q) to one of several other choices if you want. If you edit source c ode in a full-screen session, you will want to specify how many full-screen sessions KwikINF should monitor for the hot-key. You can choose a default book to be searched. Lastly, and I think most useful, you can decide what happens when you hit the hot-key. If you prefer, it will always show the search window in Figure 2. This is useful if you need to choose which book to search every time you want help. But if you're getting help on an API that's specified in the index files, it's faster to bypass the search window. KwikINF determines the correct .INF file and launches it with the text under your cursor. However if you misspell the API, an error message will appear, and control will be returned to the originating window. Figure 1. Configuration Screen The search window in Figure 2 lets you specify the search-text and the book to be searched. This is less convenient than the bypass method previously described. But, it is required if you press the hot-key sequence from a graphical editor. If you use a graphical editor which has the appropriate macro support, you can write a macro that calls KWIKINF.EXE directly with the search-string as a parameter. Make sure you don't use the KwikINF hot-key to invoke this macro or KwikINF will intercept it before your editor ever sees it. Figure 2. Search Window ΓòÉΓòÉΓòÉ 19.2. Building Custom Index Files ΓòÉΓòÉΓòÉ If you have an online book that is best used as a reference, you can create an index file to let KwikINF do the searching for you when you need information. By examining the index files shipped with the toolkit, you can see they're easy to build. A typical line from the index file in the OS/2 2.1 Developer's Toolkit (x:\TOOLKT21\BOOK\EPMKWHLP.NDX) is (Win*, view pmref ~). The first token on this typical line, (Win*), identifies a group of APIs that reside in a specific book. The asterisk, or wild-card character, specifies all APIs that have the Win prefix. This eliminates the need to list each individual API and greatly red uces the size of your index file. The second token, (view), is currently unused. The third token, (pmref), is an environment variable that specifies a group of books to be searched. A specific .INF file can be used as well. Here's a simple index file demonstrating the basic syntax: /* C style comments and blank lines are acceptable */ /* Specific file extensions may be specified here (for EPM editor) */ EXTENSIONS: * /* A title may be placed here */ DESCRIPTION: Any Developer's Custom KwikINF index file /* Complete help words or prefixes with wildcard (*) character may be used */ /* to determine the proper book to open */ (undelete, view cmdref.inf ~) (sysl*, view cmdref.inf ~) (wp*, view pmwkp.inf ~) Using this sample index file, KwikINF is able to load the correct book and find the unrelated topics undelete, syslevel, syslog, and wpOpen. ΓòÉΓòÉΓòÉ 19.3. Installing Index Files ΓòÉΓòÉΓòÉ KwikINF determines the index files to use from the HELPNDX environment variable, installed in the CONFIG.SYS file by the OS/2 Toolkit installation program. SET HELPNDX=EPMKWHLP.NDX If you write your own index file, you must add it to the end of this variable. For example, suppose you wrote an index file named CUSTOM.NDX. You modify this variable like this: SET HELPNDX=CUSTOM.NDX+EPMKWHLP.NDX For KwikINF to find your index file, it must be in the BOOKSHELF environment path (in CONFIG.SYS). ΓòÉΓòÉΓòÉ 19.4. Future Work ΓòÉΓòÉΓòÉ Though KwikINF is very useful as it is, I'm excited by the prospect of continually improving this tool. Future work on KwikINF might include making it portable to different hardware platforms (a good idea for any code), faster interface into .INF files, full 32-bit port, and an API interface for other applications. But you're the customer. We'd like your idea and suggestions; send your ideas using CompuServe, or write us at the address shown in The Developer Connection News. ΓòÉΓòÉΓòÉ 19.5. Summary ΓòÉΓòÉΓòÉ If you rely heavily on the OS/2 Online References when you write code, KwikINF is the tool for you. Try it! You might think twice before you clutter your desk with hardcopy books. KwikINF puts it at your fingertips. For more detailed information on KwikINF, see the Tools Reference in the Toolkit Information folder. ΓòÉΓòÉΓòÉ 19.5.1. About the Author ΓòÉΓòÉΓòÉ Paul Brightly is a Staff Programmer in the OS/2 and Workplace OS Tools development organization, where he is presently working on Workplace OS tools and samples. Paul has been working on OS/2-related projects since 1987 when he joined IBM. ΓòÉΓòÉΓòÉ 20. Writing Device Drivers - Where to Start? ΓòÉΓòÉΓòÉ by Steve Mastrianni I get a lot of questions from developers just starting to write device drivers. One of the most common questions is "How do I get started writing OS/2 device drivers?" Well, that depends on your background. Because device drivers interact with the OS/2 kernel, you should have a good understanding of the basic functions provided by OS/2, such as multithreading, priorities, memory allocation, and addressing. A majority of the questions I get involve a misunderstanding of how various types of addresses work. Driver writers must be able to work with virtual, linear, physical, and real addresses. Since the device driver interacts with the processor at the machine level, a good understanding of the processor architecture is also invaluable. Failures in a device driver usually hang the system, and tracking them down can be tedious without knowing where to look. ΓòÉΓòÉΓòÉ 20.1. So, What Tools Do I Need? ΓòÉΓòÉΓòÉ If you're writing your device drivers in C, you'll need a 16-bit C Compiler such as Microsoft C Version 5.1 or Version 6.0. You'll also need an assembler, such as the Microsoft Version 6.0 Macro Assembler. Previous versions (such as Version 5.1) will also work. If you're writing Virtual Device Drivers (VDDs), you'll need a 32-bit C compiler, such as IBM C Set/2 or C Set++ (recommended) or the special 32-bit compiler, CL386, included in the Device Driver Source Kit (DDK). The DDK also includes the kernel debugger and ASDT32, which you will need to debug your device drivers. The Periscope Debugger is available commercially. You also should get the OS/2 Technical Library, a 50-pound collection of developer reference books, which includes the OS/2 Physical Device Driver Reference, Virtual Device Driver Reference, and Presentation Driver Reference. The library is also available as part of the OS/2 Online Book Collection CD-ROM. You can get the book, Writing OS/2 2.1 Device Drivers in C, 2nd edition. It's the only tutorial on writing OS/2 2.x device drivers. Call 1-800-842-3636 to order. Support for device driver writers is free via IBM's DUDE (Dynamic Upload and Download Environment). Periodically, the DUDE team archives the questions into a file (removing names), which you can download. See the Directory of this Newsletter on how to access the DUDE. You can download the file CDISK.ZIP from the Libraries section, Device Drivers, of OS2DF1 on CompuServe. CDISK.ZIP includes several sample device drivers, including a VDD sample, all written in C. I've always written my drivers in C; IBM has historically written them in assembler. This is evidenced by the code in the PDD reference, which contains MASM examples of DevHlp calls. With the advent of Workplace OS, IBM has begun to document C-language interfaces to the DevHlps. Future releases of the DDK and driver references will include these. ΓòÉΓòÉΓòÉ 20.2. Another Question... ΓòÉΓòÉΓòÉ Another question I get asked frequently is "How can I initialize a memory mapped adapter during initialization (Init time)?" Very often, adapters must have their memory loaded with a program or initialized. Many device driver writers experience their first Trap 13 (General Protection Fault) when attempting to perform this operation during Init. The most common cause is that driver writers sometimes forget that Init is run as a ring 3 thread of the system. Mapping a physical address to a virtual address with PhysToVirt yields a GDT-based pointer, which is not usable from a ring 3 thread. Ring 3 threads do not have GDT access; only LDT access. The solution to this problem is to map the physical address of the adapter to a virtual address that's mapped into the application's LDT. This is done with the PhysToUVirt DevHlp call, rather than the PhysToVirt call. If you have a lot of data to download to the adapter, keep it in a disk file, and use the standard DosOpen, DosRead, and DosClose APIs. This is possible because Init is running as a ring 3 thread, which is the same ring level at which most applications run. ΓòÉΓòÉΓòÉ 20.3. And, Yet Another Question... ΓòÉΓòÉΓòÉ "How can device drivers can transfer data at interrupt time?" This is a little tricky; but easy once it's been explained. Remember that Init runs as a ring 3 thread with access to the application program's LDT. The rest of the time, your device driver operates in the lowest ring, ring 0. While at ring 0, the device driver has full access to the GDT and for the most part, the entire system. The problem is that when an interrupt occurs, your program might not be the program that is currently running. For example, your program might be blocked waiting for I/O or waiting on a semaphore. Because of this, the context, or current environment at t hat instant, might not be known. Trying to map an application's buffer address at interrupt time will not work. To maintain addressability in any context, the application's buffer address must be mapped to a GDT selector. The selector, however, must be allocated during Init, and then mapped to the GDT selector for later use during interrupt time. Remember that even though you map the selector during Init, you can't use it during Init. ΓòÉΓòÉΓòÉ 20.3.1. About the Author ΓòÉΓòÉΓòÉ Steve Mastrianni is an industry consultant specializing in device drivers and real-time applications for OS/2. The author of "Writing OS/2 Device Drivers in C", Steve is regarded as one of the industry's leading experts in OS/2 and OS/2 device drivers. ΓòÉΓòÉΓòÉ 21. DDK Notes ΓòÉΓòÉΓòÉ by Judith A. Courter Version 1.1 of the IBM Device Driver Source Kit for OS/2 (DDK) became available on September 30, 1993. If you previously ordered the one year program, Version 1.1 was automatically shipped to you. If you ordered the single-issue copy of Version 1.0, you can start your yearly program now by ordering Version 1.1. (Call 1-800-6DEVCON.) We hope you are pleased with the direction the DDKs are going. We've received your requests through the DUDE, conferences, and trade shows and are trying to satisfy them as fast as possible. I enjoyed meeting many of you at the Device Driver Conference held in San Jose in July; it was a great opportunity to talk to you and find out what you needed in order to write your OS/2 drivers. If you haven't signed up for the DUDE, see the Directory of this newsletter for more information on DDK support. For those of you who started with the Beta in February, you can see how we've grown in the last several months. Some of the new items are the direct result of requests we've received from you. For example, a new tool, DDKREF, has been added to enable vi ewing the online documentation directly from your CD-ROM instead of installing the books on your hard drive. We've added a new tool, DELDDK, to use if you ever want to delete the DDK. Several files created by the install program are not obvious to you a nd if not deleted could cause problems when reinstalling or installing a new DDK. DELDDK takes care of these. Additionally, you've asked for debuggers and we've provided 7, plus documentation. Some of the other online documentation has been updated and expanded. ΓòÉΓòÉΓòÉ 21.1. Using Your DDK ΓòÉΓòÉΓòÉ Version 1.0 contained an online book called General Information. It has been renamed Using Your DDK. This book contains the following helpful information: o A listing and description of all new drivers, tools, and books contained in this version. o A listing of each driver and a cross-reference to the compiler/assembler needed by each driver and tool. o A directory structure overview of the DDK. o A listing of each compiler/assembler used in the DDK and a cross-reference to the device drivers and tools. o The file names of all drivers that can be built using the DDK. o A listing of some useful reference books that may help you develop your own device drivers under OS/2; including excerpts from Steven Mastrianni's book, Writing OS/2 2.1 Device Drivers in C. o Documentation on the 32 bit Mini-Driver Rasterizing Printer Driver sample. ΓòÉΓòÉΓòÉ 21.2. It's a Program ΓòÉΓòÉΓòÉ As we've said in the past, it doesn't end here! The DDK Team is currently working on the next DDK. It will contain additional device driver source code, more tools, and restructured and expanded documentation. If you haven't ordered the DDK, see the Directory of this newsletter for more information on ordering. ΓòÉΓòÉΓòÉ 21.3. Version 1.1 Contents ΓòÉΓòÉΓòÉ The Version 1.1 CD-ROM contains almost 140MB of source, tools, debuggers, and documentation. The following list identifies what's new: o Video Device Drivers - 32-Bit S3 Chip Set Support (8 bit color) - 32-Bit ISO Fonts - DBCS VGA/SVGA PM Display - Screen Base Videos o Printer Device Drivers - 32-Bit 42xx Rasterizing Sample - 32-Bit Mini-Driver Rasterizing Sample o DASD Device Driver - Adapter Presence-Check Services o PCMCIA Device Driver - Client Services Sample o Multimedia Device Drivers and Installs - Generic Audio Installation - Generic Video Installation - Audio Vendor-Specific Resource File - Video Capture Adapter PDD - Video Capture Adapter VSD o Clock Device Drivers o Debuggers - 5 OS/2 Debug Kernels - ASDT32 Debugger - Debugo o Test Tools/Suites - 32-Bit Font Test Tool - MMPM/2 P2String Audio Test Suites - MMPM/2 P2String Video Test Suites o DDK Tools - DELDDK - DDKREF o Updated and expanded on-line documentation ΓòÉΓòÉΓòÉ 21.3.1. About the Author ΓòÉΓòÉΓòÉ Judith A. Courter is the Manager of the POS Toolkit Development department. She started a dedicated DDK team in August of 1993. Judi has held a variety of programming positions since she began with IBM in 1981. ΓòÉΓòÉΓòÉ 22. Order Form ΓòÉΓòÉΓòÉ The Developer Connection for OS/2 ORDER FORM Send this completed Order Form and $199.00 for each single, annual subscription and $75.00 for each additional license (plus applicable shipping charges and sales tax). Members of the U.S. Commercial/Premier Services of the IBM Developer's Assistance Program can get a discount by calling 1-800-6DEVCON (1-800-633-8266). IBM Order Fulfillment, 010J Fax This Form to: P.O. Box 9031 1-800-494-3045 Boulder, CO 80301-9191 Receive By Mail an annual subscription consisting of 4 CD's and newsletters, plus access to the interactive forum for one year.* Please allow 1-2 weeks for delivery. Please Complete (please print or type): Bill To: __________________________________________________________________ Name __________________________________________________________________ Company Phone __________________________________________________________________ Street __________________________________________________________________ City State Zip MethodofPayment :( Checkone ) ____Visa ___MasterCard ____American Express ___ Discover ___Other Payment Method 3 Card#________________________________________________________________________ Annual Subscription (Qty): ____ x 199.00 = $__________ Additional Licenses (Qty): ____ x 75.00 = $__________ TOTAL = $__________4 I certify that the information I have provided is accurate and complete and the submission of this form is in accordance with the conditions specified below. ____________________________________________________________________ Signature (required when ordering by credit card) Date Instructions: 1. To ensure speedy delivery, please make sure that the information provided is accurate and legible. 2. If you have any questions, please call 1-800-6DEVCON. 3. To pay by check/money order or to submit a Corporate Purchase Order, please call 1-800-6DEVCON for instructions. 4. Applicable Sales Tax and Shipping and handling charges will be added to your total. Conditions: o The Developer Connection for OS/2 is for the customer's own use and is not to be remarketed. o Lost or misdirected Order Forms are not the responsibility of IBM or IBM Fulfillment Headquarters. o IBM reserves the right to modify or withdraw this offer at any time. *CompuServe membership is required IBM and OS/2 are registered trademarks of International Business Machines Corporation. The Developer Connection for OS/2 is a trademark of International Business Machines Corporation. Other products and brand names may be trademarks or registered trademarks of their respective owners. International Business Machines Corporation, 1993. All Rights Reserved. IBM Order Fulfillment 010J P.O. Box 9031 Boulder, CO 80301-9191 11-93 ΓòÉΓòÉΓòÉ 23. Q's and A's ΓòÉΓòÉΓòÉ Question 1: My Toolkit will not run properly. I get a message that the file PMREF cannot be found. How do I solve this problem? Answer: References to PMREF should be changed to the name PMFUN. This seems to fix the problem. Also, C/Set&Toolkit&WorkFrame must be installed in the following order: Toolkit, WorkFrame, C Set/2. If they are not, WorkfFame will not be aware of C Set/2 and some of the function will not be available. If you get missing libraries, such as dde4XXXX, you need to go back and install the migration part of the compiler. Question 2: I get an Error Unresolved External 2029 message when trying to link a program. Why? Answer: The following statements need to be present and correct in the OS/2 CONFIG.SYS file: 1. The LIBPATH line must include: x:\TOOLKT20\DLL;x:\IBMC\DLL;x:\IBMWF\DLL; (x: = drive letter) 2. The SET PATH line must include: x:\TOOLKT20\OS2BIN;x:\IBMC\BIN;x:\IBMWF\BIN; 3. The SET DPATH line must include x:\IBMC\LOCALE;x:\IBMC\HELP;x:TOOLKT20\BOOK; 4. The SET HELP line must include: x:\TOOLKT20\OS2HELP;x:\IBMC\HELP;x:\IBMWF\HELP; 5. SET IPF_KEYS=SBCS 6. The following lines should be at the end of the CONFIG.SYS: SET PROGREF20=GUIREF20.INF SET PMREF=PMFUN.INF+PMGPI.INF+PMHOK.INF+PMMSG.INF +PMREL.INF+PMWIN.INF+PMWKP.INF SET HELPNDX=EPMKWHLP.NDX+DDE4.NDX SET IPFC=x:\TOOLKT20\IPFC; SET INCLUDE=x:\TOOLKT20\C\OS2H; x:\TOOLKT20\ASM\OS2INC;x:\IBMC\INCLUDE SET LIB=x:\TOOLKT20\OS2LIB;x:\IBMC\LIB Question 3: I notice that the OS/2 2.0 toolkit documentation, specifically the manual OS/2 2.0 Physical Device Driver Reference, was not changed to reflect the code change to touch display support. Is there a reason for this? Answer: The mouse IDC, Process_Absolute, has been changed in OS/2 2.0 because a defect was raised by the IBM Touch Display support added to 2.0. The change was to remove the function where the MOUSE.SYS device driver would check the movement of the mouse pointer against the button mask that was passed in and change that mask if there was a discrepancy. This was deemed in error since there are occasions where the device-dependent driver may want to pass these bogus values up the chain to running applications. The OS/2 2.0 Toolkit documentation, specifically the manual OS/2 2.0 Physical Device Driver Reference, was not changed to reflect the code change. In the Physical Mouse Device Driver Reverence (in the Mouse IDC section), there is a reference to the "EVENT" field that should be changed. Remove/ignore the following sentence: The event field should never indicate that motion was associated with the event. MOUSE$ determines if motion occurs. Question 4: I created an application program, but the CD drive doesn't respond as it does with the Compact Disc program. What am I doing wrong? Answer: Check proper use of APIs and verify sufficient stack is used when creating a second thread, as follows: 1. Check that you are using commands with the same alias that was used on the "open" if using the string interface, or the same DeviceID that was returned on the MCI_OPEN command if using the procedural interface. 2. If creating a second thread, make sure that sufficient stack is allocated. The IOCTL router or CD drive driver sometimes acts peculiar if low stack is used on a secondary thread. We recommend 64KB, but you must have at least 16KB. 3. If using C Set/2, use _beginthread instead of DosCreateThread. See the C Set/2 user's manual for more details. Question 5: I am getting a general protection fault error when I try to run an FSCANF statement in a DLL. The DLL is being called from two different programs in two different sessions. What is happening? Answer: The FSCANF and other like functions are called critical functions. They cannot be run in a DLL because they lack SEMAPHORES. This means that when an FSCANF runs, it grabs hold of everything and doesn't allow another process the use of FSCANF. The solution is to use exception handling or DosRead. The DosRead functions have SEMAPHORES built in, and therefore allow multiple processes to simultaneously access them. Question 6: My system hangs intermittently (shell hang; not kernel) when running certain PM Applications that utilize DosKillThread() or DosKillProcess(). What is the reason for this? Answer: The problem is that any thread that makes PMWIN calls may own/control certain PMWIN controls, such as semaphores, and may be currently in the middle of updating global PMWIN structures. Both DosKillThread() and DosKillProcess() will force the thread(s) of the process to die upon immediately exiting from the Kernel. However, PMWIN runs at rings 3 and 2, so their operations are not completely within the kernel. This may cause a user thread to die while in the middle of updating a PMWIN structure. The only resolution, until PMWIN becomes 32-bit, is for the developer to use some form of IPC in place of DosKillxx() calls (such as, Semaphores, Queues, Shared Memory, or Presentation Manager Messages.) ΓòÉΓòÉΓòÉ 24. Tips 'N Techniques ΓòÉΓòÉΓòÉ Use the following tips to increase your productivity! ΓòÉΓòÉΓòÉ 24.1. Device Driver Tips: ΓòÉΓòÉΓòÉ o To access a GDT selector during Init, start a timer handler that will be called within 32ms at ring 0; then perform the access. o If you need to post a 32-bit shared even semaphore at interrupt time, which normally can't be done, allocate and arm a context hook. This hook will be called at task time and therefore will be able to post the semaphore. ΓòÉΓòÉΓòÉ 24.2. Performance Tip: ΓòÉΓòÉΓòÉ o Tip: Reduce your icon sizes and increase system performance. o Technique: Attaching icons to desktop objects (abstract objects for WPS programmers) can increase the size of the OS2.INI file. This can potentially effect system performance. Large icons shipped with software cascades this effect to users. Icons are stored as bitmap arrays. This allows for different display types and resolutions. Unfortunately, the more formats stored, the larger they get. But many icons don't require many colors or resolution. If you edit them with the icon editor and save only the Independent VGA format, they will be less than 1K. If this format isn't present, just add it from the menu. The existing format will be rendered into the new format. And, the VGA is a pretty good lowest-common-display type. The opposite extreme can be seen by saving an icon with all possible formats. The resulting file is around 17K. With so many desktop objects, you can see how we can all benefit by smaller icons. ΓòÉΓòÉΓòÉ 24.3. KwikINF Tips and Techniques: ΓòÉΓòÉΓòÉ Like any tool, there are good and bad ways to use them. Here are some of my favorite tips for getting the best use and performance out of KwikINF. Don't use full-screen monitors if you don't need them. It wastes memory and creates a keyboard monitor for every full screen session you start (up to the maximum set in the configuration menu. Keep books open if you intend to keep accessing them. It can take a long time to open a book. If you're writing new code, you'll likely want frequent access to certain online references. If you leave the book open (minimized), you won't have to wait so long each time you press Alt+Q. Trim down your index files! If you create an index file for your own online reference, then take advantage of the wildcard character (*) supported in index files. Every single entry in an index file has to be allocated, added to an index table in memory , and searched by KwikINF. If we didn't use Win* to specify the PM reference in the toolkit index file, there would be a LOT of unnecessary index entries for every WinXXX API in our index table. Don't restrict KwikINF to your editor. There are other ways to benefit from this tool. I've often typed an API on a Windowed Command Prompt so I could press Alt+Q and get help on it. And one of my favorite tricks is to get help while I'm reading E-mail or a public forum. I can answer a technical question with the press of a key. ΓòÉΓòÉΓòÉ 24.4. MMPM/2 Tips and Techniques: ΓòÉΓòÉΓòÉ o Tip: Improve overall performance in MMPM/2 applications. o Technique 1: WRITE MULTITHREADED APPLICATIONS! This is the most important tip and cannot be stressed enough! OS/2 is a very powerful operating system and provides its programmers with the ability to execute more than one activity (thread) at a time. This is not automatic, however; it must be programmed into applications. The benefits gained from multithreaded applications are tremendous. This is especially true when it comes to Presentation Manager (PM) applications. A PM application should never tie up its main message procedure's thread for very long. If it does, users will experience the OS/2 timer icon, and be unable to manipulate the application (or other applications) for a period of time. This also holds when programming MultiMedia Presentation Manager/2 (MMPM/2) applications. Time-consuming Media Control Interface calls should not be made from within a PM application's main message procedure's thread. Instead, a worker thread should be created to make the MCI call. The most time consuming calls incl ude MCI_OPEN, MCI_CUT, MCI_COPY, MCI_PASTE, MCI_SAVE, and sometimes MCI_LOAD (this depends on the device and/or the file size). o Technique 2: Use the MMPM/2 pre-roll capability provided through the MCI_CUE message. When an application will have a time delay between an MCI_LOAD and an MCI_PLAY of a file (like a Wave Player application: where the user opens a file [MCI_LOAD], then presses a butt on to start playing the file [MCI_PLAY]) the application should make an MCI_CUE call. This message will pre-roll the data (pre-fill the play buffers) and allow the MCI_PLAY to start immediately. Without the MCI_CUE message, an MCI_PLAY will take longer as it will automatically take the time to perform an MCI_CUE. Note: The MCI_CUE will have no effect if the MCI_PLAY uses the MCI_FROM flag. The MCI_FROM will change the start position of a file and thus invalidate the buffers that were pre-filled. If a file is to be played FROM a particular position, one should first MCI_SEEK to the position, issue the MCI_CUE, and then finally, when appropriate, issue the MCI_PLAY message. o Technique 3: Don't close a device unless necessary. Many applications MCI_OPEN a device, MCI_LOAD a file, MCI_PLAY the file, and then MCI_CLOSE the device they are using. This is fine, however, some of these applications then turn around and re-issue MCI_OPEN the same device, MCI_LOAD another file, MCI_PLAY, and then MCI_CLOSE again. This is very wasteful. On each open, a device must be initialized, resource must be allocated, and so on. It is much more efficient (and desirable) to leave the device open and simply do another MCI_LOAD and then another MCI_PLAY. The basic rule of thumb to follow is: Re-open a device as little as possible. o Technique 4: Open and close devices that will be needed prior to using them. The most time consuming MCI message is the MCI_OPEN message. Opening a device takes time due to the amount of work that must be accomplished (initializing the device, allocating device reso urce, making the appropriate connections and perhaps, even loading a file). The MCI_OPEN takes a bit longer than usual when a device is opened for the first time, because the associated dynamic link libraries (DLLs) for that device must be loaded. Pre-opening and closing the particular device(s) that will/may be used will load the needed DLLs. These DLLs will remain loaded (even after an MCI_CLOSE), as long as the application is still running. Subsequent MCI_OPEN calls will occur quicker, because the DLLs are already loaded. For example, a digital video application could, on its initialization, create a thread to open and then close the digital video devices it might be using. When the user determines which device will be used (perhaps by selecting a particular video file) the device's DLLs will have already been loaded, and thus the open will occur quicker. Note: When MMPM/2's system sounds are installed, part of the audio subsystem will have already been loaded at system boot time, thus there may not be a need to open and close the audio device prior to using it in an application. ΓòÉΓòÉΓòÉ 25. Conference Column ΓòÉΓòÉΓòÉ Look to this column each issue for the most up-to-the-minute information on OS/2 conferences. Be sure to register for these conferences early, as you don't want to be left out! ΓòÉΓòÉΓòÉ 25.1. PSP Technical Interchange Featuring OS/2 and LAN Systems ΓòÉΓòÉΓòÉ So, you enjoyed the technical interchange in Orlando, and can't wait for the next one? Well, the good news is that PSP is currently planning the next one; the bad news is that it's not planned until April. Here's the preliminary information: Where: San Francisco, California at the San Francisco Hilton When: April 25, 1994 to April 29, 1994 Cost: 895 USD; however, a discounted fee of 795USD is available until March 21, 1994. Contact: US: 1-800-872-7109 All other countries: 1-508-443-3330 Look in the February issue of The Developer Connection News for more details. ΓòÉΓòÉΓòÉ 25.2. Trade Shows ΓòÉΓòÉΓòÉ The following are some of the major trade shows through April of 1994. What: Networks Expo Where: Boston, Massachusetts When: February 15 Contact: Bruno Blenheim, Inc. 1-800-829-3976/1-201-346-1400 What: Software Development and Business Software Solutions Where: San Jose, California When: February 15 Contact: Miller Freeman, Inc. 1-415-905-2741 What: Federal Office Systems Symposium Where: Washington, DC When: March 21 Contact: National Trade Productions 1-800-638-8510/1-703-683-8500 ΓòÉΓòÉΓòÉ 26. Directory ΓòÉΓòÉΓòÉ Ever wonder where to call to order a product or to voice a particular problem or concern. Well, we believe it's our job to let you know how to contact IBM. Watch this space; we'll continually update this information. The Developer Connection for OS/2 1-800-6DEVCON (1-800-633-8266) phone 1-800-494-3045 fax Additional Order Numbers To order in Europe: The Developer Connection for OS/2 can be ordered direct from IBM SPC in Denmark if you live outside the US, Canada, or Asia/Pacific. Please ensure that you dial the international access code applicable to your country before dialing the appropriate phone number. This applies to both telephone and fax orders. Operators speaking the following languages are available. Note that 45 is the country code for Denmark. Dutch 45-3-252-7088 English 45-3-252-6588 French 45-3-252-7411 German 45-3-252-6711 Italian 45-3-252-7622 Spanish 45-3-252-6311 FAX 45-3-252-8203 To order in Canada: The Developer Connection for OS/2 can be ordered direct from Canada. Please dial the following appropriate number: 1-800-561-5293 (phone) 1-416-946-5700 (fax) To order in Asia/Pacific: The Developer Connection for OS/2 can be ordered in Asia/Pacific countries. Please ensure that you dial the international access code applicable to your country before the listed phone number. Note that 61 is the country code for Australia. 61-2-354-7684 (phone) 61-2-354-7766 (fax) To order in Mexico: The Developer Connection for OS/2 can be ordered direct from Mexico. Please dial the appropriate phone number. 91-800-00639 (Country) 627-2444 (Mexico City) To order in Brazil: The Developer Connection for OS/2 can be ordered direct from Brazil. Please dial the appropriate phone number. 0800-111205 (phone) (011) 886-3222 (fax) Electronic Support Electronic support is provided through CompuServe. Obtain technical support or use the forum to exchange messages, ideas, comments, or concerns with The Developer Connection for OS/2 team or other members. The dedicated Developer Connection section is located in the IBM OS/2 Developer Forum 2. To obtain access to this section, please send a note with your subscription number to the Developer Connection Administrator at CompuServe user id 73423,2767. You will receive notification or access to the Developer Connection section within 2 business days. To access the forum, type GO OS2DF2 at the ! prompt; then, select the Developer Connection section. For CompuServe membership information, call one of the following numbers depending on where you are located. From Germany 0130 37 32 From the United Kingdom 0800 289 378 From other countries in Europe (+44) (+272) (255 111) From the U.S. 1-800-524-3388 From elsewhere 1-614-457-0802 Ask for Representative 239. You will receive a special introductory membership for IBM customers. IBM Device Driver Source Kit for OS/2 1-800-6DEVCON (1-800-633-8266) phone 1-407-982-3217 modem 1-407-982-4239 voice Additional Order Numbers To order in Europe: The Device Driver Source Kit can be ordered direct from IBM SPC in Denmark if you live outside the US, Canada, Asia/Pacific, or Brazil. Please ensure that you dial the international access code applicable to your country before dialing the appropriate phone number. This applies to both telephone and fax orders. Operators speaking the following languages are available. Note that 45 is the country code for Denmark. Dutch 45-3-252-7088 English 45-3-252-6588 French 45-3-252-7411 German 45-3-252-6711 Italian 45-3-252-7622 Spanish 45-3-252-6311 FAX 45-3-252-8203 To order in Canada: The Device Driver Source Kit can be ordered direct from Canada. Please dial the following appropriate number: 1-800-465-7999 (phone) To order in Asia/Pacific: The Device Driver Source Kit can be ordered in Asia/Pacific countries. Please ensure that you dial the international access code applicable to your country before the listed phone number. Note that 61 is the country code for Australia. 61-2-354-7684 (phone) 61-2-354-7766 (fax) To order in Brazil: The Device Driver Source Kit can be ordered direct from Brazil. Please ensure that you dial the international access code applicable to your country before the listed phone number. Note that 02 is the country code for Brazil. 02-1-800-6120 (phone) 02-1-800-6936 (fax) Obtain support for the IBM DDK kit by calling the Dynamic Upload/Download Environment (DUDE) BBS. After completing a self-registration, you will first have limited access to the system; then, within one business day, you will be notified that your access level has been upgraded to NORMAL. Send your questions using your PC and modem. If you have problems connecting to the DUDE BBS, you can leave a voice message on 1-407-982-4239. A member of the DDSC team will return your call before the end of the next business day. OS/2 2.1 Technical Support 1-800-992-4777 When you buy OS/2 2.1, you also receive 60 days of free technical support. The OS/2 technical support team will provide assistance with installing OS/2 2.1, setting up printers and displays, partitioning disk drives, setting up to run multiple operating systems, moving commercial programs to folders or to the OS/2 desktop, and installing and using Multimedia. You can also report suspected product defects to the technical support team. Electronic Support (U.S. and Puerto Rico only) Electronic support enables you to access current OS/2 technical information, exchange messages with other OS/2 users, and submit program defects to IBM. Electronic support is available to users with a modem and a telephone line through the OS/2 Bulletin Board System (BBS) or CompuServe. For information about registration and access to the IBM OS/2 BBS, call 1-800-547-1283. For CompuServe membership information, call 1-800-848-8199. If you are already a CompuServe member, type GO OS2SUP at the ! prompt to access the IBM OS/2 forum. Electronic Support (Canada only) Electronic Support enables you to access current OS/2 technical information and exchange messages with other OS/2 users. Electronic support is available to users with a modem and a telephone line through an OS/2 BBS. You can connect directly to the OS/2 BBS nearest you by dialing one of the following numbers: 1-416-946-4255 1-514-938-3022 1-604-664-6466 Note: Set your modem and communication software to the following: no parity bit, 8 data bits, 1 stop bit. The Developer Assistance Program The Developer Assistance Program (DAP) is a worldwide program that offers services to software developers. Specific services vary by country and development platform. For more information about the DAP, call: U.S. 1-407-982-6408 (phone) 1-407-998-7610 (fax) Worldwide 1-407-982-4259 (phone) Additional Phone Numbers All 800 numbers are applicable in the USA only; for individual country numbers, please check on your local BBS or your IBM Representative. IBM Academic Information Systems Ordering Information 1-800-222-7257 IBM Direct Marketing 1-800-IBM-2YOU Order IBM ValuePoint systems, IBM ThinkPad systems, IBM Communication and LAN hardware and software, memory options, printer, and typewriter supplies. HOURS: 8:00 a.m. - 10:00 p.m. EST. IBM FAX Information Service 1-800-IBM-4FAX Retrieve information on IBM products with your fax machine. IBM LAN Systems Service and Support 1-800-237-5511 Technical support for customers who own LAN Systems products. IBM PC Dealer Referral 1-800-237-4824 Locate an IBM dealer nearest you. IBM Personal Systems Help Center 1-800-PS2-2227 Obtain general information and technical support on ValuePoint systems, ThinkPad systems, PS/2, and OS/2 products. HOURS: 24-hours a day. Independent Vendor League The Independent Vendor League was formed to meet the specific needs of individuals and companies who develop and market products and services that support OS/2. It is an association of vendors whose common ground is the IBM OS/2 marketplace. To join or to receive information 1-203-262-3769 1-203-262-3776 To order an IVL Catalog 1-800-342-6672 Multimedia Help Line 1-800-241-1620 Obtain technical support for the Multimedia Presentation Manager/2 product. Multimedia Information Center 1-800-IBM-9402 Obtain information on the Multimedia Presentation Manager/2 product. OS/2 and IBM LAN Systems Sales 1-800-3-IBM-OS2 Purchase OS/2 and IBM LAN Systems products by phone. Ultimedia Tool Series 1-800-887-7771 Obtain technical support on the Ultimedia tool series.