home *** CD-ROM | disk | FTP | other *** search
-
- ΓòÉΓòÉΓòÉ 1. Title Page ΓòÉΓòÉΓòÉ
-
- Welcome to EDM/2 - The Electronic OS/2 Developers Magazine!
- Portions copyright (c) by Larry Salomon Jr.
- Volume 2, issue 2
-
- Copyright Notice and Other Stuff
-
- The editor of this electronic magazine is Larry Salomon, Jr.
-
- Portions of EDM/2 are copyrighted by the editors. This publication may be
- freely distributed in electronic form provided that all parts are present in
- their original unmodified form. A reasonable fee may be charged for the
- physical act of distribution; no fee may be charged for the publication itself.
-
- All articles are copyrighted by their authors. No part of any article may be
- reproduced without permission from the original author.
-
- Neither this publication nor the editors are affiliated with International
- Business Machines Corporation.
-
- OS/2 is a registered trademark of International Business Machines Corporation.
- Other trademarks are property of their respective owners. Any mention of a
- product in this publication does not constitute an endorsement or affiliation
- unless specifically stated in the text.
-
- Administrivia
-
- More Format Changes
-
- First, I would like to say that I (finally) understood what the comments of
- "duplicate introductions" mean. Let me defend myself by claiming that I always
- thought that the readers would use the hyperlinks that were defined at the end
- of each section. People who noticed this behavior were instead using the
- Forward button to cycle through all of the panels. Since the issue was built
- with two copies of the introduction - one which is displayed if you select the
- article or column title, and one if you select the Introduction section - they
- were seeing both. In lieu of this annoying behavior, only one introduction
- will be present.
-
- As a last minute change, I decided to remove the hyperlinks at the end of each
- section for the following two reasons:
-
- o They duplicate the functionality of the Forward button.
- o If there are other hyperlinks in the section, it is not "just a press of the
- Enter key" to get to the next section.
-
- Thus, I have removed these links and suggest to those that used them to use the
- Alt+F key or the Forward button via the mouse.
-
- Another format change is that the CONTENTS.NDX file has been moved out of the
- EDMIv-i.ZIP file. To avoid conflicts with index files from later issues, it
- has also been renamed to EDMIv-i.NDX. Doing this will allow those who are
- interested in specific topics to just download this file to see what the issue
- contains.
-
- Awards News Flash
-
- If anyone knows how to contact Gavin Baker, please do so and tell him what he
- won (, Bob :) . Email sent to his address bounces, so I cannot get his address
- to mail his prize. If we do not hear from him by the release of next month's
- issue, the prize will be awarded to someone else.
-
- Speaking of prizes, we still have not received them. While we are not blaming
- anyone, this is being pointed out to explain for the delay. As soon we receive
- them, they will be shipped out.
-
- And In This Corner
-
- This month seems to be the month of reviews; we have two reviews that I think
- the readers will be interested in: Gordon Zeglinski has (finally) received his
- copy of IBM's C-Set++/2 version 2.1 product and presents an update to his
- compiler comparison that appeared in volume 1, issue 5. Also, Jonathan Story
- wrote a very interesting review of Quercus Systems's Personal Rexx product on
- the Internet, and we were granted permission to reproduce it here. Many thanks
- to Jonathan for allowing us to do so.
-
- Congratulations to Patrick Mueller for finally getting approval from IBM to
- submit his article. He had expressed a desire to do so around volume 1, issue
- 5, but didn't have time to deal with the beaurocratic issues involved. Maybe
- Lou's influence is starting to extend itself to North Carolina :) . I would
- also like to state that - to date - Patrick's article was the easiest to
- reformat, since 99% of his submitted text followed the Article Submission
- Guidelines.
-
- (I wonder how many people will pick up the puns in the graphic for that
- article. I'll take your guesses and will publish the name of the first correct
- answer for each of the three.)
-
- WPS Developer Wanna-Be's
-
- For the people beginning (or attempting to begin, as the case may be) to do
- Workplace Shell development, watch this space; I'm learning quickly how this
- stuff works, and while I am only a beginner, many people have a hard time
- getting anything to work at all. I'm hoping to have an introductory article on
- this topic for the next issue.
-
- In the meantime, there is a SOM/WPS mailing list run by Gess Shankar, who does
- the EDM/2 distribution on the Internet. If you are interested in joining, send
- a blank mail message to somwps-info@knex.via.mind.org.
-
- Continuations
-
- Andre Asselin apologizes for not having the next part of his award-winning
- series OS/2 Installable File Systems ready for this issue, but promised to have
- it for the next issue.
-
- Marc van Woerkom was to continue his series Making Noise with MMPM/2. Because
- he was running behind, I agreed to wait until Friday for his article.
- Unfortunately, something has come up and I will not be here on Friday, so I
- asked him if he could get it to me sooner. Since I never received a response,
- I decided to push his article until next issue.
-
- I hate doing things like this, but such is the life of the editor. :(
-
- A Final Thanks
-
- ...to all of the subscribers who answered my four question survey sent out in
- the last week of January. The results were very interesting; I hope to compile
- them and send out a summary of what I received. It's still not too late to
- send me your responses, however!
-
-
- ΓòÉΓòÉΓòÉ 2. This Issue's Features ΓòÉΓòÉΓòÉ
-
- The following articles constitute this issue's features:
-
- o A Review of Personal REXX for OS/2
- o TCP/IP Socket Programming in REXX
-
-
- ΓòÉΓòÉΓòÉ 2.1. A Review of Personal REXX for OS/2 ΓòÉΓòÉΓòÉ
-
- Written by Jonathan Story
-
- OS/2 is like a chest full of treasures. It runs OS/2, DOS and Windows
- programs, and you don't need to buy DOS or Windows because both are already
- included. And when you dig a little deeper you discover REXX, a jewel brought
- over from the mainframe world.
-
- OS/2 includes REXX for no extra charge. Quercus Systems, makers of Personal
- REXX, would be very happy to sell you a copy of their version. Why should
- anyone pay good money for something they already have? Well, consider OS/2's
- REXX compared to Personal REXX as the difference between a good pair of
- sensible street shoes and top-of-the-line rollerblades.
-
-
- ΓòÉΓòÉΓòÉ 2.1.1. Documentation ΓòÉΓòÉΓòÉ
-
- The documentation that comes with Personal REXX can help almost anyone to get
- started learning and using REXX. It includes: a User's Guide, an OS/2
- Addendum, a REXXLIB User's Guide, a Reference Summary booklet, and the book The
- REXX Language: A Practical Approach to Programming, Second Edition by M.F.
- Cowlishaw (the 'bible' for the REXX language.)
-
- For the novice, the User's Guide introduces the elements of the language in an
- easy step-by-step fashion illustrated by brief example programs. The Guide
- takes care to distinguish between what is a part of the language itself and the
- extensions from Quercus. For someone who wants to make his programs work on as
- many environments as possible, this is very important to know.
-
-
- ΓòÉΓòÉΓòÉ 2.1.2. Installation ΓòÉΓòÉΓòÉ
-
- This is one of the few areas I would like to see improved. Personal REXX for
- OS/2 has an install program, but it does not modify your CONFIG.SYS. It could
- be that the installation process avoids changing anything that might cause
- problems, although for me installing manually caused problems anyway: I
- completed what was left of the install by hand according to the instructions,
- but it took me two tries (rebooting each time) before successfully making the
- changeover from the REXX included with OS/2 to Quercus's Personal REXX. Why
- should the ordinary REXX user have to know about PATH and LIBPATH? Adding a
- few more smarts so that everything will install automatically (an uninstall
- would be another pleasant bonus) can remove this unwelcome technical encounter.
-
- A minor nit: a program called INSTEST checks that all components of the
- package have been installed. This is useful (and, for me, was necessary), but
- when nothing is correctly installed the report can be misinterpreted to suggest
- that all is okay. A more informative message ("Personal REXX is NOT
- installed") and some corrective suggestions would make INSTEST more useful.
-
-
- ΓòÉΓòÉΓòÉ 2.1.3. Compatibility ΓòÉΓòÉΓòÉ
-
- Almost every program that runs under OS/2's REXX will also run under Personal
- REXX. The exceptions are few and are documented. (One very rare condition is
- not documented: If a REXX program is reading characters from the standard
- input and then invokes another program that also is reading from the standard
- input, the second program might not receive the first part of the remaining
- data. This has to do with how Personal REXX reads buffers and here
- compatibility is sacrificed for speed.)
-
- In addition, Personal REXX has loosened some of the constraints in OS/2's REXX.
- It has increased the maximum number of arguments for a procedure from 20 to
- 250, and the number of I/O streams from 15 to 50. But mere compatibility is
- not sufficient reason to use Personal REXX.
-
-
- ΓòÉΓòÉΓòÉ 2.1.4. Enhancements ΓòÉΓòÉΓòÉ
-
- It is, of course, important that programs running OS/2's REXX continue to work
- with Personal REXX. But the real seasoning for this product comes from greater
- speed and abilities.
-
- The first thing you notice when using Personal REXX is that programs run
- faster. In most cases the difference is not only noticeable, it is striking.
- Like moving from a 386 to a 486, or from a 486 to a Pentium, performance
- typically doubles or better. Some people use REXX for easy prototyping and
- then recode in C for speed. Personal REXX surprisingly often can be an
- acceptable alternative to a compiled program. In addition to programs running
- faster, Personal REXX includes functions for things that either cannot be done
- in standard REXX or that would otherwise need clever workarounds.
-
- The utilities enhancements to standard REXX can be grouped into three areas:
- PC hardware; the Operating System; and miscellaneous functions. With the
- hardware functions you can discover the PC type, the type of drives on the
- system, the type of keyboard, the number of serial and parallel ports, and so
- on. You can change the cursor position, make sounds from the PC's speaker,
- change the shift state of the NumLock and CapsLock keys, and more. (There is
- some difference in the kinds of things that can be done by the OS/2 version and
- the DOS version of Personal REXX. This is related to the degree the operating
- system isolates a program from the physical environment and the meaningfulness
- of the information. For example, in OS/2 you don't have PEEK() and POKE(), and
- there is no such thing as EMS memory.)
-
- Operating system functions can sometimes be handled in REXX simply by passing
- the command on to the OS environment. Personal REXX provides functions that do
- these too, and more. In addition to DOSCD() to change the current directory,
- there is also DOSISDEV() and DOSISDIR() to detect whether something is a file
- or a device.
-
- Miscellaneous functions provided with Personal REXX include some that it would
- be easy to imagine had been left out of standard REXX by mistake. In
- particular, UPPER() to convert characters to upper case and LOWER(), plus
- DATECONV() to convert a date from one type to another.
-
- CMS-like facilities
-
- For the old guard REXX programmer who learned the language when it first
- appeared on IBM's mainframes, Personal REXX gives some consideration. The
- three commands LISTFILE, EXECIO, and GLOBALV were a staple of such old REXX
- programs. In this package these three commands are included as utilities,
- making it easier to convert code to run on PCs.
-
-
- ΓòÉΓòÉΓòÉ 2.1.5. REXXLIB ΓòÉΓòÉΓòÉ
-
- REXXLIB is a package included with Personal REXX for OS/2, but one can purchase
- it separately to use with OS/2's REXX. It contains a wide range of functions
- to make programming easier.
-
- One group of functions repairs a major deficiency in the language itself.
- Compound variables serve the same purpose as arrays do in other languages.
- These variables can have arbitrary indexes - a valuable tool. But REXX cannot
- simply find all indexes that have been defined, which reduces the power of
- arbitrary indexes. REXXLIB addresses this flaw with CVTAILS() and related
- functions: CVTAILS() makes an array of all the tails of a compound variable.
- CVWRITE() writes all values of a variable to a file and CVREAD() reads values
- from this file. CVCOPY() copies the values of a compound variable.
-
- Another type of compound variable is known as an array. Here, the stem indexes
- begin at 1 and increase sequentially. The total number of array elements is
- kept in the element 0. Functions developed for this are: ARRAYCOPY(),
- ARRAYDELETE(), ARRAYINSERT(), and ARRAYSORT().
-
- VARDUMP(), VARREAD(), and VARWRITE() read and write the values of variables
- from and to a file. This makes it easy for a program to recall what it was
- doing the last time it ran.
-
- There are also functions that deal with OS/2 sessions, processes, and other
- services. These let you, for example, change the priority of a process or kill
- it. In addition, to make working with concurrently running processes easier,
- REXXLIB includes the ability to use semaphores and named pipes.
-
- Finally, the package includes some very useful mathematical functions:
- logarithms (LOG(), LOG10()); exponentiation (EXP(), POW(), SQRT());
- trigonometric (SIN(), COS(), TAN(), etc.); hyperbolic (COSH(), SINH(), TANH());
- plus ERF(), ERFC(), and GAMMA().
-
-
- ΓòÉΓòÉΓòÉ 2.1.6. Conclusion ΓòÉΓòÉΓòÉ
-
- Personal REXX for OS/2 with REXXLIB adds speed and power to REXX in the OS/2
- environment. True, it doesn't match the glitter of the GUI REXXes, but in raw
- performance it shines.
-
- Contact information:
-
- Quercus Systems
- P.O. Box 2157
- Saratoga, CA 95070
- (408) 867-7399
- Fax: (408) 867-7489
- BBS: (408) 867-7488
-
-
- ΓòÉΓòÉΓòÉ 2.2. TCP/IP Socket Programming in REXX ΓòÉΓòÉΓòÉ
-
- Written by Patrick Mueller
-
- Legal Glorp
-
- Copyright IBM Corp., 1994. All Rights Reserved.
-
- While the information provided herein is believed to be accurate, IBM does not
- warrant the information, and the information is provided "as is".
-
- OS/2 is a trademark of International Business Machines Corp.
- Unix is a trademark of X/Open Company Ltd.
-
-
- Introduction
-
- Remember when your mother used to tell you "Don't stick things into the wall
- outlets - sockets are dangerous!" Well, you've grown up, and guess what:
- sockets are fun to play with! At least TCP/IP sockets are. TCP/IP sockets are
- the programming interface used by all your favorite TCP/IP programs, including
- FTP, TELNET, news readers, IRC, and so forth.
-
- Most implementations of TCP/IP provide a programming toolkit that includes a C
- language library for socket functions. I've created a REXX interface to the
- TCP/IP socket functions as provided by the IBM TCP/IP product, allowing
- programs that use sockets to be written in the REXX language as well as the C
- language.
-
- In this article, I will discuss how to write programs in REXX that access
- TCP/IP sockets. First, I give an overview of sockets, followed by a
- description of the socket programming interface available for REXX. Then, I
- explain the sample programs shipped with the article (TMSG.CMD and TMSGD.CMD).
- Finally, I list a set of references that provide more information on
- programming with sockets, and what you can use sockets for.
-
- After reading the article, you should have enough information to start
- implementing clients and servers for your favorite TCP/IP protocols, or
- implementing new protocols and applications in REXX that run over TCP/IP.
-
-
- ΓòÉΓòÉΓòÉ 2.2.1. What are sockets? ΓòÉΓòÉΓòÉ
-
- The TCP/IP programming interface provides a way to allow multiple computers to
- work together, assuming that they are connected somehow. Computers that are
- connected form a network, and there are a number of different ways computers
- can be connected to one another: Token Ring LANs, Ethernet, telephone
- connections, and so on. Although it is possible to write programs with a
- specific type of connection in mind, it is often not practical to do so.
- Instead, there are abstraction layers for network programming that provide
- common programming interfaces and handle the underlying physical network
- connections for you.
-
- TCP/IP is one such abstraction layer. There are TCP/IP implementations
- available for nearly all popular networks. It is also widely available on
- various harware platforms - from lowly 8088 PCs, to supercomputers - and
- everything in between. So, programming to the TCP/IP layer not only gives you
- network independence, but also some level of platform independence.
-
- The lowest level of programming to the TCP/IP layer is done with sockets.
- Sockets are in many ways similar to file handles in traditional programming
- languages. Within a program, you open a socket, read from the socket, write to
- the socket, and close the socket. The main difference is that instead of a
- file handle being associated with a file on a disk drive, a socket is
- associated with another program that is also reading and writing data on the
- socket. In this manner, sockets are similar in behavior to pipes on OS/2 and
- Unix.
-
- Programs that use sockets often use a client/server model. In this model, a
- server program and a client program both open sockets and connect them
- together. The client sends some data to the server; the server reads the data,
- does some processing, and sends data back to the client. The client then reads
- that data back from the server. This data exchange can continue back and forth
- for some time. Eventually, both the client and server program close their
- sockets and end the communication.
-
- As an example, consider news readers and news servers. When you read Usenet
- news, you start up your news reader (client). The client connects to an
- already-running news server (server). The client requests information from the
- server, for instance, "list all the subject lines for articles in the
- comp.os.os2.programmer.misc news group". The client requests the information
- by sending this command (in a more standardized form than the English example
- given above) to the server. The server consults its database of Usenet news and
- sends back the list of subject lines. This sort of command/response flow is
- typical of the client/server model.
-
-
- ΓòÉΓòÉΓòÉ 2.2.2. Socket functions for sending and receiving data ΓòÉΓòÉΓòÉ
-
- Below is a description of the basic socket functions that TCP/IP socket
- programs can use. There are functions to open and close a socket and functions
- to read from and write to a socket. The functions described are the REXX
- functions available in the rxSock function package.
-
- o SockSocket(family,type,protocol)
-
- This function creates a new socket and returns it to the caller. The socket
- is an integer value. The socket is used by all the other socket functions,
- passed as the first parameter.
-
- The parameters passed to the socket determine different flavors of socket the
- programmer can use. Most of the time, the values AF_INET, SOCK_STREAM, and
- IPPROTO_TCP are used as the parameters, respectively. Other values are used
- only for special purposes.
-
- o SockRecv(socket,buffer,length,flags)
-
- This function reads data from the socket. The buffer parameter is the name
- of a variable that will be used to place the data received from the socket.
- The length parameter is the maximum amount of data to be received by the
- socket. The flags parameter is generally unused and is optional.
-
- The number of bytes actually read into the buffer variable is returned from
- the function.
-
- o SockSend(socket,string,flags)
-
- This function writes data into the socket. The string parameter is the data
- sent into the socket. The flags parameter is generally unused and is
- optional.
-
- The number of bytes actually written is returned from the function.
-
- o SockClose(socket)
-
- This function closes a socket and makes it unusable on both sides of the
- connection.
-
- Sockets have the following properties:
-
- o The data sent and received on a socket is not translated in any way. If your
- programs must deal with EBCDIC and ASCII character encoding, or byte ordering
- of integers, you need to provide this in your program.
-
- o Sockets are full duplex, meaning that a program can both read and write to
- the same socket.
-
- o Data transmitted via SockSend() can be broken up by the underlying software
- into smaller units. For example, if a SockSend() of 8 bytes occurs, the data
- may be received by one call to SockRecv() returning 3 bytes, and the next
- call to SockRecv() returning 5 bytes.
-
- o If a program calls SockRecv() and the other program has not sent any data via
- SockSend(), the SockRecv() call blocks until some data has been sent, or the
- socket is closed on the SockSend() side.
-
- The properties described above imply that the client and server programs have
- to know something about the data being sent over the network. For instance, if
- you plan on sending binary data as 2-or 4-byte integers between a client and
- server, you'll have to decide before writing the programs what the order of the
- bytes in the integer will be. On most PC workstations, integers are stored
- internally with their bytes reversed. For instance, the number 0x12AB is
- stored internally as AB 12. Many of the higher-powered, non-PC workstations
- store integers without the bytes reversed. Choose either the reversed or
- non-reversed format, and then make sure the hardware your program is running on
- uses that format. If it doesn't, reverse the bytes before sending them (or
- after receiving them, as the case may be).
-
- Also, because text sent with SockSend() can be broken into multiple packets,
- you will have to determine how the program doing the SockRecv() will decide
- when it has received enough data. It can't read until it gets everything,
- since it will eventually block. Instead, you will have to rely on one of the
- following techniques:
-
- o Have the sender and receiver pass messages of a predetermined, fixed length.
-
- o Have the sender sender prefix the data being sent with its length, which the
- receiver can read first to determine the length of the data to be received.
-
- o Have the sender add a special character or characters to the end of the data
- to signify the end of the data. Many client/server programs use this method,
- particularly if they are sending textual data across the network. The
- terminating characters are often a carriage return, followed by a line feed.
-
-
- ΓòÉΓòÉΓòÉ 2.2.3. Socket functions for connecting clients and servers ΓòÉΓòÉΓòÉ
-
- The functions SockRecv() and SockSend() described above only can be used once a
- socket is connected to another machine. But how does the connection between
- two programs take place? In order for a client program to talk to a server
- program, the client has to know on what machine the server is running. Every
- machine on the TCP/IP network is uniquely identified by a 32-bit number, called
- its Internet address, or IP address. Because 32-bit numbers can get rather
- unwieldy to use for humans, they are often displayed as four 8-bit numbers,
- converted to decimal numbers with dots between them, called dot decimal
- addresses. For example, the address 9.67.225.165 corresponds to the 32-bit
- number 9 * 256^3 + 67 * 256^2 + 225 * 256 + 165 = 155,443,621. Even dot
- decimal addresses are unwieldy, so there's usually a human readable name also
- associated with each IP address, called its hostname.
-
- The socket functions generally deal with IP addresses. There is a function -
- SockGetHostByName() - that can be used to convert a hostname to an IP address,
- so many programs accept either an IP address or hostname as a machine address.
- When a hostname is passed in, it is converted to an IP address, and that
- address is used in the remainder of the program.
-
- Because there is often more than one server program running on a machine, there
- must be a way to distinguish between them. This is done with a port. A port
- is just an integral number that is associated with a particular server. Most
- of the programs provided with TCP/IP, such as FTP, TELNET, SMTP (mail), have
- "well-known" ports associated with them. The well-known port for FTP is 21,
- and the well-known port for TELNET is 23. In other words, any program that
- wants to interact with an FTP server uses 21 as the port. Two servers on the
- same machine cannot use the same port.
-
- If you are writing your own client and server program with sockets, you'll need
- to have the client and server agree on a port. This can be done by hard-coding
- it in your program or by allowing it to be passed in as a parameter to the
- program.
-
- The combination of an address and port are enough to distinguish any particular
- server running on any machine in the network. These two numbers are set in the
- address stem variable, which is used in functions to connect clients and
- servers. These functions are described below. See the rxsock.doc file shipped
- with the rxSock function package for more information on the address stem
- variable.
-
- o SockBind(socket,address)
-
- This function is used by servers to reserve a port. The port field of the
- address stem variable is filled in with the port the server will be using.
-
- o SockAccept(socket,address)
-
- This function is used by a server to wait for a client to try to make a
- connection. The socket must have been bound with the SockBind() function
- above before calling SockAccept(). Once the connection is made, the function
- returns a new socket and fills in the address stem variable with the IP
- address of the client. The new socket returned is used for all other
- communication with the client. The original socket remains open, waiting for
- new connections.
-
- o SockConnect(socket,address)
-
- This function is used by a client when it tries to connect to a server. The
- address stem variable is filled in with the IP address and port of the
- server.
-
- The basic flow of the reading, writing, and connecting functions is shown
- below.
-
- Note that the loop for SockSend() and SockRecv() is dependant on the
- application - some clients will just send, receive, or send and receive data
- once. The loop enclosing SockAccept() on the server is to handle each client ;
- each time through the loop corresponds with one client session. The
- SockClose() call in the loop on the server is to close the socket obtained by
- SockAccept(), not the socket obtained by SockSocket().
-
- client server
- ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ
- SockSocket()
- SockBind()
- SockSocket()
- loop ...
- SockConnect() SockAccept()
-
- loop ... loop ...
- SockSend() SockRecv()
- SockRecv() SockSend()
-
- SockClose() SockClose()
- SockClose()
-
-
- ΓòÉΓòÉΓòÉ 2.2.4. rxSock - the REXX Socket Programming Function Package ΓòÉΓòÉΓòÉ
-
- Up until now I've only discussed the socket functions themselves. The socket
- functions are not included in OS/2 REXX itself, but implemented in a function
- package. The function package is implemented in an OS/2 Dynamic Link Library
- (DLL), available from the IBM Employee Written Software (EWS) program. EWS
- files are available from a number of places, including CompuServe, and the
- ftp.cdrom.com and software.watson.ibm.com anonymous FTP sites. Look for a
- subdirectory called EWS. On ftp.cdrom.com, rxsock is located in the
- /pub/os2/ibm/ews subdirectory. The rxSock function package is in a file called
- rxsock.zip. Unpack the .ZIP file, and read the rxsock.doc file for installation
- instructions and reference material on the functions in rxSock.
-
- The REXX functions implemented in rxSock closely match the socket functions
- available to C programs. If you already know C, once you learn the REXX socket
- functions, you won't have any problem learning the C socket functions. In this
- respect, rxSock provides a way to prototype socket programs in REXX, and then
- implement them in C for speed.
-
- The rxSock function package is supported with the OS/2 TCP/IP product, versions
- 1.2.1 and 2.0. At this time, I know of no other non-IBM TCP/IP implementations
- that support rxSock.
-
-
- ΓòÉΓòÉΓòÉ 2.2.5. Example programs - TMSG and TMSGD ΓòÉΓòÉΓòÉ
-
- Now it's time to put all the pieces together and write an application. This
- example is an application to send a textual message from one OS/2 machine to
- another.
-
- Two programs are used to implement the application: TMSG is the client, and
- TMSGD is the server. The client program is used to send a message to the
- server. The server receives the message and displays it on the console.
-
- To start the server, just run the TMSGD program. It will display a startup
- message and then wait for clients to send messages. The program will not
- terminate unless you press Ctrl-C or Ctrl-Break.
-
- To use the client, run the TMSG program, passing it the hostname of the machine
- to display the message on, followed by the text of the message.
-
- To test the programs on your own system,
-
- 1. start the server
- 2. run the client, passing your hostname as the first parameter
-
- Both programs assign a port number (the same number) at the top of the program,
- and make sure the rxSock package is loaded.
-
- The TMSG program does the following:
-
- o Converts the hostname to an IP address
- o Creates a socket
- o Connects the socket to the server
- o Sends the message to the server - the message is followed by a carriage
- return and then a linefeed character
- o Closes the socket
-
- The TMSGD program does the following:
-
- o Creates a socket
- o Minds the socket to a port
- o Loops through the following processing (once per client connection)
-
- - Accepts a connection from the client
-
- - Converts the client's IP address to a hostname
-
- - Reads the message from the client - it reads from the socket until it
- receives a carriage return and then a linefeed character.
-
- - Closes the socket returned from the SockAccept() call
-
- - Displays the message
-
- A few notes on some of the other processing the programs do:
-
- o The client program does a SockRecv() before closing the socket. The server
- never sends any data back, but the SockRecv() call will return having read 0
- bytes when the server closes the socket. The call to SockRecv() does nothing
- more than wait for the server to close its side of the socket before the
- client closes its side. If the client were to close its socket before the
- server read all the data, the server might not receive all the data.
-
- o In this example, the client program never received anything back from the
- server. Quite often, the client receives data back from the server after
- sending it some data, but not always.
-
- o The SockListen() call by the server is used to set the backlog of connections
- that TCP/IP will handle. If the server gets a connection request while it's
- processing another client, this connection will be queued up until the server
- can handle it. The number passed to SockListen() determines the maximum
- number of connection requests the will be queued up by the server.
-
-
- ΓòÉΓòÉΓòÉ 2.2.6. References ΓòÉΓòÉΓòÉ
-
- Two good books on socket programming are:
-
- o "Internetworking with TCP/IP" by Douglas Comer, ISBN 0134685059
-
- o "Unix Network Programming" by Richard Stevens, ISBN 0139498761
-
- The Comer book focuses more on TCP/IP, especially on the internals of TCP/IP,
- and the Stevens book focuses more on different types of interprocess
- communication on Unix systems. Unless you are really interested in the
- internals of TCP/IP, the Stevens book is probably the better source of
- information.
-
- Many of the TCP/IP protocols used by programs are documented in RFC files
- (Request For Comments). These include NNTP (news), TELNET, FTP, and hundreds
- more. These files may be obtained via the Internet from venera.isi.edu in the
- in-notes directory. The rfc-index.txt file contains an index of all the RFCs
- currently available.
-
- There are a few programs publically available that make use of the rxSock
- function package. These programs are available via anonymous ftp to
- ftp.cdrom.com, in the /pub/os2/2_x/network subdirectory. The programs are:
-
- fingerd.zip a finger server
-
- ntp.zip a Network Time Protocol (NTP) client
-
- rxnew11a.zip an NNTP news reader
-
- Besides being useful programs in their own right, the programs can also be used
- as further examples of socket programming with the rxSock function package.
-
-
- ΓòÉΓòÉΓòÉ 3. Columns ΓòÉΓòÉΓòÉ
-
- The following columns can be found in this issue:
-
- o C++ Corner
- o Introduction to PM Programming
- o Scratch Patch
-
-
- ΓòÉΓòÉΓòÉ 3.1. C++ Corner ΓòÉΓòÉΓòÉ
-
- Written by Gordon Zeglinski
-
- At long last the infamous C-Set++ 2.1 CD-ROM has arrived! Was it worth the
- wait?
-
- This column will look at the new features in C-Set++ 2.1, and then benchmark
- the compiler against the Watcom C/C++ v9.5a compiler using POV version 2.1 and
- a mini-application from numerical analysis. POV has been chosen as a test
- program because its source is freely available and it is fairly popular.
-
-
- ΓòÉΓòÉΓòÉ 3.1.1. What's New? ΓòÉΓòÉΓòÉ
-
- The new features in C-Set++ 2.1 are:
-
- o WorkFrame version 2.1
- o Drag-and-drop support to the User Interface Class Libs
- o KASE:Set
-
- Bundled features in C-Set++ 2.1 are:
-
- o CSD Level 002 applied to the compiler, tools, and the user interface class
- libraries.
- o Toolkit 2.1
-
- Note: by now, the compiler is at CSD level 005, and the user interface class
- libs are at CSD level 003.
-
- WorkFrame Version 2.1
-
- The new WorkFrame (WF for short) is nothing short of pure WPS magic. As with
- most magic, it doesn't always work though. Before getting to the disappointing
- stuff, let's look at the new whiz-bang features.
-
- The new WF is totally different that the older versions of the WF. It
- introduces several new WPS objects, two of which are, the WorkFrame/2 Project
- and the WorkFrame/2 Composite Project. The WorkFrame/2 Project is roughly
- analogous to the projects in WF version 1.x.
-
- The new projects are enhanced to allow source files being located in multiple
- directories, and it has a more intelligent make file creator. At last, the
- make file creator "remembers" which files have been previously selected, and
- what actions to perform on them! The WorkFrame/2 Composite Project objects
- allows multiple targets to be maked at once or in sequence. Typically, these
- multiple targets (or projects in WF terminology) are the various components of
- the application like DLL's, help files, etc.
-
- The best feature in the new WF is its make file creator. It not only remembers
- previous selections, but also masks out files whose extensions don't match the
- actions you are doing. For instance, suppose, you are compiling and linking
- your code; only files matching the masks of *.C, *.CPP, etc. would be shown in
- the file list of the makefile creator.
-
- Like the previous versions, version 2.1 is still compiler independent. It uses
- objects called Actions Profiles to provide a WPS front end to the actions a
- tool can perform.
-
- On to the bad part, the WPS is not 100% bug free. Thus, any of its bugs will
- affect the WF. On top of that, the WF isn't 100% bug free either. Numerous
- warning message boxes have popped up telling me that some unknown detached
- processed has generated some sort of exception and that it should be
- terminated.
-
- These, however, are not too bad as OS/2 is quite capable of surviving them. The
- more serious bugs will actually hang OS/2. Most PM developers are aware of how
- fragile the message dispatch thread is to exceptions. The easiest way to hang
- PM is to have an exception occur in this thread. The WF unfortunately has a
- few of these bugs too. Also, the migrate option in the new WF doesn't migrate
- all of my old WF 1.1 projects.
-
- Overall, the new WF is a big improvement over WF 1.1, but is also a bit less
- stable. I'm sure it will improve over time.
-
- Drag and Drop Support to the User Interface Class Libraries
-
- Basically, this is an extension to the user interface class libs that shipped
- with C-Set++ 2.0. It is comprised of several new classes which encapsulate
- OS/2's drag and drop mechanism. This topic in itself could cover several
- issues, so I'll not get into any details here but rather save it for a future
- column or two. For those who can't wait, the C-Set distribution includes
- several sample programs that illustrate their use and some documentation on
- them.
-
- KASE:Set
-
- This is the most disappointing part of the package simply because my
- expectations were high. This package makes use of existing IBM supplied tools
- for editing dialog resources, bitmaps, and icons. It does provide a built-in
- menu editor, but I found it a bit awkward to use. This product can't be used
- to generate many of today's applications due to it's limitations. However,
- some people may find it fun to play with. The Guidelines product, which has a
- one free copy per organization license, is better for those interested in code
- generating tools.
-
- Note: Guidelines also requires C-Set++ at present.
-
- IPMD
-
- IPMD is the debugger included with the C-Set++ 2.1 (and the C-Set++ FirstStep)
- package. Although it is the same debugger that is mentioned in my previous
- compiler showdown, many debugger features were not discussed in that issue
- because of the number of compiler packages looked at. We will look at some of
- these features here.
-
- The debugger is PM based and is equipped with many features designed to help
- debug PM based applications. It has message queue monitor that can be used to
- display the PM messages being sent to an application. These messages can be
- filtered on the bases of the window they are going to, the message queue they
- are sent to, and by the actual message. A nice feature here is that you can
- specify how your custom messages are displayed.
-
- For instance, if your application has defined the message WM_USER+1 as
- MSG_MY_MESSAGE, you can configure IPMD to display MSG_MY_MESSAGE as the message
- instead of the number given by WM_USER+1. In addition, the message parameters
- are displayed in a form that represents their interpretation for the given
- message. If a message specifies that paramater 1 holds two SHORTs, IPMD will
- display the message as two short integers. Another nice feature for PM
- programmers is the window analysis views. In these views, all the details
- about the windows an application has created are shown.
-
- For C++ programmers, the debugger includes a hierarchy browser. The real value
- in this browser is realized when you are using class libraries written by other
- people. The hierarchy can be viewed in a graphical form, and explored in a
- textual form.
-
- As expected, the debugger includes all the features common to debuggers in
- general,, ncluding, variable viewers/modifiers, break points, etc. But one
- feature I haven't seem on a PC-based debugger is it's ability to save the debug
- state when you exit the debugger. Saving the debug state saves the
- breakpoints, open source code views, and various monitor windows (the PM
- message monitor, variable monitor, etc.). This feature is of use to both PM
- and non-PM programmers alike.
-
-
- ΓòÉΓòÉΓòÉ 3.1.2. On with the Benchmarks. ΓòÉΓòÉΓòÉ
-
- As I mentioned before, POV 2.1 will be used as the test program for these
- benchmarks. Both compile times and execution times will be measured. In
- addition to POV 2.1, a specialized heat transfer application based on the
- finite difference method will also be tested. For the curious, makefiles for
- the C-Set++ and Watcom compilers are included.
-
- POV 2.1 test
-
- First, let's look at the code generation. The following table presents the
- results from this first test:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- ΓöéCompiler ΓöéCompile Time ΓöéExecutable Size Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- ΓöéWatcom C/C++ 9.5a Γöé6 min 20 sec Γöé239006 Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- ΓöéC-Set++ CSD005 Γöé4 min 42 sec Γöé343040 Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- Now let's look at the time it takes to trace the following scene:
-
- The above scene is the result of test 1. Test 1 traces the scene into a
- 200x200 image using antialiasing. Test 2 traces the same scene into a 100x100
- image without antialiasing.
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- ΓöéTest Number ΓöéWatcom Time ΓöéC-Set++ Time Γöératio: Γöé
- Γöé Γöé Γöé ΓöéWatcom/C-Set++ Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé1 Γöé59 min 8 sec Γöé46 min 2 sec Γöé1.28 Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé2 Γöé2 min 17 sec Γöé1 min 45 sec Γöé1.30 Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- Heat Transfer App. Test
-
- The heat transfer application is based around the Gauss-Seidel iterative method
- for solving matrix systems. The code is not object-oriented, but it makes use
- of a few C++ specific features. The Gauss-Seidel method is quite common in
- certain areas of numerical analysis; thus, it was included in this comparison
- to reflect a real world application.
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- ΓöéCompiler ΓöéCompile Time ΓöéExecutable Size Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- ΓöéWatcom C/C++ 9.5a Γöé48/46 sec Γöé44290 Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- ΓöéC-Set++ CSD005 Γöé41/37 sec Γöé73716 Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- The compile times given are in the form of first compile/second compile. The
- first compile refers the first time the compiler is executed within the VIO
- window. The second refers the second time the compiler is executed within the
- same VIO window. This was done, because this application comprises of only one
- fairly small source file. A better feel for the compile time can be achieved
- by averaging the two times.
-
- The execution time shown below, is for a 216x216 matrix.
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- ΓöéCompiler ΓöéExecution Time Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- ΓöéWatcom C/C++ 9.5a Γöé27 sec Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- ΓöéC-Set++ CSD005 Γöé31 sec Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- Notes For The Curious
-
- The heat transfer program will prompt you to enter the number of nodes in the X
- and Y directions. The number of nodes must follow the following equations:
-
- NODES =(3/N)+1
- x
-
- NODES =(1/N)+1
- y
-
- N must be less than or equal to 0.5 and 1/N must be an integer.
-
- The program will also prompt you for the value of k and H. Any non zero value
- can be used for these two variables.
-
- Bits and Pieces
-
- The tests were performed on a 486 DX2-66 based system with 128K external cache
- and 16M of main RAM. The execution times and compile times were measured after
- rebooting OS/2 except where noted otherwise.
-
- Two zip files are included with this column. POV.ZIP includes the makefile for
- the watcom version of POV for OS/2. The file HEAT.ZIP includes the
- executables, source code, and makefiles for the program used in the heat
- transfer application test.
-
-
- ΓòÉΓòÉΓòÉ 3.1.3. Summary ΓòÉΓòÉΓòÉ
-
- For a C-Set++ 2.0 owner, the real value of the C-Set++ 2.1 package lies in it's
- inclusion of the new WorkFrame, the drag and drop support objects in the user
- interface library, and the 2.1 toolkit. Although C-Set++ generates code that
- is somewhat larger than that generated by the Watcom compiler, it may or may
- not be faster than the Watcom compiler. Your mileage will vary depending on
- the application.
-
- More importantly, there are cases where the speed of the executable is not
- important. This is especially true, in applications which depend heavily on
- user interaction or those which are I/O-bound. When developing PM
- applications, the quality of the support tools is just as important as the
- quality of the compiler. Without a good PM aware debugger, discovering why a
- PM application is not behaving as expected would more be difficult.
-
-
- ΓòÉΓòÉΓòÉ 3.2. Introduction to PM Programming ΓòÉΓòÉΓòÉ
-
- Written by Larry Salomon, Jr.
-
- The purpose of this column is to provide to the readers out there who are not
- familiar with PM application development the information necessary to satisfy
- their curiousity, educate themselves, and give them an advantage over the
- documentation supplied by IBM. Of course, much of this stuff could probably be
- found in one of the many books out there, but the problem with books in general
- is that they don't answer the questions you have after you read the book the
- first time through.
-
- I will gladly entertain feedback from the readers about what was "glossed over"
- or what was detailed well, what tangential topics need to be covered and what
- superfluous crap should have been removed. This feedback is essential in
- guaranteeing that you get what you pay for. :)
-
- It should be said that you must not depend solely on this column to teach you
- how to develop PM applications; instead, this should be viewed as a supplement
- to your other information storehouses (books, the network conferences, etc.).
- Because this column must take a general approach, there will be some topics
- that would like to see discussed that really do not belong here. Specific
- questions can be directed to the Scratch Patch, where an attempt to answer them
- will be made.
-
-
- ΓòÉΓòÉΓòÉ 3.2.1. Last Month ΓòÉΓòÉΓòÉ
-
- Last month, we took a good hard look at a very typical main() function for a PM
- application. We discussed in detail the WinCreateStdWindow() function, as well
- as the many parameters and flags it can take. Finally, we started looking at
- window procedures and some of the more important messages that you - as a PM
- developer - will be interested in.
-
- Since a large portion of PM application development is done in coding the
- window procedure, this month, we will begin to look more closely at this beast
- and see how, through the use of various messages, we can tame it in order to
- accomplish our own goals.
-
-
- ΓòÉΓòÉΓòÉ 3.2.2. Presentation Spaces, the WM_PAINT Message, and Painting ΓòÉΓòÉΓòÉ
-
- Since the most important task you will probably have to perform will be
- painting your window, let us first look at the mechanism used to accomplish
- this. Reproduced below from last month's column is the simple window procedure
- that we saw.
-
- MRESULT EXPENTRY windowProc(HWND hwndWnd,
- ULONG ulMsg,
- MPARAM mpParm1,
- MPARAM mpParm2)
- {
- switch (ulMsg) {
- case WM_PAINT:
- {
- HPS hpsPaint;
- RECTL rclPaint;
-
- hpsPaint=WinBeginPaint(hwndWnd,NULLHANDLE,&rclPaint);
-
- WinFillRect(hpsPaint,&rclPaint,SYSCLR_WINDOW);
-
- WinQueryWindowRect(hwndWnd,&rclPaint);
-
- WinDrawText(hpsPaint,
- -1,
- "Hello world.",
- &rclPaint,
- CLR_BLACK,
- 0,
- DT_CENTER|DT_VCENTER);
-
- WinEndPaint(hpsPaint);
- }
- break;
- default:
- return WinDefWindowProc(hwndWnd,ulMsg,mpParm1,mpParm2);
- } /* endswitch */
-
- return MRFROMSHORT(FALSE);
- }
-
- Figure 1) Simple window procedure
-
- Hmmm...The variable hpsPaint - of the type HPS - seems to be used quite a bit.
- What is an HPS? Looking into os2defs.h, we don't see much to help answer this.
-
- typedef LHANDLE HPS;
- typedef HPS *PHPS;
-
- In case you haven't associated the title of this section with our question, an
- HPS is a handle to a presentation space. Okay, that helps a lot...not! What
- is a presentation space?
-
- Presentation Spaces and Device Contexts
-
- The easiest way to explain a presentation space is to use the familiar (and
- usually very vague, as you should remember from your college days :) "logical
- and physical" explanation. Consider an output device, which has numerous
- physical characteristics: the size of the output medium, the current colors,
- the current font, etc. All of these characteristics are physical
- characteristics, and they are collectively known as a device context.
-
- Figure 2) Physical output device
-
- However, as a programmer, you don't want to have to be cognizant of the types
- and brands of each output device; thus, OS/2 provides the concept of a logical
- device which has an analagous set of characteristics. This logical device is
- called a presentation space (HPS). When you draw on the HPS, PM automatically
- converts all of the logical characteristics to their physical equivalents.
-
- Figure 3) Logical output which results in the figure 2
-
- The point is, and this is the only part you need to remember, any drawing is
- done on an HPS.
-
- Invalidation
-
- One of the many characteristics that an HPS has is called a clipping region.
- If you'll recall, last issue in the New Concepts section of this column, figure
- 5 illustrated many children clipped to their parent. While it was implied that
- clipping areas - or regions as they are called - are rectangular, this is not
- always the case.
-
- Figure 4) No clipping
-
- Figure 4 illustrates a drawing of a box with no clipping applied. Applying a
- clipping region of a triangular shape yields the following (the clipping
- boundary is shown as a dotted line for illustrative purposes only):
-
- Figure 5) Triangular clipping
-
- Whenever any portion of your window needs repainting, the section that needs to
- be painted is said to be invalid. While PM could in fact provide a precise
- clipping region that outlines the invalid portion, for performance reasons, it
- instead provides the coordinates of the smallest rectangle to completely bound
- the invalid area. Why are we bothering with all of this? Keep reading...
-
- The WM_PAINT Message
-
- Whenever your window has an invalid region, PM sends your window procedure a
- WM_PAINT message.
-
- WM_PAINT
-
- This message occurs when an application needs to repaint itself.
-
- Parameters
-
- param1
-
- Reserved.
-
- NULL Reserved value.
-
- param2
-
- Reserved.
-
- NULL Reserved value.
-
- Returns
-
- reply
-
- Reserved.
-
- NULL Reserved value.
-
- Since we have already said that, in order to do any drawing, you need an HPS,
- all that is left to reveal is the method by which you obtain one. As you have
- probably guessed, the function to use is WinBeginPaint().
-
- HPS WinBeginPaint(HWND hwndWindow,
- HPS hpsCreated,
- PRECTL prclInvalid);
-
- hwndWindow - the window for which the HPS is to be obtained.
-
- hpsCreated - used whenever you have already created an HPS and would like to
- use it instead of having the system allocate one for you. We will always
- specify NULLHANDLE for this parameter.
-
- prclInvalid - points to a RECTL structure to receive the bounding rectangle.
- This can be NULL.
-
- For reasons beyond the scope of this column, the HPS must be returned to the
- system once you are finished. The function to do this is WinEndPaint(), and
- its only parameter is the HPS to release.
-
- BOOL WinEndPaint(HPS hpsRelease);
-
- Some important things to note:
-
- o The HPS returned by WinBeginPaint() automatically has a clipping region set
- to the bounding rectangle returned in prclInvalid. This rectangle is
- returned to the caller to take advantage of any painting optimizations
- possible by restricting the area that is repainted to only the rectangle.
- o The WinEndPaint() call sets the invalid region to empty (empty is also
- referred to as NULLHANDLE with respect to regions, since they are also a
- datatype in PM).
- o You cannot use WinBeginPaint() and WinEndPaint() except in the context of a
- WM_PAINT message. Should you need to do any drawing in any other message,
- the functions WinGetPS() and WinReleasePS() should be used. This is because
- there will be no invalid region, so everything will be clipped.
- o An HPS is used to allow you to draw only. It does not remember what was
- drawn, so you must redraw each time you receive a WM_PAINT message. There
- are ways around this, however, which we will look at in future issues.
-
-
- ΓòÉΓòÉΓòÉ 3.2.3. Now That I Have an HPS, What do I do Next? ΓòÉΓòÉΓòÉ
-
- There is an entire system devoted to drawing, known as the Graphical
- Programming Interface but usually referred to as the Gpi. Since it is so
- extensive, we will not cover it directly; instead, some of the more common
- functions will be explained as they are encountered.
-
- In the Win subsystem, however, there are a number of functions which provide
- access to the more commonly needed functions.
-
- o WinDrawBitmap() - draws a bitmap at a specified position, with some control
- over appearance
- o WinDrawBorder() - draws a border inside a specified rectangle
- o WinDrawPointer() - draws a mouse pointer or an icon at a specified position
- o WinDrawText() - draws a string at a specified position, with many different
- options for appearance
- o WinFillRect() - fills the specified rectangle with the specified color
- o WinInvertRect() - inverts (a la xor) the specified rectangle
-
- I will leave it as a reader exercise to refer to the Programming Reference for
- more information about these functions.
-
-
- ΓòÉΓòÉΓòÉ 3.2.4. And On The First Day... ΓòÉΓòÉΓòÉ
-
- ...&deity. sent a WM_CREATE message. :)
-
- The final topic for this month's column is two new messages: these are the
- WM_CREATE and WM_DESTROY messages.
-
- WM_CREATE
-
- This message occurs when an application requests the creation of a window.
-
- Parameters
-
- param1
-
- pvData (PVOID)
-
- Window-specific data that is specified on the call to
- WinCreateWindow().
-
- param2
-
- pcsCreate (PCREATESTRUCT)
-
- Points to a CREATESTRUCT structure that specifies the various initial
- characteristics of the window, e.g. size, position, etc.
-
- Returns
-
- reply
-
- bReply (BOOL)
-
- Success indicator:
-
- FALSE Initialization succeeded. Continue with window creation.
- TRUE Initialization failed. Do not create the window.
-
- WM_DESTROY
-
- This message occurs when an application destroys a window.
-
- Parameters
-
- param1
-
- Reserved.
-
- NULL Reserved value.
-
- param2
-
- Reserved.
-
- NULL Reserved value.
-
- Returns
-
- reply
-
- Reserved.
-
- NULL Reserved value.
-
- These two messages are sent to allow a window to perform any initialization and
- termination processing. As shown, if initialization fails, the window
- procedure should return TRUE to prohibit the creation of the window.
-
- A couple of things should be noted:
-
- o The window procedure is directly invoked to send the WM_CREATE message. This
- is different than it being sent or posted to the window procedure in that the
- window doesn't actually exist until the processing completes and returns
- FALSE. This significance is noted because, since the window doesn't really
- exist, certain functions will not work properly (i.e. WinQueryWindowRect(),
- WinQueryWindowPos(), etc.). Instead, you should use the values of the fields
- of the pcsCreate parameter.
- o Last issue, we saw the following code:
-
- hwndFrame=WinCreateStdWindow(HWND_DESKTOP,
- WS_VISIBLE,
- &ulCreate,
- CLS_CLIENT,
- "Hello World Sample",
- 0,
- NULLHANDLE,
- RES_CLIENT,
- &hwndClient);
-
- Since the WM_CREATE message is a direct function call, WinCreateStdWindow()
- hasn't returned yet, and so hwndFrame is still uninitialized. If the
- unlikely event that you declare hwndFrame to be a global variable, you cannot
- use its value in the WM_CREATE message processing. Instead, you should use
- the function WinQueryWindow() in the following manner:
-
- case WM_CREATE:
- {
- HWND hwndFrame;
-
- :
- hwndFrame=WinQueryWindow(hwndWnd,QW_PARENT);
- :
- }
- break;
-
- Before you shrug your shoulders and say "Yeah, that's nice, but what is the
- real benefit of these messages?", keep reading...
-
- Think back to the first installment of this column, where it was said that a
- window procedure is the common way of referring to the entity called a window
- class procedure. The point here is that, should you write an application that
- has to create multiple windows of the same class (which you developed), you can
- no longer use global or static variables to store information that must be
- shared among message processing blocks. This is because all windows of the
- class share these variables; if one window needs to update the value of one
- variable, the update will affect all windows of that class.
-
- To alleviate this, PM has the idea of window words, which are additional bytes
- of memory allocated for each instance of a window class. You could, for
- example, then specify that an additional 4 bytes of memory is to be allocated,
- and then use those 4 bytes to point to a structure containing instance-specific
- data. See the section Design in the article Development of a New Window Class
- - Part 1 in issue 4 of EDM/2 for more information about window words.
-
- Another common reason for using these messages is for creating other window
- that are the children of your window class. For example, say you want to
- display a list of choices, and underneath you want to display the text
- currently selected. There are two defined window classes - listboxes and
- static controls - which individually do part of what is desired. You could
- then create them as part of the initialization process and if either should
- fail, return TRUE to stop the application from continuing.
-
-
- ΓòÉΓòÉΓòÉ 3.2.5. Summary ΓòÉΓòÉΓòÉ
-
- This month, we took a much more detailed look at the concept of painting and
- how presentation spaces are used by the system to hide the specifics of
- whatever physical output medium is connected to the CPU. We explained update
- regions and their corresponding bounding rectangles, and their relationship to
- invalid regions. Finally, we looked at two new messages - WM_CREATE and
- WM_DESTROY - and briefly touched on their purpose.
-
- If you understood everything in this column and the last one, you should be
- able to look at intro.zip (provided last month) and understand most - if not
- all - of the program source code. This should be verified in order to
- determine your retention percentage, and, should any further clarification be
- necessary, send me email with your questions.
-
- Next month, we will introduce some of the other controls in order to discuss
- dialog boxes and how they are used to communicate with the user. We will also
- take a more detailed look at resources and how they are used in the development
- of dialog boxes. Finally, we will continue our perusal of the messages that
- are commonly used in PM application development.
-
-
- ΓòÉΓòÉΓòÉ 3.3. Scratch Patch ΓòÉΓòÉΓòÉ
-
- Written by Larry Salomon, Jr.
-
- Welcome to this month's "Scratch Patch"! Each month, I collect various items
- that fit into this column sent to me via email. The ones that I feel contribute
- the most to developers, whether in terms of information or as a nifty trick to
- tuck into your cap, get published in this column.
-
- To submit an item, send it via email to my address - os2man@panix.com - and be
- sure to grant permission to publish it (those that forget will not be
- considered for publication). This month, we have the following:
-
- o Questions and Answers
- o Snippet(s) of the Month
- o Want Ads
-
-
- ΓòÉΓòÉΓòÉ 3.3.1. Questions and Answers ΓòÉΓòÉΓòÉ
-
- Unfortunately, I saved the following questions while replying to the sender's
- mail. Since the Elm mail utility doesn't put the header information into the
- temporary file used to compose the mail, I do not have the address of this
- person, nor the name.
-
- Nonetheless, he (I remember the gender at least!) writes:
-
- I have three questions that are really starting to drive me crazy, so hopefully
- they are driving other people crazy and would make good inclusions into the
- next EDM/2.
-
- 1) I've seen programs that have their icon bound into the .EXE somehow rather
- than in [extended attributes]. The WPS has no problem finding the icon in this
- programs and displaying it from a program object or from the drives object.
- How is this done? I even have source for programs that do this, and I still
- can't figure out what they are doing that I'm not!
-
- 2) I've designed a nice dialog box with IBM's Dialog Editor. In it I have
- some static text fields with their font's and colors changed to make them look
- nice (e.g. I have the title of the program in 18.Tms Rmn). Unfortunately, I've
- found that dragging a scheme from the scheme palette onto my dialog causes all
- of the fonts to revert to System Proportional! :-( From what I can tell, PM
- does not send any message before it kills everything, only after
- (WM_PRESPARAMSCHANGED). How can I keep things from being changed? The
- behavior that I would like to see would be for the drag-n-drop operation to be
- denied (I don't know the actually terminology, but you get that "circle with a
- bar in it" icon).
-
- 3) This is the most frustrating one. I've been through the PM Reference so
- many times I can hardly see, and I still haven't figured out how to load a font
- resource. I have all of my resources bound into my .EXE, but GpiLoadFonts()
- requires the name of a .FON file. The font is one that I have created in IBM's
- Font Editor, and I've included in in my resource file like so:
-
- FONT ID_MAIN "c:\\project\\myproject\\myfont.fnt"
-
- Thanks for any help you can give me. You have full permission to do absolutely
- anything with these questions you want, including print them in EDM/2 :-)
-
- 1) The first icon resource found is used, I believe.
-
- 2) All three palettes work in this way: when they receive the WM_BEGINDRAG
- message, they capture the mouse ; when the WM_ENDDRAG message is received, they
- call WinWindowFromPoint() to get the handle of the window under the mouse;
- finally, they call WinSetPresParam() to change the appropriate attributes.
- Thus, they aren't using direct manipulation, so you can't stop it from
- happening.
-
- 3) Fonts can only be loaded from .FON files, which are nothing more than DLL's
- with a different extension. The easiest way to create this is to write a short
- C program which contains a static function dummy(). This function is defined
- as such:
-
- VOID dummy(VOID)
- {
- }
-
- This will compile and link, creating a .DLL that you can bind your font to.
- Rename the file to .FON and you're finished.
-
-
- ΓòÉΓòÉΓòÉ 3.3.2. Snippet(s) of the Month ΓòÉΓòÉΓòÉ
-
- This following function was submitted (along with a host of other functions) by
- our own Gordon Zeglinski. It can be found in the file scratch.zip.
-
- VOID AddSysMenuItem ( HWND hwndFrame, MENUITEM *Item, PSZ Text )
- {
- /***************************************************************************
- * Local Declarations *
- ***************************************************************************/
-
- HWND hwndSysMenu ;
- HWND hwndSysSubMenu ;
- USHORT idSysMenu ;
- MENUITEM miSysMenu ;
-
- /***************************************************************************
- * Obtain the system menu window handle. *
- ***************************************************************************/
-
- hwndSysMenu = WinWindowFromID ( hwndFrame, FID_SYSMENU ) ;
-
- /***************************************************************************
- * Get the system menu's base item and its window handle. *
- ***************************************************************************/
-
- idSysMenu = SHORT1FROMMR ( WinSendMsg ( hwndSysMenu,
- MM_ITEMIDFROMPOSITION,
- NULL,
- NULL ) ) ;
-
- WinSendMsg ( hwndSysMenu,
- MM_QUERYITEM,
- MPFROM2SHORT(idSysMenu,FALSE),
- MPFROMP(&miSysMenu) ) ;
-
- hwndSysSubMenu = miSysMenu.hwndSubMenu ;
-
- /***************************************************************************
- * Add the new item to the system menu's submenu, which is what we see. *
- ***************************************************************************/
-
- WinSendMsg ( hwndSysSubMenu, MM_INSERTITEM, MPFROMP(Item), MPFROMP(Text) ) ;
- }
-
-
- ΓòÉΓòÉΓòÉ 3.3.3. Want Ads ΓòÉΓòÉΓòÉ
-
- Below are the hot topics as of this issue's writing. Feel free to write on any
- of these.
-
- Workplace Shell Programming (hot) - lately, I have noticed two things: 1) lots
- of people want to learn how to write new Workplace Shell classes and 2) no one
- who knows anything about it is telling the rest of us how to do it. I'll even
- stoop down to accepting an article in ASCII format on this topic! :)
-
- Client/Server (hot) - using either named pipes (with or without a network) or
- sockets, client/server programming is all-the-rage these days. On a related
- note, some people have also expressed an interest in learning about interfacing
- with the various protocol drivers (e.g. NDIS, IPX/SPX, etc.). Any articles in
- this area are most welcome.
-
- Multimedia (warm) - last month we had two articles on this topic. However,
- they both dealt with sound, which we all know is not the only alternative media
- type. Articles on anything else - MIDI, video, etc. - are needed.
-
- Animation (warm) - a few readers expressed an interest in the various animation
- techniques that can be applied to PM applications. The ultimate article, in my
- opinion, would be one that develops a sprite library a la the Commodore 64's
- (and Amiga's?) built-in routines, since this is probably the hardest component
- of any good animation sequence. Call this a "personal request"...
-
-
- ΓòÉΓòÉΓòÉ 4. How do I get EDM/2? ΓòÉΓòÉΓòÉ
-
- EDM/2 can be obtained in any of the following ways:
-
- On the Internet
-
- o All back issues are available via anonymous FTP from ftp.cdrom.com in the
- /pub/os2/2_x/program/newsltr directory.
- o The EDM/2 mailing list. Send an empty message to edm2-info@knex.via.mind.org
- to receive a file containing (among other things) instructions for
- subscribing to EDM/2.
- o IBM's external gopher server, which I have not the address of, in Almaden.
-
- On Compuserve
-
- All back issues are available in the OS/2 Developers Forum 2.
-
- IBM Internal
-
- o IBM's internal gopher server, which I have not the address of, in Almaden.
- o IBM's REQUEST command on all internal VM systems. Enter the VM command
- REQUEST LIST FROM ASSELIN AT RALVM12 and a list of the requestable packages
- will be sent to you; in this list are the names of the packages containing
- the EDM/2 issues.
-
-
- ΓòÉΓòÉΓòÉ 5. Contributors to this Issue ΓòÉΓòÉΓòÉ
-
- Are You a Potential Author?
-
- As always, we are always looking for (new) authors. If you have a topic about
- which you would like to write, send a brief description of the topic
- electronically to any of the editors, whose addresses are listed below, by the
- 15th of the month in which your article will appear. This alerts us that you
- will be sending an article so that we can plan the issue layout accordingly.
- After you have done this, get the latest copy of the Article Submission
- Guidelines from ftp.cdrom.com in the /pub/os2/2_x/program/newsltr directory.
- (the file is artsub.zip) The completed text of your article should be sent to
- us no later than the last day of the month; any articles received after that
- time may be pushed to the next issue.
-
- The editors can be reached at the following email addresses:
-
- o Larry Salomon - os2man@panix.com (Internet).
-
- The following people contributed to this issue in one form or another (in
- alphabetical order):
-
- o Larry Salomon, Jr.
- o Jonathan Story
- o Gordon Zeglinski
- o Network distributors
-
-
- ΓòÉΓòÉΓòÉ 5.1. Patrick Mueller ΓòÉΓòÉΓòÉ
-
- Patrick Mueller is currently working in the Software Solutions division of IBM
- in Cary, North Carolina. He has been working for IBM for eight years, on
- various things including spell- and grammar-checking systems, editors,
- distributed systems, and object oriented programming. He has written a number
- of programs for the OS/2 Employee Written Software Program (EWS), including
- rxMath, rxSock, rxFTP, RxD, cPost, and cBook.
-
- Patrick can be reached electronically via the Internet at pmuellr@vnet.ibm.com.
-
-
- ΓòÉΓòÉΓòÉ 5.2. Larry Salomon, Jr. ΓòÉΓòÉΓòÉ
-
- Larry Salomon wrote his first Presentation Manager application for OS/2 version
- 1.1 in 1989. Since that time, he has written numerous VIO and PM applications,
- including the Scramble applet included with OS/2 and the I-Brow/Magnify/Screen
- Capture trio included with the IBM Professional Developers Kit CD-ROM currently
- being distributed by IBM. Currently, he works for International Masters
- Publishers in Stamford, Connecticut and resides in Bellerose, New York with his
- wife Lisa.
-
- Larry can be reached electronically via the Internet at os2man@panix.com.
-
-
- ΓòÉΓòÉΓòÉ 5.3. Jonathan Story ΓòÉΓòÉΓòÉ
-
- Jonathan Story is associated with the Vancouver PC Users Society - OS/2 Special
- Interest Group. He can be reach via email on the Internet at
- jonathan@jspc.wimsey.bc.ca.
-
-
- ΓòÉΓòÉΓòÉ 5.4. Gordon Zeglinski ΓòÉΓòÉΓòÉ
-
- Gordon Zeglinski is a freelance programmer/consultant who received his Master's
- degree in Mechanical Engineering with a thesis on C++ sparse matrix objects.
- He has been programming in C++ for 6 years and also has a strong background in
- FORTRAN. He started developing OS/2 applications with version 2.0 .
-
- His current projects include a client/server communications program that
- utilitizes OS/2's features which has entered beta testing. Additionally, he is
- involved in the development of a "real-time" automated vehicle based on OS/2
- and using C++ in which he does device driver development and designs the
- applications that comprise the control logic and user interface.
-
- He can be reached via the Internet at zeglins@cc.umanitoba.ca.
-
-
- ΓòÉΓòÉΓòÉ 5.5. Network distributors ΓòÉΓòÉΓòÉ
-
- These people are part of our distribution system to provide EDM/2 on networks
- other than the Internet. Their help to provide access to this magazine for
- others is voluntary and we appreciate them a lot!
-
- o Paul Hethman (hethman@cs.utk.edu) - Compuserve
- o Gess Shankar (gess@knex.via.mind.org) - Internet
- o David Singer (singer@almaden.ibm.com) - IBM Internal
- o Andre Asselin (ASSELIN AT RALVM12) - IBM Internal
-
- If you would like to become a "network distributor", be sure to contact the
- editors so that we can give you the credit you deserve!