💾 Archived View for gemini.spam.works › mirrors › textfiles › computers › DOCUMENTATION › opendoor.t… captured on 2022-06-12 at 06:35:52.
-=-=-=-=-=-=-
?????????? ???????? ?????????? ????????? ??? ??? ??????? ??????? ??????? ??? ??? ??????? ??????? ?????? ??????? ??? ??? ??????? ??????? ??????? ??? ??? ??????? ??????? ?????? ??????? ?????????? ??? ??? ??????? ??? ??? ????????? ??? ??? ??? ??? ??? ??????? ?????????? ??????? ??????? ??? ??? ???????? ??????? ??????? ??? ??????? ??? ??? ??? Online Software Programming Toolkit ??????????????????????????????????????????????????????????????????????????? Programmer's Manual Version 6.00 DOS and Win32 Editions NOTE: Since you will likely want to refer to this manual while working with OpenDoors, it is highly recommended that you take the time to print it out. Simply type COPY OPENDOOR.TXT PRN from your DOS prompt. With the exception of this title page, this document contains only 7-bit ASCII characters. (C) Copyright 1991 - 1996 by Brian Pirie. All Rights Reserved. TABLE OF CONTENTS CHAPTER 1 - INTRODUCTION TO OPENDOORS.......................................5 WELCOME! ...............................................................5 FEATURES OF THE OPENDOORS TOOLKIT ......................................6 CHAPTER 2 - ABOUT THIS EVALUATION COPY AND ORDERING.........................9 THE EVALUATION COPY & BENEFITS OF REGISTERING ..........................9 HOW TO ORDER ...........................................................10 HOW TO ORDER BY MAIL ...................................................11 SENDING YOUR ORDER FEE IN THE MAIL .....................................12 ORDERING BY CREDIT CARD ................................................14 HOW YOU CAN RECEIVE YOUR ORDER .........................................15 ORDERING THE SOURCE CODE ...............................................17 OPENDOORS 6.00 ORDER FORM ..............................................18 OPENDOORS 6.00 FEEDBACK FORM ...........................................19 TERMS OF REGISTRATION AND SOURCE CODE USE ..............................20 CHAPTER 3 - OPENDOORS TUTORIAL..............................................21 ABOUT THIS MANUAL ......................................................21 COMPILING A PROGRAM WITH OPENDOORS .....................................22 LINKING WITH OPENDOORS USING A DOS COMPILER ............................23 LINKING WITH OPENDOORS USING A WINDOWS COMPILER ........................24 RUNNING A DOOR PROGRAM WRITTEN WITH OPENDOORS ..........................26 RUNNING DOS-BASED DOOR PROGRAMS ........................................26 RUNNING WINDOWS 95/NT DOOR PROGRAMS ....................................26 BASICS OF DOOR PROGRAMMING WITH OPENDOORS ..............................29 TOUR OF A SAMPLE DOOR PROGRAM: "EX_VOTE" ...............................33 OTHER EXAMPLE PROGRAMS INCLUDED WITH OPENDOORS .........................38 CHAPTER 4 - THE OPENDOORS API FUNCTIONS.....................................40 OVERVIEW ...............................................................40 TABLE OF MOST COMMONLY USED FUNCTIONS ..................................41 TABLE OF ALL FUNCTIONS .................................................42 OD_ADD_PERSONALITY() ...................................................47 OD_AUTODETECT() ........................................................48 OD_CHAT() ..............................................................50 OD_CARRIER() ...........................................................51 OD_CLEAR_KEYBUFFER() ...................................................53 OD_CLR_LINE() ..........................................................55 OD_CLR_SCR() ...........................................................57 OD_COLOR_CONFIG() ......................................................59 OD_DISP() ..............................................................60 OD_DISP_EMU() ..........................................................62 OD_DISP_STR() ..........................................................63 OD_DRAW_BOX() ..........................................................65 OD_EDIT_STR() ..........................................................68 OD_EXIT() ..............................................................79 OD_GET_ANSWER() ........................................................81 OD_GET_INPUT() .........................................................82 OD_GET_KEY() ...........................................................85 =============================================================================== OpenDoors 6.00 Manual End of Page 2 OD_GETTEXT() ...........................................................89 OD_HOTKEY_MENU() .......................................................90 OD_INIT() ..............................................................92 OD_INPUT_STR() .........................................................95 OD_KERNEL() ............................................................97 OD_LIST_FILES() ........................................................98 OD_LOG_WRITE() .........................................................100 OD_MULTILINE_EDIT() ....................................................101 OD_PAGE() ..............................................................104 OD_PARSE_CMD_LINE() ....................................................105 OD_POPUP_MENU() ........................................................107 OD_PRINTF() ............................................................110 OD_PUTCH() .............................................................115 OD_PUTTEXT() ...........................................................116 OD_REPEAT() ............................................................118 OD_RESTORE_SCREEN() ....................................................120 OD_SAVE_SCREEN() .......................................................121 OD_SCROLL() ............................................................123 OD_SEND_FILE() .........................................................124 OD_SET_ATTRIB() ........................................................128 OD_SET_COLOR() .........................................................131 OD_SET_CURSOR() ........................................................134 OD_SET_DTR() ...........................................................135 OD_SET_PERSONALITY() ...................................................136 OD_SET_STATUSLINE() ....................................................137 OD_SLEEP() .............................................................139 OD_SPAWN() .............................................................141 OD_SPAWNVPE() ..........................................................143 OD_WINDOW_CREATE() .....................................................145 OD_WINDOW_REMOVE() .....................................................147 CHAPTER 5 - THE OPENDOORS CONTROL STRUCTURE.................................148 INTRODUCTION TO THE CONTROL STRUCTURE ..................................148 CONTROL STRUCTURE - DOOR INFO FILE STATS ...............................150 CONTROL STRUCTURE - SERIAL PORT SETTINGS ...............................153 CONTROL STRUCTURE - BBS AND CALLER INFORMATION .........................158 CONTROL STRUCTURE - DOOR SETTINGS ......................................182 CONTROL STRUCTURE - DIAGNOSTICS ........................................185 CONTROL STRUCTURE - OPENDOORS CUSTOMIZATION ............................187 CONTROL STRUCTURE - FUNCTION KEYS ......................................212 CONTROL STRUCTURE - COLOR CUSTOMIZATION ................................216 CONTROL STRUCTURE - TEXT CUSTOMIZATION .................................217 CHAPTER 6 - SPECIAL TOPICS..................................................220 ADDITIONAL INFORMATION ON THE WIN32 VERSION ............................220 CONFIGURATION FILE SYSTEM ..............................................225 DEFINING CUSTOM DOOR INFORMATION FILE FORMATS ..........................230 MULTIPLE PERSONALITY SYSTEM ............................................233 LOG FILE SYSTEM ........................................................235 MAKING DOORS MULTI-NODE-AWARE ..........................................237 CHAPTER 7 - TROUBLESHOOTING AND GETTING ASSISTANCE WITH OPENDOORS...........242 =============================================================================== OpenDoors 6.00 Manual End of Page 3 ABOUT THIS CHAPTER .....................................................242 TROUBLESHOOTING PROBLEMS ...............................................242 SOLUTIONS TO COMMON PROBLEMS ...........................................244 OPENDOORS SUPPORT ......................................................245 THE OPENDOORS SUPPORT BBS ..............................................245 THE OPENDOORS WORD WIDE WEB SITE .......................................246 THE OPENDOORS CONFERENCE ...............................................246 GETTING IN TOUCH WITH ME ...............................................247 APPENDIX A - CONTENTS OF PACKAGE............................................249 APPENDIX B - CHANGES FOR THIS VERSION.......................................250 APPENDIX C - FUTURE VERSIONS................................................254 APPENDIX D - SPECIAL THANKS.................................................255 GLOSSARY....................................................................256 INDEX.......................................................................267 =============================================================================== OpenDoors 6.00 Manual End of Page 4 11 111 11 11 11 11 1111 ------------------------------------------------------------------------------- CHAPTER 1 - INTRODUCTION TO OPENDOORS WELCOME! ------------------------------------------------------------------------------- Welcome to OpenDoors! OpenDoors is a POWERFUL and EASY TO USE online software programming toolkit for C and C++. While OpenDoors is most often used to create add-on "door" programs that run under BBS systems, it can also be used for many other online software applications. By using OpenDoors, you are joining over 500 other programmers from around the world who have used it since it was first released to the public in 1991. Over the years, OpenDoors has grown from a simple BBS door programming library to what is perhaps the most sophisticated, widely used and supported package of its type. What exactly is OpenDoors? OpenDoors provides a complete system that allows you to quickly and easily write spectacular, professional quality interactive online software. With OpenDoors, you can write software such as BBS door programs just as you would write any other program - without having to worry about the many of the internal details of door programming. OpenDoors looks after communicating through the modem, providing ANSI/AVATAR/RIP terminal support and interfacing with a wide variety of BBS packages through door information files (such as DOOR.SYS, DORINFO1.DEF, etc.). OpenDoors also looks after status lines and sysop function keys for DOS shells, chatting, hanging up, and so on. In addition, OpenDoors carries out all the work involved in keeping track of carrier detection, user timeouts and much, much more. OpenDoors is also highly flexible, allowing you to take as little or as much control of your program's behavior as you wish. This package includes both DOS and Win32 versions of OpenDoors. This allows you to build a plain-DOS version of your program to run under a variety of platforms (DOS, DesqView, Windows 3.x, NT, 95 and OS/2), to build a Win32 version that takes special advantage of Windows 95 / NT, or build both versions of your program - the choice is yours. The DOS version of OpenDoors performs its serial I/O using either a FOSSIL driver, or built- in serial I/O capabilities, making the use of a FOSSIL driver =============================================================================== OpenDoors 6.00 Manual End of Page 5 optional. The Win32 version takes special advantage of 32-bit programming, multithreading and the Windows GUI, and allows you to access many services that are provided by Windows, such as ODBC (for database access) and MAPI (for email and messaging). Both the DOS and Win32 versions of OpenDoors can be run under both DOS and Windows-based BBS packages. The DOS version of OpenDoors can also be run under OS/2-based BBS packages. The following section provides more detailed information on the features and capabilities that OpenDoors provides. FEATURES OF THE OPENDOORS TOOLKIT ------------------------------------------------------------------------------- You will find that OpenDoors provides a solid platform to build BBS door programs and other online software on top of. You may want to write simple utility door programs, on-line games or sophisticated applications. Perhaps you are interested in getting into the market of selling online software, or perhaps you just wish to write some custom door programs for a particular BBS system. With OpenDoors, you can accomplish all of these things - and do it much more easily than ever before. Some of the features that OpenDoors provides to : - OpenDoors handles all the "dirty" work involved in writing BBS door programs. Since OpenDoors looks after all the door- related operations for you, you need do next to nothing different when writing door programs than you would when writing any other program. You simply call OpenDoor's simple functions to input, output and control door operation. In fact, many people have converted non-door programs to door programs in only a matter of minutes using OpenDoors. One of the most common comments I receive about OpenDoors is how easy it is to use. - OpenDoors allows you to write software that DIRECTLY support a wide variety of BBS systems, including RemoteAccess, QuickBBS, PC-Board, Maximus, Opus, Wildcat!, WWIV, Spitfire, SuperBBS, Telegard, TriBBS, GAP, and others. - As you would expect, OpenDoors flawlessly monitors the modem's carrier detect signal, to automatically recover when a user hangs up - without your having to do anything extra in your program. OpenDoors also monitors how much time the user has left in the door, and provides a fully adjustable inactivity timeout monitor. - OpenDoors takes care of all the work involved in reading and writing BBS door information files, such as DORINFO1.DEF, =============================================================================== OpenDoors 6.00 Manual End of Page 6 EXITINFO.BBS, CHAIN.TXT, DOOR.SYS, etc. If the particular information is available to OpenDoors, it will provide you with just about everything you could ever want to know about the user on-line, the system your door is running under, and so on. In addition to the many door information file formats supported by OpenDoors, you are also able to define your own custom formats. - OpenDoors also does all the work involved in displaying and automatically updating the door's status line, with information available to the sysop such as user name, location, baud rate, time left, function keys, ANSI/AVATAR/RIP settings, and so on. Using OpenDoors, you can choose from a number of different "personalities". These personalities allows OpenDoors to mimic the status lines and sysop function keys used in various BBS packages. OpenDoors includes personalities that mimic RemoteAccess, PC-Board and Wildcat! OpenDoors also allows you to create your own personalities to mimic any other BBS system. - OpenDoors automatically provides the sysop with all the standard function keys for adjusting user time, hanging up on or even locking out the user, and so on. OpenDoors also provides you with a chat mode, which is available to the sysop by pressing Alt-C. In addition, OpenDoors has full support for sysop shell to DOS, activated by the Alt-J key. - What's more, OpenDoors is designed to be very easy to use. Even the most novice 'C' programmers are able to write professional-quality doors with OpenDoors. It takes care of just about every detail for you, yet still gives you the ability to completely control and customize every detail of your door's behavior. There are even people who begin door programming with OpenDoors, having never programmed in C in the past. - OpenDoors supports both FOSSIL-based and built-in serial I/O capabilities. FOSSIL-based serial I/O can be used for maximum compatibility with various systems and serial ports, including multiple-port serial cards such as DigiBoard. OpenDoors can also operate without a FOSSIL driver, using it's own serial I/O capabilities. OpenDoor's built-in asynchronous communications supports baud rates of up to 115,200 and non-standard serial port configurations. OpenDoors also has the ability to automatically detect which of the two serial I/O methods should be used on a particular system. - OpenDoors also automatically detects when the BBS system is operating in local mode, and supports full local mode operations itself. =============================================================================== OpenDoors 6.00 Manual End of Page 7 - Other OpenDoors functions include a built in sysop-page function that will ask the user why they wish to chat, and then proceed to page the sysop, just as any BBS package would. OpenDoors also provides screen clearing functions (which will detect whether the user has screen clearing turned on), and various ANSI/AVATAR/RIP control functions (which again detect if the user has graphics mode turned on). - In addition to the basic display features of OpenDoors there are also a number of advanced screen control functions. These include functions to save and restore the entire screen, along with functions to save, restore or scroll portions of the screen. Other functions allow you to provide overlapping windows and pop-up menus with highlighted selection bars. - OpenDoors provides a multi-line text editor that you can use to allow the user to enter or edit text files, email messages, or any other text that spans multiple lines. You can customize many of the editor's settings to suit your needs. - OpenDoors has a number of special sub-systems that you may elect to include in your doors. Among these, is a log-file system that allows you to add log file support to your doors with only a single line of programming. - Another valuable OpenDoors sub-system is the configuration file system. Again using only a single line of code, you can add configuration file support to your doors. OpenDoors configuration files permit the sysop using the door to customize the door's behavior to their own preferences. - OpenDoors can also be fully customized in order that you may write door programs that use languages other than English. - Among the ANSI/AVATAR/RIP features found in OpenDoors is the ability to send ANSI/AVATAR/RIP files from disk. This allows you to easily design program screens, and incorporate them into your doors. - OpenDoors also comes with the source code for a number of example doors, which you can modify, or simply extract bits and pieces for use in your own doors. Plus, this manual contains many examples of C source code, to help you in writing nearly any door program you might wish to build. - You may also elect to purchase the source code for OpenDoors, which will permit you to make modifications to any portion of OpenDoors, use any portions of the OpenDoors source code in other programs you write, or merely learn how communications- type programs are written. =============================================================================== OpenDoors 6.00 Manual End of Page 8 2222 22 22 22 22 22 22 222222 ------------------------------------------------------------------------------- CHAPTER 2 - ABOUT THIS EVALUATION COPY AND ORDERING THE EVALUATION COPY & BENEFITS OF REGISTERING ------------------------------------------------------------------------------- OpenDoors is distributed and sold using the conventional "shareware" approach. This complete package can be freely distributed, both online (through BBS systems and the Internet) and on CD-ROMs or other media. This gives you the chance to try OpenDoors before you buy it. Unlike traditional commercial software, you have the opportunity to see OpenDoors first-hand, and determine whether it meets your needs without first paying for it. However, before registering you are only permitted to use it under the following conditions: 1.)You may only use this package for a one month period, and for evaluation purposes only. 2.) Programs written with this package may not be distributed. Also, before registering, any program written with OpenDoors will display a message to the user indicating that OpenDoors is not registered. Of course, this message is removed once you have registered. If you decided to register OpenDoors, you will become the licensed owner of a powerful tool for creating BBS door programs and other online software. Registered (licensed) owners of OpenDoors are entitled to: 1.)Virtually unlimited use of OpenDoors. You may write as many programs as you wish using OpenDoors, and do what you please with these programs. They may be freely distributed, or even sold. What's more, there are no additional royalty fees. Your one time purchase of OpenDoors entitles you to use it as you please. 2.)Your registration entitles you to use both the DOS and Win32 versions of OpenDoors. =============================================================================== OpenDoors 6.00 Manual End of Page 9 3.)You will also be entitled to free upgrades to newer versions of OpenDoors. In addition to the great many features and the quality that this version of OpenDoors has to offer, I am currently working on a great many additions and enhancements for the next version. (See the end of this document for an outline of features currently "in the works".) Any programs you write using this version will also automatically take on many of these new features when you upgrade to the new version. Perhaps the best news of all is the price of OpenDoors. Similar packages sell for $50, $75, or even more. However, this version of OpenDoors will only cost you $28 US Dollars, $34 Canadian Dollars, or the equivalent in your country's currency! (Note that this price will increase in future versions. By registering now, you will save by being able to upgrade to all future versions at no additional charge.) Also, the source code for OpenDoors is now available to licensed users for an additional $28US / $34CDN / equivalent. Ordering a copy of the source code will allow you to customize OpenDoors for your own use, making any changes or additions that you wish. It also gives you the opportunity to see how OpenDoors works, and to use any portions of the OpenDoors code in any other programs you wish to write. If you think you might be interested in ordering the OpenDoors source code, please be sure to read the section entitled "Ordering The Source Code", located on page 20. HOW TO ORDER ------------------------------------------------------------------------------- There are to ways of ordering and OpenDoors license (registration): -The most common way to order is by mailing the OpenDoors order form along with a cheque, money order or cash to the address on this order form. - You may order using a major credit card. OpenDoors credit card orders are handled by a third-party credit card order service, named PsL. The following sections provide more information on how to order using each of these options. =============================================================================== OpenDoors 6.00 Manual End of Page 10 HOW TO ORDER BY MAIL ------------------------------------------------------------------------------- To order OpenDoors by mailing a cheque, money order or cash, simply follow these three steps: 1.) Fill out the registration form. Information on filling out the form is located on page 15. 2.) Send the appropriate payment, $28US/$34CDN/equivalent for the registration or $56US/$68CDN/equivalent for both the registration and source code. If you wish more detailed instructions on sending the registration fee, see the section that begins page on 12. Included in that section is a list of equivalent prices for a number of other countries. 3.) Send the above two items to me at: Brian Pirie 117 Cedarock Drive Kanata ON K2M 2H5 Canada Many people who register OpenDoors also order the source code package. You may wish to consider the benefits of having the OpenDoors source code - it allows you to learn how OpenDoors and communications software is written, it allows you to modify and customize OpenDoors to suit your own preferences, and it also allows you to use portions of OpenDoors for other non-door programming projects. If you think you might also be interested in the OpenDoors source code, be sure to read the section on the source code, which begins on page 20. Also, you may wish to send the OpenDoors feedback form (located on page 19), along with your registration. The feedback form gives you a chance to tell me what you think of OpenDoors, and what changes you would like to see in future versions. In fact, the majority of suggestions made on these forms in the past have already been implemented in the current version of OpenDoors. If you have printed the OpenDoors manual, you can simply remove and mail the forms on pages 18 and 19. If you have not already printed a copy of the manual, and you have a printer, you can quickly print these forms by printing the ORDER.FRM file included in the OpenDoors distribution archive. (Type COPY ORDER.FRM PRN from your DOS prompt.) NO PRINTER? Alternatively, if you do not have a printer, simply send a hand- written version of the order form. =============================================================================== OpenDoors 6.00 Manual End of Page 11 If you have any special instructions for me, or anything that you would like to say when you register, feel free to write this on the back of the registration form, or on a separate piece of paper. When filling out the OpenDoors registration form, be sure to indicate how you would prefer to receive your OpenDoors registration key and/or source code. The following options are available: - Having me send the registration and/or source code by conventional mail - Internet E-Mail (the fastest option) - By Fax - Having me call to your BBS - You calling the OpenDoors support BBS - FidoNet "CrashMail" Once you have decided which means you would prefer to receive your order by, please read the detailed instructions on your order method, below. Also, if you are ordering the source code, please be sure to read the section on ordering the source code, which begins on page 20. SENDING YOUR ORDER FEE IN THE MAIL ------------------------------------------------------------------------------- The price of OpenDoors is 34 Canadian Dollars, 28 U.S. Dollars, or equivalent for the registration. The source code costs an additional 34 Canadian Dollars, 28 U.S. Dollars, or equivalent. For your convenience, the equivalent value in a number of other country's currencies, at the time of this writing, is as follows: ----------------------------------------------- REGISTRATION REGISTRATION ONLY AND SOURCE CODE ----------------------------------------------- 34 Canadian Dollars 68 Canadian Dollars 28 US Dollars 56 US Dollars 18 British Pounds 36 British Pounds 150 French Francs 300 French Francs 44 German Marks 88 German Marks 50 Netherland Gilders 100 Netherland Gilders 39 Australian Dollars 78 Australian Dollars ----------------------------------------------- If you are ordering by mail, this order fee may be paid using any of the following methods: =============================================================================== OpenDoors 6.00 Manual End of Page 12 -Cheque or Money Order in Canadian currency, drawn upon a Canadian bank. In this case, your order fee will be either $34CDN for just the registration, or $68CDN for both the registration and source code. -Cheque or Money Order in U.S. currency, drawn upon a U.S. bank. In this case, your order fee will be either $28US for just the registration, or $56US for both the registration and source code. -An International Money Order or International Bank Draft (available from your bank, post office or companies such as American Express), in Canadian currency. Depending on the particular case, your order fee MAY be sent to me by the postal service, and you will mail your order form by itself. You should have the money order drawn in either $34CDN for just the registration, or $68CDN for both the registration and source code. -A cheque drawn on any bank in the world, IN THAT COUNTRY'S CURRENCY, equivalent to 34 Canadian dollars. For instance, a cheque for the appropriate number of British Pounds, drawn on a British bank, is perfectly acceptable. However, I am unable to accept a cheque for $34 Canadian dollars, drawn on a British Bank. UNFORTUNATELY, THE BANKS IN CANADA ARE CURRENTLY UNWILLING TO ACCEPT EUROCHEQUES. -Cash. Please note that it is not usually recommended that cash be sent in the mail, and that I cannot be responsible for any cash lost in the mail. Simply put, if you wish to order by cash, it is your responsibility to get the cash to me. However, if I do receive your order in the form of cash, it will be perfectly acceptable to me. I would like to mention that many people have already ordered OpenDoors by sending cash, and I have yet to run across any case of cash being lost in the mail. Nonetheless, if you wish to send cash, you may wish to consider doing so by registered mail, for your added security. If you are ordering OpenDoors from within Canada, you will most likely choose the first option (a Canadian cheque or money order). If you are ordering OpenDoors from within the United States, you will most likely choose the second option (an American cheque or money order). If you are ordering from outside Canada and the U.S., it would be ideal if you could send your fee by an international money order. However, it should be noted that any of the above order methods will be acceptable from any location. Also, it is quite possible that I may be able to accept other means of sending your order fee. If you are unsure about sending your order fee, please feel free to get in touch with me by any of the means listed on page 247. =============================================================================== OpenDoors 6.00 Manual End of Page 13 ORDERING BY CREDIT CARD ------------------------------------------------------------------------------- This information applies to CREDIT CARD ORDERS ONLY. Please read this entire section before ordering OpenDoors by credit card. In order to cover the additional costs of processing credit card orders, an $8 shipping and handling fee applies to all OpenDoors orders made through PsL. As such, the total prices you will pay are: - Just registration ($28 + $8 Handling) = $36 U.S. - Registration and Source Code ($56 + $8 Handling) = $64 U.S. (All prices will be charged to your credit card in U.S. Dollars.) You can order OpenDoors with MC, Visa, Amex, or Discover from Public (software) Library by calling 800-2424-PsL or 713-524-6394 or by FAX to 713-524-6398 or by CIS Email to 71355,470. You can also order online through the World Wide Web. For more information on how to do this, visit the OpenDoors Web site. (Information on the OpenDoors web site is provided on page 246.) You can also mail credit card orders to PsL at P.O.Box 35705, Houston, TX 77235-5705. When ordering by phone, you must call between 6:00am and 6:00pm CST on Monday to Thursday, or between 6:00am and 12:30pm on Fridays. THE ABOVE NUMBERS ARE FOR CREDIT CARD ORDERS ONLY. THE AUTHOR OF THIS PROGRAM CANNOT BE REACHED AT THESE NUMBERS. Any questions about the status of the shipment of the order, refunds, registration options, product details, technical support, volume discounts, dealer pricing, site licenses, non- credit card orders, etc., must be directed to: Brian Pirie 117 Cedarock Drive Kanata ON K2M 2H5 Canada To insure that you get the latest version, PsL will notify me the day of your order and I will ship OpenDoors directly to you. I will send OpenDoors by conventional mail unless I have previously heard from you, asking me to send your order by some other means. When ordering by credit card through PsL, please be sure to indicate whether you wish to order just the OpenDoors registration, or both the registration and source code. Also, please be sure to include your credit card billing address. Without this information, PsL will be unable to process your order. =============================================================================== OpenDoors 6.00 Manual End of Page 14 HOW YOU CAN RECEIVE YOUR ORDER ------------------------------------------------------------------------------- For your convenience, I can send your OpenDoors registration key and/or source code by any of the following methods. If you are ordering OpenDoors by mail, simply check one of these options on your order form. If you are ordering through the third-party credit card service, I will automatically send your order by Internet email or conventional mail unless I receive a message from you before you order, asking me to send it by some other means. ------------------------------------------------------------------------------- RECEIVING If you wish to receive your OpenDoors registration key by ORDER BY Internet E-Mail (including Internet E-Mail to a CompuServe INTERNET account), fill out the order form and mail it along with your E-MAIL payment as described below. Be sure to include your e-mail address on your order form. Note that the source code cannot be sent via Internet e-mail. ------------------------------------------------------------------------------- RECEIVING In order to receive your OpenDoors registration key and/or ORDER source code by conventional mail, simply fill out the order BY MAIL form and mail it along with your payment as described below. I will cover the cost of postage. If your address contains non- Roman characters, also enclose a self-addressed envelope or mailing label. ------------------------------------------------------------------------------- RECEIVING If you wish to receive your OpenDoors registration key by ORDER BY FAX, fill out the order form and mail it along with your payment FAX as described below. Be sure to include your fax number on your order form. Do to choose this method if you are ordering the source code. ------------------------------------------------------------------------------- RECEIVING You may choose to receive your OpenDoors registration and/or ORDER BY source code by calling the OpenDoors BBS after your registration CALLING form and order fee have been received here. If you are unable to OPENDOORS receive your order by any other electronic means (such as a call BBS to your BBS, or by electronic mail), this may be the quickest way for you to receive your registration information and/or source code. The obvious disadvantage with to option is the fact that you will have to estimate when your order will arrive here in order to receive it as quickly as possible. You may end up calling the OpenDoors BBS more than once before your order has arrived. After your order form has arrived, your registration key and/or source code will be placed on hold for you, and you =============================================================================== OpenDoors 6.00 Manual End of Page 15 will be able to receive it on your first call to the BBS. The phone number of the BBS is: +1 (613) 599-5554 ------------------------------------------------------------------------------- RECEIVING In order to receive your OpenDoors registration key and/or ORDER BY source code by a message and/or upload to your BBS, fill out CALL TO the order form and mail it along with your payment as described YOUR BBS below. Be sure to include the phone number, baud rate, and my login and password for the BBS to which you would like me to call. As always, I will cover any long distance costs. If, for some reason, I am unable to connect to your BBS (not because it is busy, but, for example, if your BBS is no longer online), I will send your order by conventional mail instead. ------------------------------------------------------------------------------- RECEIVING In order to receive your OpenDoors registration key and/or ORDER BY source code by FidoNet CrashMail, simply fill out the order FIDONET form and mail it along with your payment as described below. CRASHMAIL Be sure to include the FidoNet node address to which you wish to have your registration key and/or source code sent to (via CrashMail). Again I will cover any long distance costs. If, for some reason, I am unable to connect to your FidoNet system, I will send your order by conventional mail instead. =============================================================================== OpenDoors 6.00 Manual End of Page 16 ORDERING THE SOURCE CODE ----------------------------------------------------------------------------- Many people also choose to order the source code along with their OpenDoors registration. Ordering the source code will allow you to customize OpenDoors for your own use, use parts of the OpenDoors source code in other programs, and learn more about how OpenDoors works. If you have any ideas for changes that you would like to see in OpenDoors, either large or small, ordering the source code will allow you to makes these changes yourself, creating your own customized version of OpenDoors. You will be able to remove copyright notices, change the way certain OpenDoors functions work, or add new capabilities to OpenDoors in surprisingly little time. You will also be able to use any of the OpenDoors source code, be it the DesqView-aware code, EMS/disk swapping routines, configuration file system, communications routines, or anything else, in any other programs that you write. Also, ordering the OpenDoors source code will allow you to learn more about how OpenDoors works, and how to program communications software and BBS door programs. When you order the OpenDoors source code, you will receive the source code package. The source code package also includes a short "Source Code Manual", with a description of how the OpenDoors source code is organized, instructions on how to recompile the source code, and more. If you choose to receive the source code package electronically, you will receive it in the form of a single .ZIP file. If you choose to receive the source code package by mail, you will receive it on a 3-1/2" diskette. REQUIREMENTS Due to the wide variety of compilers that are available, and the differences between them, I have been unable to test the OpenDoors source code with every compiler. This means that you may need to make some changes to the source code in order to compile it with certain compilers. In order to compile the DOS version of OpenDoors, you must be using a compiler that supports inline assembly language keywords. This includes all Borland compilers released since 1991, and many other compilers. The one notable exception is Watcom's compiler, which does not support inline assembly language at the time of this writing. For your information, the DOS OpenDoors libraries included with this package were compiled using Turbo C++ 1.0 Professional. The Win32 libraries included with this package were compiled using Microsoft Visual C++ 2.0. This means that you can be reasonably certain that OpenDoors will compile with these compilers and any more recent compilers by these companies without any changes. =============================================================================== OpenDoors 6.00 Manual End of Page 17 -------------------------------------------------------------------------- OPENDOORS 6.00 ORDER FORM -------------------------------------------------------------------------- REGISTRATION NAME : _______________________________ (AS SHOULD APPEAR IN REGISTRATION) YOUR NAME : _______________________________ (IF DIFFERENT) POSTAL ADDRESS : ______________________________________________________ ______________________________________________________ ______________________________________________________ E-MAIL ADDRESSES : ____________________________________ (IF APPLICABLE) ADDITIONAL INFO : ______________________________________________________ (EG FAX/BBS PHONE NUMBER & BRIAN'S PASSWORD, IF NEEDED) I WISH TO RECEIVE MY ORDER BY: ___ ___ | | - INTERNET E-MAIL (FASTEST) | | - I WILL CALL BRIAN'S BBS |___| |___| ___ ___ | | - CONVENTIONAL MAIL | | - CALL TO MY BBS |___| |___| (INCLUDE LOGIN INFO) ___ ___ | | - FAX (INCLUDE FAX #) | | - FIDONET "CRASHMAIL" |___| |___| ___ I WOULD LIKE TO ORDER: | | - BOTH REGISTRATION KEY AND SOURCE CODE |___| ($56 US, $68 CANADIAN, OR EQUIVALENT FUNDS) ___ | | - JUST MY REGISTRATION KEY |___| ($28 US, $34 CANADIAN, OR EQUIVALENT FUNDS) ___ | | - UPGRADE TO SOURCE CODE (ONLY IF ALREADY |___| REGISTERED) ($28 US, $34 CANADIAN OR EQUIV.) I AGREE TO THE REGISTRATION TERMS, ____________________________ SET FORTH ON PAGE 20 OF THE MANUAL (SIGNATURE) MAKE CHEQUES PAYABLE TO: BRIAN PIRIE 117 CEDAROCK DRIVE KANATA ON K2M 2H5 CANADA +-- OFFICIAL USE ONLY ----------------------------------------------------+ | | | S.N. : _____________ SENT : _________________________________________ | +-------------------------------------------------------------------------+ =============================================================================== OpenDoors 6.00 Manual End of Page 18 -------------------------------------------------------------------------- OPENDOORS 6.00 FEEDBACK FORM -------------------------------------------------------------------------- YOUR NAME : _______________________________ WHICH OPENDOORS LIBRARY(S) DO YOU EXPECT TO USE: ___ | | - DOS VERSION, MEMORY MODELS: _________________________ |___| ___ | | - WINDOWS (WIN32) VERSION |___| HOW DID YOU FIRST LEARN OF OPENDOORS? ____________________________________________________________ WHICH COMPILER(S) AND VERSION(S) ARE YOU USING? ____________________________________________________________ WHAT DO YOU LIKE MOST ABOUT OPENDOORS? ____________________________________________________________ ____________________________________________________________ WHAT CHANGES OR ADDITIONS WOULD YOU LIKE TO SEE IN FUTURE VERSIONS? ____________________________________________________________ ____________________________________________________________ DO YOU HAVE ANY ADDITIONAL COMMENTS? ____________________________________________________________ ____________________________________________________________ ____________________________________________________________ ----------------------------------------------------------------------------- =============================================================================== OpenDoors 6.00 Manual End of Page 19 TERMS OF REGISTRATION AND SOURCE CODE USE ----------------------------------------------------------------------------- When you purchase an OpenDoors registration and/or source code license, you are entitled to almost unlimited use of all versions of OpenDoors. However, in order to protect my investment of time and effort in developing OpenDoors, you must also agree to the terms outlined below when licensing OpenDoors and/or the source code. These terms are intended to be very reasonable, and are in no way intended to limit your use of OpenDoors. The primary intent of these terms is that you are not permitted to disclose your OpenDoors registration information, or the OpenDoors source code, to other individuals. The terms of registration and source code use are as follows: For the purpose of these terms, "OpenDoors" is defined to be the library files, header files, example programs and programmer's manual of all versions, past and present, for all languages and platforms of the OpenDoors online software programming toolkit. In the case of a source code license, OpenDoors also refers to the source code that is used to build OpenDoors. Upon licensing OpenDoors, the individual or organization named on the order form (the licensee) is entitled to use of all versions of OpenDoors, within the terms set forth below. Violation of these terms will be considered copyright infringement, and grounds for the termination of the registration agreement. The licensee is entitled, at no additional cost, to use, distribute or sell the executable (.EXE or .COM) files that are built from OpenDoors. The licensee is also entitled to use, distribute or sell the example programs, example configuration files and portions of the manual. If licensing the source code, the licensee is also entitled to distribute or sell any executable files that result from using altered versions of the source code, or portions thereof, provided that it is not possible for other programmers to access the OpenDoors API functions through this executable file. The licensee is NOT entitled to distribute the registration key number that is provided by Brian Pirie, nor any portions of the OpenDoors source code. For the purposes of these terms, an organization is considered to be a company or non- profit organization. If the licensee is an organization, the registration key and source code may be shared among members of the organization, under the condition that these individuals are using the registration and/or source code only for official activities of that organization. These terms in no way suggest an agreement on the part of Brian Pirie to develop any future versions of OpenDoors, or fix any bugs in current versions of OpenDoors. OpenDoors is offered "as is", and no warrantees are expressed or implied. In no event shall Brian Pirie be liable for any loss of profit or any other damage, including but not limited to special, incidental, consequential or other damages. =============================================================================== OpenDoors 6.00 Manual End of Page 20 3333 33 33 33 333 33 33 33 3333 ------------------------------------------------------------------------------- CHAPTER 3 - OPENDOORS TUTORIAL ABOUT THIS MANUAL ------------------------------------------------------------------------------- The OpenDoors programmer's manual is intended to serve as a complete tutorial, guide and reference to writing programs with OpenDoors. Chapter 1 of this manual, beginning on page 5, provides an introduction and overview of the features of OpenDoors. If you are unsure of what OpenDoors will do for you, begin with Chapter 1. Chapter 2, beginning on page 9, provides important information related to this evaluation copy of OpenDoors, and how to register your copy. Chapter 3 serves as a tutorial on OpenDoors and BBS door programming in general. Chapter 4 provides a reference to the OpenDoors API functions which you can use in your programs. Chapter 5 provides a reference to the "OpenDoors control structure", which gives you access to a wide array of information, and allows you to customize OpenDoor's appearance and behavior. Chapter 6 provides information on special OpenDoors features and advanced door programming topics. Among the subjects discussed in chapter 6 are the Win32 version of OpenDoors, configuration files, multi- node operation, RIP graphics, logfile support, defining custom door information file formats, and more. Chapter 7 (which begins on page 242) gives instructions on troubleshooting programs written with OpenDoors, lists solutions to common difficulties, and has information about the many sources for OpenDoors support. If at any time you are having difficulty with OpenDoors, be sure to refer to this chapter for complete step-by-step instruction on tracing the source of your problem, and for solutions to common difficulties with OpenDoors. This chapter also directs you to some of the major sources of support, including information on the OpenDoors email conference, the OpenDoors support BBS, and how to get in touch with me. You will also find many useful tools in this manual, which will no doubt come in useful while working with OpenDoors. Beginning on page 2 is a basic table of contents, showing you how the manual is organized, and helping you to locate general topics. =============================================================================== OpenDoors 6.00 Manual End of Page 21 At the end of the manual, beginning on page 267, is an index to help you locate more information on specific topics. The manual also includes a glossary, on page 256, which will help you in understanding new terms that you may come across while reading the manual. At the end of the manual, you will also find several useful sections, such as information on what is new in this version, information on how to contact me, and information about new OpenDoors features currently in the works. You will likely want to print this manual, to make reading and reference while programming easier. To print this manual, simply type the following line from your DOS prompt. If you are worried about the size of this manual, you might consider using a utility that can print multiple pages of a text file on a single sheet of paper. Printing two manual pages per side of paper should certainly be legible, and even four-up would give you text about the size of average newspaper text. Printing on both sides, you should be able to fit the manual on about 34 sheets of paper (269/8 < 34). COMPILING A PROGRAM WITH OPENDOORS ------------------------------------------------------------------------------- The process of compiling a program written with OpenDoors is very similar to that of compiling any other program. However, there are two additional steps which you must be sure to remember: 1.) You must include the OPENDOOR.H header file. 2.) You must link your program with the appropriate OpenDoors library file. All programs written with OpenDoors, must "include" the OPENDOOR.H header file. If you have placed the OPENDOOR.H header file in the same directory as your program's source code, place the following line at the beginning of your .C or .CPP file(s): #include "opendoor.h" If you have placed the OPENDOOR.H header file in the same directory as other standard header files (such as stdio.h), place the following line at the beginning of your .C or .CPP file(s): #include <opendoor.h> =============================================================================== OpenDoors 6.00 Manual End of Page 22 In addition to including the OpenDoors header file in your source code modules, you must also "link" the appropriate OpenDoors library file with your program. The procedure for doing this depends upon which compiler you are using. The following sections describe how to link with the OpenDoors libraries using various compilers. LINKING WITH OPENDOORS USING A DOS COMPILER ------------------------------------------------------------------------------- This section describes how to link with the provided OpenDoors library files under a variety of DOS compilers. If you are using a compiler other than those described here, refer to your compiler's manual for information on how to link with third- party libraries. If you are using Borland Turbo C 2.00 or earlier, you can cause your compiler to link your program with the OpenDoors library by creating a text file with a .PRJ extension. In this text file, you should list the names of your program's .C modules, along with the name of the appropriate OpenDoors library file, as listed in the table at the end of this section. You should then select this Project file from within the Turbo C IDE prior to compiling your program. If you are using Turbo C++ or Borland C++, you can set your compiler to link your program with the OpenDoors library by creating a project file from within the IDE. To do this, choose the Open Project command from the Project menu, and enter the name for your new project file in the Load Project dialog box. Then add the names of your program's .C/.CPP modules, along with the name of the appropriate OpenDoors library file, by pressing [Insert] in the project window. When you return to Turbo C++ or Borland C++ again, you can work with the same project file by using the Open command from the Project menu. If you are using any Microsoft C compiler, such as Quick C, Microsoft C or Visual C++, you can set your compiler to link your program with the OpenDoors library by creating a makefile. You can create a new project file from within Quick C by using the Set Program List option from the Make menu. You can do this from within Visual C++ by using the New command from the Project menu. You should add the names of your program's .C/.CPP source files, along with the name of the appropriate OpenDoors library file, to the newly create makefile. There are several different DOS library files included with OpenDoors, each one for use with a different memory model. The following chart lists the library file names, along with their corresponding memory model. It is important that you use the =============================================================================== OpenDoors 6.00 Manual End of Page 23 library file which corresponds to the memory model you are using. Whenever you change your compiler to use a different memory model, it is important to rebuild all of your source files (using the "Build All" or "Rebuild All" command) in addition to changing the library that your program is being linked with. If you are unfamiliar with the concept of memory models, you should refer to your compiler's manuals. If you are unsure as to what memory model your compiler is currently using, check this setting in the compile options dialog box or command line reference information. +------------------------------------------------+ | Library | Memory | | Filename | Model | |-------------|----------------------------------| | ODOORS.LIB | DOS small memory model library | | | | | ODOORM.LIB | DOS medium memory model library | | | (Available separately) | | | | | ODOORC.LIB | DOS compact memory model library | | | (Available separately) | | | | | ODOORL.LIB | DOS large memory model library | | | | | ODOORH.LIB | DOS huge memory model library | +------------------------------------------------+ To understand how to compile a program written with OpenDoors, it is a good idea to try compiling one of the example programs, such as ex_hello.c, that are included in the OpenDoors package. LINKING WITH OPENDOORS USING A WINDOWS COMPILER ------------------------------------------------------------------------------- The Win32 version of OpenDoors resides in a DLL, ODOORS60.DLL. In order to use OpenDoors from a Win32 program, you will typically link to an import library (although it is also possible to use load-time dynamic linking through the use of LoadLibrary() and GetProcAddress()). The OpenDoors package includes a COFF-format import library for use Microsoft compilers, named ODOORW.LIB. If you are using a compiler that uses OMF-format object files, such as a Borland compiler, you will need to create your own version of the odoorw.lib import library, by using the implib utility provided with your compiler. When compiling an OpenDoors program with a Windows compiler, be sure that either the WIN32 or __WIN32__ constant is defined. =============================================================================== OpenDoors 6.00 Manual End of Page 24 Microsoft and Borland compilers define one of these constants by default. However, if you are using a compiler from another company, you may need to explicitly configure your compiler to define one of these preprocessor constants. If you are using Microsoft Visual C++ 2.0 or later, you can setup your compiler to link with the OpenDoors import library by creating a makefile (choose File|New|Project) and adding both your program's .C/.CPP source file(s) and the odoorw.lib import library to the project. When prompted for the Project type, choose "Application", not a "MFC AppWizard". If you are using Visual C++ 2.0, then you must manually edit the .mak file using a text editor. In this file, replace all occurrences of "/SUBSYSTEM:windows" with "/SUBSYSTEM:windows,4.0". This instructs the linker to create an executable file that is targeted for Windows 95. If you do not do this, some of the OpenDoors visual elements will not appear correctly. Later versions of Microsoft's compiler default to using "/SUBSYSTEM:windows,4.0", and so this step is no longer necessary with those compilers. If you are using Borland C++ 4.50 or later, you must create an OpenDoors import library for ODOORS60.DLL before you can compile your first OpenDoors program. To do this, go to the directory where ODOORS60.DLL is located, move the original odoorw.lib to a backup location, and issue the command: IMPLIB ODOORW.LIB ODOORS60.DLL This will create a new import library (ODOORW.LIB) which you can then use with your compiler. To compile an OpenDoors program from the command line, issue the command: BCC32 -tW your_program.c ODOORW.LIB To compile an OpenDoors program from within the IDE, create a new project file, and add both your program's source file(s) and the OpenDoors import library to that project. If you are compiling from within the IDE, check the TargetExpert and be sure that you are using the multithreaded version of the the runtime libraries. By default, the Borland IDE compiles single- threaded, which will not work with OpenDoors. Additional information on the Win32 version of OpenDoors is provided in chapter 6. =============================================================================== OpenDoors 6.00 Manual End of Page 25 RUNNING A DOOR PROGRAM WRITTEN WITH OPENDOORS ------------------------------------------------------------------------------- This section provides information on how to run a BBS door program that has been written with OpenDoors. If you are using OpenDoors to write some other form of online software, the information provided here will apply to different degrees, depending on the nature of your program. OpenDoors supports both local and remote modes. In the normal mode of operation, remote mode, your program's output will be displayed to both the local screen and the remote user's screen. To run your program in remote mode, you will usually set it up to run under some BBS package. However, for testing purposes, it is often convenient to run your program in local mode. There are several ways to start your program in local mode. The first method is to place the example DORINFO1.DEF file in the same directory as your program. If your program uses the OpenDoors command line processing function, od_parse_cmd_line(), then you can start your program in local mode by simply specifying -local on your program's command line. For example, you can try the example program include with OpenDoors by issuing the command VOTEDOS -LOCAL (for the DOS version) or VOTEWIN -LOCAL (for the Windows 95/NT version). OpenDoors will also run in local mode if you set it up to run under a BBS package, and log into the BBS in local mode. When the BBS runs your door program, OpenDoors will automatically run in local mode. To run your program in remote mode, you will probably want to run it under a BBS system. If you don't have a BBS package for testing purposes, you might want to obtain a popular BBS package such as Wildcat!, Maximus (which is free) or RemoteAccess. RUNNING DOS-BASED DOOR PROGRAMS ------------------------------------------------------------------------------- DOS BBS packages typically run door programs using one of two methods. Either the BBS package directly loads and executes the program, or it exits to a DOS batch file, which in turn executes the door program. In either case, the BBS package produces a door information file, common called a "drop file", which provides information to the door program such as the name of the current user. OpenDoors automatically supports the common drop file formats, including DORINFOx.DEF and DOOR.SYS. RUNNING WINDOWS 95/NT DOOR PROGRAMS =============================================================================== OpenDoors 6.00 Manual End of Page 26 ------------------------------------------------------------------------------- This section provides information specific to running door programs that are compiled with the Win32 version of OpenDoors. Please feel free to include this information in your program's manual. Since the Win32 version of OpenDoors resides in a DLL, ODOORS60.DLL, this file must be present on any system where your program will be run. Although Windows 95/NT will find this file if it is located in the same directory as your program's executable file, it is a good idea to install this DLL into the Windows system directory. This way, all programs using the Win32 version of OpenDoors can share the same copy of the DLL, reducing the amount of disk space that is used. The required setup for a Windows 95/NT door will depend upon what BBS system it is being run under. If you the program is being run under a native Windows 95/NT BBS system, then ideally that BBS system will provide the ability to pass a live serial port handle to the door program, on the program's command line. Otherwise, you should run the door from a batch file, following the instructions provided below for running the program under a DOS-based BBS system. If the BBS system is able to pass a live Window communications handle on the door's command line, and you are using the OpenDoors standard command-line processing function (od_parse_cmd_line()), then you can just setup the BBS to run the program directly, using the command line: YourProgramName.exe -handle xxxxxxxxxx where xxxxxxxxx is the serial port handle, in decimal format. You do not need to use the start command, nor the DTRON utility, and you do not have to change the COM<n>AutoAssign setting in the system.ini file. If you are running the Win32 door program under a DOS-based BBS system, or a Windows-based BBS system that is unable to pass a live serial port handle to the door program, then follow these steps: 1.Add a line of the form "COM<n>AutoAssign=<x>" to the [386Enh] section of your system.ini file. Here, <n> specifies the serial port number that the BBS's modem is connected to, and <x> will usually be 0. For example, if your modem is connected to COM1, you would add a line such as "COM1AutoAssign=0" (sans quotes). You will then have to re- start your computer for this change to take effect. If you do not do this, the Windows-based door program will not be able to access the modem. =============================================================================== OpenDoors 6.00 Manual End of Page 27 2.Setup the BBS software to run the Windows-based door program just as you would any other door program. You will probably want to do this from a batch file. The command line that runs the Windows program should be of the form: start /w /m YourProgramName.exe [any command line parameters] This will cause the Windows-based door program to start in minimized mode, and cause the calling MS-DOS session to wait until the Windows program exits before continuing. If you do not wish the program to be started in minimized mode, remove the /m from the command line. If you attempt to start the door program by calling it directly, rather than using the "start /w" command, the BBS software will immediately start again, cause it to attempt to run simultaneously with the door program. 3.After running the start command, use DTRON.EXE or a similar utility to re-enable DTR detection by the modem. Normally, this command line will be of the form: dtron /port x /bps y Where x is the serial port number (0 for COM1, 1 for COM2, etc.) and y is the locked bps rate. For example, if your serial port is locked at 38400 bps and is connected to COM2, you would use: dtron /port 1 /bps 38400 For full information on the DTRON utility, simply type the command line: dtron /help You may freely redistribute the DTRON utility that is included in this package with your program. Additional information on the Win32 version of OpenDoors, and further explanation of some of these steps, is provided in chapter 6. =============================================================================== OpenDoors 6.00 Manual End of Page 28 BASICS OF DOOR PROGRAMMING WITH OPENDOORS ------------------------------------------------------------------------------- This section provides a complete tutorial to the basics of writing BBS door programs using OpenDoors. If you are using OpenDoors to write other online software, much of this information will still be relevant. In addition to reading this section, I would encourage you to look at the example programs included int the OpenDoors packages. These programs, which are described beginning on page 38, will give you a much better idea of what an OpenDoors program will look like. These programs can also serve as a great starting point for writing your own programs using OpenDoors. Probably the best means of introduction to door programming with OpenDoors is by doing it yourself. As such, I strongly encourage you to try compiling and running the simple introduction program below. For instructions on compiling programs written with OpenDoors, see page 22. DOS version: #include "opendoor.h" main() { od_printf("Welcome to my first door program!\n\r"); od_printf("Press a key to return to BBS!\n\r"); od_get_key(TRUE); od_exit(0, FALSE); } Win32 version: #include "opendoor.h" int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpszCmdLine,int nCmdShow) { od_printf("Welcome to my first door program!\n\r"); od_printf("Press a key to return to BBS!\n\r"); od_get_key(TRUE); od_exit(0, FALSE); } Keep in mind that even this simple program will automatically have all of the door capabilities we have already mentioned. Notice the line that reads #include "opendoor.h". All programs written with OpenDoors must include the OPENDOOR.H header file in order to compile correctly. The first two lines in the main/WinMain function simply call the OpenDoors od_printf() =============================================================================== OpenDoors 6.00 Manual End of Page 29 function. od_printf() is similar to the printf() function that C programmers will already be familiar with. However, unlike printf(), the od_printf() function sends the output to both the modem and the local screen. Notice that the lines of text displayed by the od_printf() function end with a "\n\r" sequence, instead of the normal "\n". This is because the terminal emulation software that is running on the remote user's system usually requires both a carriage return and a line feed to correctly begin a new line. The next line in our example program is the OpenDoors single-key input function, od_get_key(). The TRUE value causes OpenDoors to wait for a key to be pressed (again, either from remote or local keyboard) before returning. The last line of the main/WinMain function is a call to od_exit(). Any program using OpenDoors should call this function. For the time being, you can always use the (0, FALSE) parameters. Once again, you are encouraged to try compiling and running this program, as described above. Congratulations, you have written your first door program! Feel free to make any changes to this program, and see what effects your changes have. To simplify this example, separate versions of this program are shown for the DOS and Win32 versions of OpenDoors. However, you would typically write your program so that it could be compiled using either the DOS or Win32 versions of OpenDoors, by beginning the mainline function as follows: #ifdef ODPLAT_WIN32 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) #else int main(int argc, char *argv[]) #endif In case you are not entirely familiar with the operation of door programs, we will now provide an introduction to the internals of a door's operation. Keep in mind that OpenDoors automatically carries out most of these tasks for you. When any door program starts up, one of the first things it must do is to read the door information file(s) (sometimes called a "drop file") passed to it by the BBS. When a user is on-line, and wishes to run a door, they will most likely select a command from a menu. At this point, the BBS system (such as RemoteAccess, Maximus, PC- Board or whatever), will create a file of information about the system, who is currently on-line, and so on. Various BBS packages produce various styles of door information files. OpenDoors automatically recognizes and reads a wide variety of door information file formats. As a result, your doors will be able to run on a almost any BBS system. =============================================================================== OpenDoors 6.00 Manual End of Page 30 Fortunately, OpenDoors takes care of all the work involved in detecting and reading the door information file, and then initializing and communicating with the serial port for you. In order to carry out these tasks, along with setting up the status line, and so on, OpenDoors provides a function called od_init(). If you do not explicitly call this function, the first call to any other OpenDoors function (such as the first time your door program outputs anything) will automatically cause the od_init() function to be called. As a result, upon the first call to an OpenDoors function, all of the initialization tasks for the door will automatically be carried out. However, there may be times when you will want your program to have access information about the user who is on-line, or carry out other actions which require od_init() to have been executed - prior to the point where you call any other OpenDoors functions. In this case, you will have to call od_init() yourself before you do any of these things. OpenDoors provides you with a C/C++ structure, by the name of od_control, which allows you to access all the available information about the user who is on-line, the system your door is running on, and also allows you to adjust various OpenDoors parameters. Depending on what BBS system your door is running under, the actual information available from the od_control structure will vary. For more information on the od_control structure, see the section on the control structure, beginning on page 148. Once the door has initialized itself, it will then begin communications with the user who is online. OpenDoors takes care of all communications, through its various input and display functions. When the door has finished, it will then write any information that has changed back to the door information file (if applicable), finish communicating with the modem, and return to the BBS. In OpenDoors, these shut-down operations are automatically performed you call the od_exit() function. This function will terminate the door's activity, OPTIONALLY hang up on the user (allowing you to provide either return to BBS or logoff options for exiting), and then exit with the specified errorlevel. One other important OpenDoors function that you should be aware of is the od_kernel() function. od_kernel() is the central OpenDoors control function, and is responsible for much of OpenDoor's updating of the status line, monitoring the carrier detect and user timeout status, responding to sysop function keys, and so on. The od_kernel() function is called automatically by OpenDoors, within the other OpenDoors functions. As a result, since most door programs will call some OpenDoors function on a regular basis, you will most often have no need to call the od_kernel() function yourself. However, if your door is going to perform some action, such as updating data =============================================================================== OpenDoors 6.00 Manual End of Page 31 files, during which it will not call any OpenDoors function for more than a few seconds, you should then call the od_kernel() function yourself. For more information on the od_kernel() function, see page 97. For more information on the functions available from OpenDoors, or the control structure, see the corresponding sections in this manual. =============================================================================== OpenDoors 6.00 Manual End of Page 32 TOUR OF A SAMPLE DOOR PROGRAM: "EX_VOTE" ------------------------------------------------------------------------------ One of the best ways to see how OpenDoors works, and the potential that it has, is to look at the example programs included in the OpenDoors package. A brief description of each of these programs can be found on page 38. This section takes a closer look at one of the example programs, EX_VOTE.C. Unlike our simple example in the previous section, EX_VOTE.C is a much more complicated program, taking advantage of many of the advanced features of OpenDoors. Even if you do not understand everything that EX_VOTE.C does, you should be able to make use of various elements demonstrated here, in your own programs. The OpenDoors package includes a two compiled versions of EX_VOTE. VOTEDOS.EXE is a plain-DOS program which can run under DOS, Windows or OS/2. VOTEWIN.EXE was compiled using the Win32 version of OpenDoors, and so it runs only on Windows 95/NT. The OpenDoors package also contains a sample door information file, DORINFO1.DEF. You can use this file to test any doors in local mode. If you wish to manually create your own DORINFO1.DEF file, you can do so very easily. The DORINFO1.DEF door information file is a simple text file which lists a different piece of information on each line, in the following format: +----------------------------------------------------------+ | LINE NUMBER | DESCRIPTION | EXAMPLE | +-------------+------------------------+-------------------| | 1 | Name of the BBS | MY OWN BBS | | 2 | Sysop's first name | BRIAN | | 3 | Sysop's last name | PIRIE | | 4 | Com Port modem is on | COM0 | | 5 | Baud rate, etc. | 0 BAUD,N,8,1 | | 6 | Unused | 0 | | 7 | User's first name | JOHN | | 8 | User's last name | PUBLIC | | 9 | Caller's location | OTTAWA, ON | | 10 | ANSI mode (0=off, 1=on)| 1 | | 11 | User's security level | 32000 | | 12 | User's time left | 60 | +----------------------------------------------------------+ Feel free to make any changes you wish to EX_VOTE.C, and recompile it. One of the most effective and enjoyable ways to learn OpenDoors is by experimenting. If you are a registered owner of OpenDoors, you may even distribute your own versions of this door. Also, you may find that EX_VOTE.C serves as a good framework for building your own door programs. The EX_VOTE.C door behaves similarly to most other door programs, and will have a fair bit in common with any other door =============================================================================== OpenDoors 6.00 Manual End of Page 33 you write in OpenDoors. What you see in the output window is identical to what a remote user will be seeing. If the user has ANSI, AVATAR or RIP mode turned on, you will see the same colors as they do, and if they have screen clearing turned on, your screen will be cleared when theirs is. The status line at the bottom of the window will list the name of the user currently on-line (if you are using the sample DORINFO1.DEF file, the user's name will be "The Sysop"), the user's location, and the user's baud rate (0 if the door is operating in local mode). The local display also shows how much time the user has left, whether the user has paged the system operator for a chat, and other information. There are a number of special commands that are only available to the system operator on the local keyboard. These commands allow the system operator to hang up on the user, adjust the amount of time the user may remain online, enter chat mode with the user, enter a DOS shell (in the DOS version), and so on. In the DOS version, help on these commands is available on the status line by pressing the [F9] key. In the Windows version, these commands are listed on the menu that appears at the top of the window. Now, let us take a closer look at the actual source code for the EX_VOTE.C door. If you have not already printed out a copy of this manual, and possibly the EX_VOTE.C file as well, it would probably be a good idea to do so now. Notice that near the top of the program, along with all the standard header files, the OPENDOOR.H file is included. This file must be included in all programs written under OpenDoors. If you are placing the OPENDOOR.H file in the same directory as the door you are compiling, simply include the line: #include "opendoor.h" in your program. The main()/WinMain() function of the EX_VOTE.C program has a for(;;) loop that repeatedly displays the main menu, obtains a choice from the user and responds to the command, until the user chooses to exit the program. Before the main menu is displayed, the screen is cleared by calling od_clr_scr(). The od_clr_scr() function will clear both the local and remote screens, but only if the user has screen clearing enabled. Refer to page 57 for information on how to force the screen to be cleared, regardless of the user's screen clearing setting. The main menu is displayed using the od_printf() function, one of the most common OpenDoors functions you will use. Next, od_get_answer() is used to obtain a menu choice from the user from the specified set of keys. Next, a switch() statement is used to respond to the user's command appropriately. If the user presses the P key to =============================================================================== OpenDoors 6.00 Manual End of Page 34 page the system operator, od_page() is called. If the user chooses to return to the BBS, od_exit() is called to terminate OpenDoor's activities and return control to the BBS. The FALSE parameter passed to od_exit() indicates that OpenDoors should not disconnect (hangup) before exiting. If the user chooses to log off, EX_VOTE.C first confirms this action with the user, and then calls od_exit() with the TRUE parameter. The numerical parameter passed to od_exit() sets the errorlevel that OpenDoors will exit with. In its ChooseQuestion() function, EX_VOTE.C uses the OpenDoors function od_get_key(). This function is similar to the od_get_answer() function that we have already seen. However, unlike od_get_answer() which will wait until the user presses some key from the list of possibilities you provide, od_get_key() will allow the user to press any key. od_get_key() accepts a single parameter. If this parameter is TRUE, od_get_key() will wait for the user to press a key before returning. If this parameter is FALSE, od_get_key() will return immediately with a value of 0 if there are no keys waiting in the inbound buffer, and returning the next key if there are characters waiting. In a number of places, EX_VOTE.C also uses the od_input_str() function. Unlike od_get_key() and od_get_answer() which return a single character, od_input_str() allows the user to input and edit a string of many characters. You will only receive the string entered by the user after they press the enter key. od_input_str() accepts four parameters: the string where the user's input should be stored, the maximum number of characters to input, the minimum character value to accept and the maximum character value to accept. Another new feature of OpenDoors that is used by EX_VOTE.C is the OpenDoors control structure, od_control. This global structure is documented in chapter 5 of this manual. The OpenDoors control structure allows you to access a wide variety of information about the user who is currently online, the BBS system your program is running on, and also allows you to control various OpenDoors settings. For example, EX_VOTE.C compares the current user name (od_control.od_user_name) with the name of the system operator (od_control.od_sysop_name) to determine whether it is the system operator who using the program. EX_VOTE.C uses two data files, the first of which contains a record for every user, and the second of which contains a record for every question. EX_VOTE.C accesses these data files in a controlled manner in order to permit the program to be running simultaneously on multiple lines on a multi-node BBS system. When EX_VOTE.C needs to update a data file, it opens it for exclusive access, so that only one node can access the file at =============================================================================== OpenDoors 6.00 Manual End of Page 35 any given time. Since the data file could have been changed by another node since the time that EX_VOTE.C last read the file, it always reads a record, makes changes to it and then re-writes the record while it has the file open for exclusive access. It then closes the file as soon as possible after opening the file, in order to permit other nodes to once again access the file. Because EX_VOTE.C keeps track of which questions each user has voted on, along with the questions and results of voting on each question, its data file format is more complex than many door programs (although not as complex as others). EX_VOTE.C also uses color. One of the easiest ways to use different colors in an OpenDoors program is to use the OpenDoor's print color-setting extensions. You can change the color of text display at any point in an od_printf() format string using by enclosing the name of new display color in back quote characters (`, not '). For example: od_printf("`red`This is in red `green`This is green\n\r"); Would cause the words "This is in red" to be displayed in red, and the words "This is in green" to be displayed in green. EX_VOTE.C also takes advantage of a number of OpenDoors capabilities that you can optionally choose to include in your door programs. You will notice that there are a number of new lines at the beginning of the main() function, all of which change settings in the OpenDoors control structure. The line: od_control.od_config_file = INCLUDE_CONFIG_FILE; causes the OpenDoors configuration file system to be included in your program. Using this system, OpenDoors automatically reads a configuration file that can be used by the system operator to change various program settings. Refer to the included door.cfg file for an example OpenDoors configuration file. In addition to the configuration file settings automatically supported by the configuration file system, you can also add your own configuration file settings. To do this, you simply supply OpenDoors with a callback function that it will call whenever it encounters an unrecognized keyword in the configuration file. The line: od_control.od_config_function = CustomConfigFunction; Causes OpenDoors to call the function CustomConfigFunction() in EX_VOTE.C for this purpose. You will notice that the CustomConfigFunction() receives two parameters - the first is the unrecognized keyword, and the second is any parameters that follow the keyword in the configuration file. EX_VOTE.C checks for two special configuration file lines - one to set whether or =============================================================================== OpenDoors 6.00 Manual End of Page 36 not users can add questions, and one to set whether or not users can view the results of a question before voting on it. The next line in the main() function, od_control.od_mps = INCLUDE_MPS; causes the OpenDoors "Multiple Personality System" to be included in program. This allows the sysop to choose from a number of status line / sysop function key "personalities" that mimic a number of different BBS systems, using the Personality setting in the configuration file. The line: od_control.od_logfile = INCLUDE_LOGFILE; causes the OpenDoors log file system to be included in the program. The OpenDoors log file system automatically records the date and time of program startup, exit and other major actions in the specified file. EX_VOTE.C also writes its own log file entries by calling the od_log_write() function. EX_VOTE.C also provides the ability for the sysop to provide their own ASCII/ANSI/AVATAR/RIP files to be displayed in place of the normal main menu. EX_VOTE.C uses the od_hotkey_menu() function to display a VOTE.ASC/.ANS/.AVT/.RIP file for the main menu, if such a file exists. If the file is not available, the normal EX_VOTE.C menu is used instead. The od_hotkey_menu() function will automatically select the appropriate file (.ASC/.ANS/.AVT/.RIP) for the current display mode, and the user is able to make a menu choice at any time. If a menu choice is made before the menu is entirely displayed, the function will stop displaying the menu and return immediately. =============================================================================== OpenDoors 6.00 Manual End of Page 37 OTHER EXAMPLE PROGRAMS INCLUDED WITH OPENDOORS ------------------------------------------------------------------------------ In addition to the EX_VOTE.C program, which is discussed in detail in the previous section, a number of other example programs are included with OpenDoors. These programs help to demonstrate what is possible with OpenDoors. They can also serve as excellent tools to help you learn OpenDoors. In addition, you are free to include any portions of any of these example programs in your own programs. Below is a summary of each of these example programs: ------------------------------------------------------------------------------- EX_HELLO.C This an example of a very simple door program that displays a short message and prompts for the user to press a key. After the user presses a key, the door exits and control is returned to the main BBS software. Despite the fact that it only consists of a few lines of code, EX_HELLO remains a fully functional door program. For information on compiling an OpenDoors door program, see the section that begins on page 22. ------------------------------------------------------------------------------- EX_CHAT.C This program is an example of a multi-window full-screen chat door written with OpenDoors. EX_CHAT demonstrates the ease of using sophisticated ANSI / AVATAR / RIP terminal features within OpenDoors programs. For instructions on how to compile this program, see the section that begins on page 22. This program create two windows on the screen, separated by a bar with user name / sysop name information. This program permits communication between the local sysop and remote user by displaying the text typed by the user in one window, and the text typed by the sysop in the other window. When either person's typing reaches the bottom of the window, the contents of the window is scrolled up to provide more room for typing. Words are also wrapped when either typist reaches the end of a line. The advantage of a split-screen chat program is that it permits both sysop and user to type at the same time without difficulty. The chat function automatically invokes OpenDoor's internal chat mode if ANSI, AVATAR or RIP modes are not available. The display colors, window sizes and locations, and distance to scroll a window's contents are configurable by setting the appropriate variables, below. When the Sysop invokes a DOS shell, a pop-up window is displayed to indicate to the user that the door program has been suspended. The chat feature of this program can also be easily integrated into other doors you write, and may be used to replace the existing OpenDoors line-oriented chat system. =============================================================================== OpenDoors 6.00 Manual End of Page 38 ------------------------------------------------------------------------------- EX_MUSIC.C This example door demonstrates how to play "ANSI" music and sound effects in an OpenDoors door. Included in this program is a function to send "ANSI" music to the remote system, and a function to text the remote system's ability to play "ANSI" music. You may use both of these functions in your own doors, if you wish to add music or sound effect capabilities. This program can be compiled by following the instructions that begin on page 22. ------------------------------------------------------------------------------- EX_SKI.C This is a simple but addictive online game that is written using OpenDoors. In this action game, the player must control a skier through a downhill slalom course. The user may turn the skier left or right, and the game ends as soon as the player skis outside the marked course. The game begins at an easy level, but quickly becomes more and more difficult as the course to be navigated becomes more and more narrow. The game maintains a list of players with high scores, and this list may be viewed from the main menu. ------------------------------------------------------------------------------- EX_VOTE.C The EX_VOTE.C file contain the source code for the Vote example door, as is described beginning on page 38. The Vote example door allows users to vote on up to 200 different "polls", view the results of voting on each question, and optionally add their own questions for other users to answer. =============================================================================== OpenDoors 6.00 Manual End of Page 39 444 4444 44 44 44444444 44 44 44 ------------------------------------------------------------------------------- CHAPTER 4 - THE OPENDOORS API FUNCTIONS OVERVIEW ------------------------------------------------------------------------------ OpenDoors provides a wide set of features that you can take advantage of in your program. You control these features and access OpenDoors from your program using two facilities - the OpenDoors API functions, and the OpenDoors control structure. In general, the API functions are used to actually accomplish a task, such as displaying something to the user, or retrieving input from the user. The OpenDoors control structure, on the other hand, is used to alter OpenDoors settings or retrieve specific information. Any program written with OpenDoors makes use of the OpenDoors API functions for all of its door-related input and output. In addition to the common input and output tasks, the OpenDoors API functions provide access to many special capabilities, such as displaying ASCII/ANSI/AVATAR/RIP files, providing pop-up windows and menus, and much more. Much of the information about the user who is online, information about the system your door is running on, and settings which customize OpenDoor's behavior are controlled through the OpenDoors control structure. The control structure is described in the section beginning on page 148. This chapter is divided into the following sections: i.) TABLE OF MOST COMMONLY USED FUNCTIONS (Page 41) ii.) TABLE OF ALL OPENDOORS FUNCTIONS (Page 42) iii.) DETAILED INFORMATION ON EACH FUNCTION (Pages 47 - 147) The two tables list the names of the OpenDoors functions, along with a brief description of the task performed by each function, and the page number on which the detailed description of that function can be found. The first table lists only the most commonly used OpenDoors functions, to allow you to quickly find the function you are most likely looking for. The second table lists all of the OpenDoors functions, grouped according to general categories of functionality. =============================================================================== OpenDoors 6.00 Manual End of Page 40 The section containing detailed information lists all of the functions in alphabetical order, with the information about each function beginning on a new page. This section includes a brief description of each function's purpose, a detailed description of how to use the function, the function call format, a list of related functions, and in many cases example source code showing you a typical use of the function. TABLE OF MOST COMMONLY USED FUNCTIONS ------------------------------------------------------------------------------ od_printf() Displays text, with the ability to change display color. (page 110) od_clr_scr() Clears the screen. (Page 57) od_input_str() Inputs a string of one or more characters from the user. (Page 95) od_get_answer() Inputs a single key from a list of possible choices ignoring upper/lower case. (Page 81) od_get_key() Inputs any single key from the user. (Page 82) od_set_cursor() Positions the cursor in ANSI/AVATAR/RIP modes. (Page 134) od_hotkey_menu() Displays an ASCII/ANSI/AVATAR/RIP file, with the option of watching for a keypress from the user. (Page 90) od_popup_menu() Displays a popup menu in ANSI/AVATAR/RIP modes. (Page 105) od_window_create() Creates a popup window in ANSI/AVATAR/RIP modes. (Page 145) od_window_remove() Removes a popup window in, restoring screen contents "underneath" window. (Page 147) =============================================================================== OpenDoors 6.00 Manual End of Page 41 TABLE OF ALL FUNCTIONS ------------------------------------------------------------------------------- OUTPUT TEXT DISPLAY FUNCTIONS FUNCTIONS ---------------------- od_disp_str() Displays a normal, NULL-terminated string. (page 63) od_disp() Sends the specified number of characters to the modem, with or without local echo. (page 60) od_printf() Performs formatted output, as the printf() function does. Also allows imbedded codes to change display color. (page 110) od_putch() Displays a single character. (page 115) od_disp_emu() Displays a string, interpreting imbedded ANSI/AVATAR terminal emulation codes. (page 62) od_repeat() Displays the same character any number of times, using AVATAR optimization, if possible. (page 118) COLOR AND CURSOR CONTROL ------------------------ od_set_color() Sets current color to specified foreground and background settings. (page 131) od_set_attrib() Sets current color to specified IBM-PC display attribute. (page 128) od_set_cursor() Sets the position of the cursor, if ANSI/AVATAR/RIP mode is enabled. (page 134) SCREEN MANIPULATION ------------------- od_clr_scr() Clears the screen, if user has screen clearing enabled. (page 57) od_save_screen() Stores the current contents of the screen, to be later redisplayed using od_restore_screen(). Works in all display modes. (page 121) od_restore_screen() Restores the contents of the screen, as previously stored using =============================================================================== OpenDoors 6.00 Manual End of Page 42 od_save_screen(). Works in all display modes. (page 120) BLOCK MANIPULATION ------------------ od_clr_line() Clears the remainder of current line. (page 55) od_gettext() Stores any area of the screen, to later be displayed by od_puttext(). Requires ANSI/AVATAR/RIP graphics mode. (page 89) od_puttext() Displays text with color information, as previously stored using od_gettext(). Requires ANSI/AVATAR/RIP graphics mode. (page 116) od_scroll() Scrolls a portion of the screen in ANSI/AVATAR/RIP graphics modes. (page 123) POPUP WINDOWS AND MENUS ----------------------- od_draw_box() Draws a box on the screen in ANSI/AVATAR/RIP graphics mode. (page 65) od_window_create() Displays a popup window, storing the screen contents "under" the window. Requires ANSI/AVATAR/RIP graphics mode. (page 145) od_window_remove() Removes a popup window displayed with od_window_create(), restoring the original screen contents "under" the window. Requires ANSI/AVATAR/RIP graphics mode. (page 147) od_popup_menu() Displays a menu in a popup window, allowing the user to choose menu items either by pressing a "hot" key, or moving a highlighted selection bar. After menu selection, the menu may be removed, restoring the original screen contents "under" the window. Requires ANSI/AVATAR/RIP graphics mode. (page 105) =============================================================================== OpenDoors 6.00 Manual End of Page 43 FILE DISPLAY FUNCTIONS ---------------------- od_send_file() Displays an ASCII/ANSI/AVATAR/RIP file (for instance, an .ANS file created by a program such as "TheDraw" (page 124) od_hotkey_menu() Displays an ASCII/ANSI/AVATAR/RIP menu file, with hotkeys active. (page 90) od_list_files() Lists the files available for download in an area, using a FILES.BBS file. (page 98) ------------------------------------------------------------------------------- INPUT od_get_answer() Inputs a single key from the keyboard, FUNCTIONS allowing only particular responses. (page 81) od_get_input() A more flexible version of od_get_key(), that also supports extended keys such as arrow keys, insert, etc. (page 82) od_get_key() Inputs a single key from the keyboard, optionally waiting if a key is not available. (page 82) od_input_str() Inputs a string of specified length, from the keyboard. (page 95) od_edit_str() Formatted string editing function, requiring ANSI/AVATAR/RIP graphics. (page 68) od_multiline_edit() Provides a text editor that allows the user to enter or edit text that spans multiple lines, such as email messages or text files. (page 101) od_clear_keybuffer() Removes any waiting keys from the keyboard input queue. (page 53) ------------------------------------------------------------------------------- COMMON od_page() Allows the user to page the sysop. DOOR (page 101) ACTIVITY FUNCTIONS od_spawn() OpenDoors "quick" spawn function. Executes an external program (eg. file compressor, external protocol, etc.) on =============================================================================== OpenDoors 6.00 Manual End of Page 44 a separate screen, restoring the OpenDoors screen afterwards. (page 139) od_spawnvpe() OpenDoors full-featured spawn function. Executes an external program on a separate screen, searching the path for the program, allowing you to specify an environment to pass to the child process, and returning the errorlevel returned by the child process. (page 143) od_log_write() Adds an entry to the end of the log file. (page 100) od_parse_cmd_line() Handle standard command line options. (page 105) ------------------------------------------------------------------------------- SPECIAL od_init() Begins door operation by setting up CONTROL the OpenDoors control structure, FUNCTIONS setting up the local screen, initializing the serial port (if applicable), and reading the door information file. (page 92) od_color_config() Transfers a color configuration line to a color attribute value. (page 59) od_add_personality() Adds a custom status line/control key personality to OpenDoors. (page 47) od_set_statusline() Temporarily alters the setting of the current OpenDoors status line. (page 137) od_autodetect() Automatically determines the remote terminal software's graphical capabilities. (page 48) od_kernel() The central OpenDoors control function, which should be executed every few seconds. (page 97) od_exit() Ends door operations, closing the serial port driver, re-writing the door information file, and optionally returning control to the BBS. (page 79) =============================================================================== OpenDoors 6.00 Manual End of Page 45 od_carrier() Allows detection of carrier signal in programs that have disabled OpenDoors internal checking. (page 51) od_set_dtr() Controls the DTR signal to the modem. Can be used to manually disconnect a remote user, in order to perform activities such as call back verification. (page 135) od_chat() Forces OpenDoors to enter chat mode, even if sysop did not press the "chat" key. (page 50) od_sleep() Suspends program execution, yielding control to other tasks in a multitasking environment. (page 139) =============================================================================== OpenDoors 6.00 Manual End of Page 46 OD_ADD_PERSONALITY() ------------------------------------------------------------------------------- PURPOSE Installs a custom status line / sysop function key personality into OpenDoors. FORMAT BOOL od_add_personality(char *pszName, BYTE btOutputTop, BYTE btOutputBottom, OD_PERSONALITY_PROC *pfPerFunc); RETURNS TRUE on success FALSE on failure DESCRIPTION If used, this function should be called before any other OpenDoors API functions. This function installs a new personality into OpenDoors. The first parameter specifies the string that will be used to identify the personality. This is the string that the user will be able to supply in the configuration file to select this personality, and is also the string that can be passed to od_set_personality() to manually switch to this personality. The second and third parameters specify the 1-based to and bottom line numbers of the output window to be used with this personality. For instance, a top value of 1 and bottom value of 23 would cause all door output to be displayed on the first 23 lines of the screen, leaving the bottom two lines for use by the personality's status line. The last parameter is a pointer to the personality function, which OpenDoors will call to perform various operations with that involve the personality. For more information on personalities and the OpenDoors Multiple Personality System, see the section which begins on page 233. This function only has an effect under the DOS version of OpenDoors. SEE ALSO od_set_personality(), od_set_statusline() =============================================================================== OpenDoors 6.00 Manual End of Page 47 OD_AUTODETECT() ------------------------------------------------------------------------------- PURPOSE Attempts to automatically determine the terminal capabilities of the remote system. FORMAT void od_autodetect(int nFlags); RETURNS N/A DESCRIPTION This function can be used to determine whether or not the remote terminal supports ANSI and/or RIP (Remote Imaging Protocol) graphics modes. This information is usually supplied to the door by the BBS software, through the door information file. For this reason, most door programs do not need to make used of this function. However, if your door will be running under any BBS software that does not report the ANSI or RIP capabilities of the remote system, you may wish to use this function. od_autodetect() will set either of the following OpenDoors control structure variables to TRUE if the corresponding graphics mode is detected: od_control.user_ansi - TRUE if ANSI mode is available od_control.user_rip - TRUE if RIP mode is available However, if either of these variables have previously been set to TRUE (either explicitly by your program, or due to the corresponding modes being enabled in the door information file), and od_autodetect() does not detect the corresponding graphics mode, they will not be set to FALSE. Not all terminal software that supports ANSI or RIP graphics mode will necessarily have the ability to report their graphics mode capabilities to the door. For this reason, failure to detect either of these modes does not necessarily indicate that they are not available. However, if these modes are detected by od_autodetect(), it is safe to assume that the remote system does support the detected mode. The nFlags parameter is reserved for future use, and should always be set to DETECT_NORMAL. This function cannot auto-detect AVATAR mode, because there is no standard means of determining whether a remote system supports AVATAR mode. EXAMPLE Below is an example of using od_autodetect() in determining the remote terminal's graphics capabilities. Since not all terminal software supports auto-detection, this example will also prompt =============================================================================== OpenDoors 6.00 Manual End of Page 48 the user to determine their software's capabilities if od_autodetect() fails to detect ANSI mode. This code assumes that if the terminal software supports the autodetection of ANSI mode, that it will also support the autodetection of RIP mode. OpenDoors assumes that ANSI mode is always available in conjunction with RIP mode. /* Call the automatic terminal detection function */ od_autodetect(); /* If ANSI mode was not detected, ask the user about if(!od_control.user_ansi) { /* Prompt the user for ANSI capabilities */ od_clr_scr(); od_printf("Does your system support ANSI graphics?"); od_printf(" (Y/N)"); /* If the user chooses [Y]es */ if(od_get_answer("YN") == 'Y') { /* Turn on ANSI mode */ od_control.user_ansi = TRUE; /* Since ANSI mode is present, RIP mode may also */ /* be available. Prompt the user for RIP. */ od_printf("\r\n\n"); od_printf("Does your system support RIP graphics?"); od_printf(" (Y/N)"); /* If the user chooses [Y]es */ if(od_get_answer("YN") == 'Y') /* Turn on RIP mode */ od_control.user_rip = TRUE; /* Since ANSI mode is present, AVATAR mode may */ /* also be available. Prompt the user for AVATAR. */ od_printf("\r\n\n"); od_printf("Does your system support AVATAR "); od_printf("graphics? (Y/N)"); /* If the user chooses [Y]es */ if(od_get_answer("YN") == 'Y') /* Turn on AVATAR mode */ od_control.user_avatar = TRUE; } od_printf("\r\n\n"); } =============================================================================== OpenDoors 6.00 Manual End of Page 49 OD_CHAT() ------------------------------------------------------------------------------- PURPOSE Manually invokes sysop chat mode. FORMAT void od_chat(void); RETURNS N/A DESCRIPTION Normally, the OpenDoors sysop chat mode will only be invoked when the sysop explicitly requests it using the sysop chat key. However, there may be some cases where you wish to manually invoke the sysop chat mode. One example is when you are replacing the OpenDoors built-in chat mode with your own, but still wish to use the OpenDoors chat mode under some circumstances. For instance, you may wish to use your own split- screen chat routine if ANSI, AVATAR or RIP graphics mode is available, and use the OpenDoors line-oriented chat mode if only ASCII mode is available. SEE ALSO od_page() EXAMPLE For an example of using the od_chat() function, see the ex_chat.c example door, which is described on page 38. =============================================================================== OpenDoors 6.00 Manual End of Page 50 OD_CARRIER() ------------------------------------------------------------------------------- PURPOSE To determine the status of the carrier detect signal, in programs where OpenDoors' internal carrier detection has been disabled. FORMAT BOOL od_carrier(void); RETURNS TRUE if a carrier is present, or FALSE if no carrier is present, or in local mode. DESCRIPTION Usually, you will not have any use for the od_carrier() function, as OpenDoors automatically monitor's the carrier detect signal, and will correctly recover if the carrier detect signal is lost while the door is operating in remote mode. However, in some programs, you may wish to disable OpenDoors' internal carrier detection routines, using the od_control.od_disable variable. Two such cases in which you might want to do this, are a call-back verification door, which disconnects the user and attempts to call them back, or in a terminal program, which is in fact not a door at all (and as such you would not want to have OpenDoors exit when the carrier detect signal is lost). In cases like these, you will then be able to use the od_carrier() function in order to determine the state of the carrier detect signal. This function will return a Boolean value (for more information on Boolean values, see the Glossary which begins on page 256), of either TRUE or FALSE. If a carrier detect signal is present when the function is called, it will return TRUE, and if no carrier detect signal is detected, it will return FALSE. Since there is no remote connection, and thus no carrier when OpenDoors is operating in local mode, this function will always return a value of FALSE in local mode. SEE ALSO od_set_dtr() EXAMPLE As an example of the use of this function, let us consider a call back verification door, which hangs up on the user, and then calls the user back at their entered phone number, in order to verify the correctness of that number. This program would probably contain a function that is responsible for disconnecting the user, waiting for the connection to be broken, and then phoning the user. At some point in this function, likely just prior to the point where the function hangs up on =============================================================================== OpenDoors 6.00 Manual End of Page 51 the user, you would disable OpenDoors' internal carrier detection, using the line: od_control.od_disable |= DIS_CARRIERDETECT; You would then want to have a piece of code which would simply wait up to a given amount of time for the carrier signal to drop. If this occurs, you would continue to place the call, and if it does not occur, you would probably try your hangup procedure one or two more times. In this example, the function will return with a value of FALSE if the carrier signal does not drop, and will return a value of TRUE if it does. char hangup(void) { clock_t timer; char to_return = FALSE; od_set_dtr(FALSE); /* Hangup modem */ /* Wait up to 30secs */ timer = clock() + CLOCKS_PER_SEC * 30; while(timer >= clock()) { /* If carrier has been lost, return with success */ if(!od_carrier()) { to_return = TRUE; break; } } od_set_dtr(TRUE); /* Re-enable DTR signal */ return(to_return); } =============================================================================== OpenDoors 6.00 Manual End of Page 52 OD_CLEAR_KEYBUFFER() ------------------------------------------------------------------------------- PURPOSE Function to clear the input keyboard buffer FORMAT void od_clear_keybuffer(void); RETURNS N/A DESCRIPTION OpenDoors maintains its own keyboard input buffer, in order to permit the user to "type ahead" - to send input to the door prior to the time when it is ready to process those key presses. For example, the user could begin to type a command while a menu is still being displayed, and when your door reaches the point of inputting the menu command, the characters already typed by the user will already be waiting for the OpenDoors input functions. Note that the keyboard input buffer will include both the keys hit by the user on-line, and the non-function keys (ie, Alt-C will not appear in the OpenDoors keyboard buffer), hit by the sysop. This allows both the user on-line and the sysop to control the door at any time. If the sysop wishes to temporarily prevent the user from having any control over the door, the sysop may use the Alt-K (user-keyboard off) key. The key strokes placed in the OpenDoors type-ahead buffer will be retrieved by the od_get_key() and od_input_str() functions. The keyboard buffer can contain a maximum of 64 user keystrokes in this version of OpenDoors, after which any additional keystrokes will simply be discarded by OpenDoors. There are times, however, when you will want to erase any keys that have been hit by the user, to prevent them from typing ahead. For example, if your door has been busy doing some processing for a few moments, they user may have been pressing keys on their keyboard - perhaps in the hope that doing so will speed things up. These keys will be waiting in the type-ahead buffer, and if one of the keys the user entered was a valid response to the next prompt in your door, the user may find that they have accidentally made a choice they did not wish to. A well designed door will simply erase the contents of the type- ahead buffer after any long period of internal processing, etc. Keep in mind that too much use of the od_clear_keybuffer() function can be just as undesirable as not using it all, as there are times when the presence of the keyboard buffer can prove to be very useful for the user of a door. To erase the contents of the type-ahead buffer, you simply call the od_clear_keybuffer() function. This function takes no parameters, and does not return any value. =============================================================================== OpenDoors 6.00 Manual End of Page 53 SEE ALSO od_get_key(), od_input_str(), od_edit_str() EXAMPLE For one example of the use of the od_clear_keybuffer() function, see the example program EX_VOTE.C, which is described beginning on page 38. Below is another example of using this function. In this case, we present a simple function, wait_for_return(), which simply pauses for the user to press their [Enter]/[Return] key. The function begins by displaying a prompt asking for the [Enter] or [Return] key to be pressed. The function then clears the keyboard input buffer, and waits until the user presses the carriage return key, using the od_get_key() function. Note also that this function will only continue if the user has pressed the correct key. This is a good idea in all door programs, as it allows your door to distinguish between a character pressed by the user, and a "line noise" character. void wait_for_return(void) { /* Display prompt */ od_disp_str("Please Press [Enter] to continue...\n\r"); od_clear_keybuffer(); /* Clear keyboard buffer */ while(od_get_key(TRUE) != 13); /* Wait for Enter key */ } =============================================================================== OpenDoors 6.00 Manual End of Page 54 OD_CLR_LINE() ------------------------------------------------------------------------------- PURPOSE Clears the rest of the current display line FORMAT void od_clr_line(void); RETURNS N/A DESCRIPTION This function clears the line that the cursor is on, from the cursor position to the end of the line. After the rest of the line is cleared, the cursor is automatically returned to the position it was at prior to issuing the command. Hence, if the display line the cursor was located on looked as follows, with the underscore (_) character representing the cursor position: This is a_line of text! With the cursor between the words "a" and "line", after the od_clr_line command is issued, the line would appear as follows: This is a_ With the cursor directly following the word "a". Note that this function places a space character at the cursor location, and every location up to the end of the line. When the door is running in plain ASCII mode, this command will simply clear the rest of the line by manually sending a series of space and backspace characters. When ANSI, AVATAR or RIP modes are active, the corresponding ANSI/AVATAR control sequence will be sent in order to accomplish the line clear. Since the graphics mode sequences are much shorter than the sequence that would be required to clear the line manually, the use of this function will cause your door's graphics to display much more quickly when ANSI, AVATAR or RIP modes are active. Also note that in ANSI, AVATAR or RIP graphics modes, the line will be cleared with the currently selected color attribute. Thus, if you wanted to place a blue background on a particular line, you would use the od_set_color() (or od_set_attrib()) function, then use the od_set_cursor() function to locate the cursor at the beginning of the desired line, followed by the od_clr_line() function. Just such a procedure is demonstrated in the example, below. SEE ALSO od_clr_scr(), od_set_cursor() =============================================================================== OpenDoors 6.00 Manual End of Page 55 EXAMPLE Below, is an example of a function that clears an entire line with a specified color. Since this function performs operations that require ANSI, AVATAR or RIP graphics mode, it should only be used in a case where these modes are known to be available. For example, this function would be useful in a full-screen editor or viewer, or when performing ANSI animations. The function accepts three parameters: the line to be cleared (where 1 is the first line, 2 the second, and so on), the foreground color of this line, and the background color of this line. This function differs from the od_clr_line() function itself in several important manners. First of all, this function clears the entire line, whereas the od_clr_line() function can be used to clear only the remaining characters of the line, after any particular location. Also, as mentioned before, this function selects a color to clear the line to, and moves the cursor to the line which is to be cleared - neither of which is done by the od_clr_line() function. void clear_line(char line_number,char foreground,char background) { od_set_cursor(line_number,1); /* move to correct line */ od_set_color(foreground,background); /* set color */ od_clr_line(); /* clear entire line */ } =============================================================================== OpenDoors 6.00 Manual End of Page 56 OD_CLR_SCR() ------------------------------------------------------------------------------ PURPOSE The OpenDoors clear screen function FORMAT void od_clr_scr(void); RETURNS N/A DESCRIPTION The od_clr_scr() function can be used to clear the output screen. (ie, the user's screen and local screen with the exception of the status line are cleared.) This function will only clear the screen if screen clearing is enabled. If your program will be running under BBS systems that do not pass the user's screen clearing setting to the door, you may wish to determine yourself whether or not the user's system supports screen clearing codes, during the first time the user uses the door. You will then be able to store this setting in a data file. The example below demonstrates how to detect whether or not the user's system supports screen clearing. You should note that the ability for the user's terminal to support screen clearing codes is independent of the user's ANSI / AVATAR / RIP graphics mode settings. For more information on the user's screen clearing setting, please refer to the user_attrib variable in the OpenDoors Control Structure chapter of this manual. If you wish to force a screen clear, regardless of the user's screen clearing setting, simply use the function call: od_disp_emu("\xc", TRUE); SEE ALSO od_clr_line() EXAMPLE Below is an example of a function which determines whether or not the user's system supports screen clearing. This function will return a value of TRUE if screen clearing is supported, and will return a value of FALSE if screen clearing is not supported: int user_supports_screen_clearing(void) { char answer; /* display instructions to user */ od_disp_str("In order for this door to function\n\r"); od_disp_str("correctly, we must know whether or not\n\r"); =============================================================================== OpenDoors 6.00 Manual End of Page 57 od_disp_str("your system supports screen clearing.\n\r"); od_disp_str("In a moment, we will attempt to clear\n\r"); od_disp_str( "your screen in order to test your system's\n\r"); od_disp_str("capabilities.\n\r\n\r"); od_disp_str("Please press [Enter]/[Return] when you\n\r"); od_disp_str("are ready to perform this test.\n\r"); while(od_get_key(TRUE)!=13); /* wait for [Return] key */ od_clr_scr(); /* attempt to clear screen */ /* ask user if their screen cleared */ od_disp_str("Did your screen just clear? (Y/N)\n\r"); for(;;) /* loop until user chooses [Y]es or [N]o */ { answer=od_get_key(TRUE); /* Get user's answer */ if(answer=='y' || answer=='Y') return(TRUE); if(answer=='n' || answer=='N') return(FALSE); } } =============================================================================== OpenDoors 6.00 Manual End of Page 58 OD_COLOR_CONFIG() ------------------------------------------------------------------------------- PURPOSE Parses a color configuration line from the configuration file, generating a color attribute value. FORMAT BYTE od_color_config(char *pszColorDesc); RETURNS Color attribute value DESCRIPTION This function will be of use if you are using the configuration file system of OpenDoors, and wish to allow the sysop to specify text colors to be used in your door. While OpenDoors automatically recognizes color configuration settings for things such as sysop chat mode and FILES.BBS listings, you may wish to add additional color configuration options. In this case, you could call the od_color_config() function from your custom line function. For more information on the custom line function, see the section on the OpenDoors configuration file system, which begins on page 224. To use this function, simply pass the configuration file line you wish to have parsed to the function in it's single parameter. The function will then return a color attribute value in the same format that is used but the od_set_attrib() function. Colors are specified using a string of the format: {Flashing} {Bright} [foreground] on [background] Where "Flashing" is an optional keyword indicating that the text should be flashing. "Bright" is an optional keyword indicating that the foreground color should be bright. Foreground is the name of a foreground color, and background is the name of a background color. Case (upper or lower) is not significant. The color keywords are language configurable, using the array od_control.od_color_names. EXAMPLE See the example accompanying in the section on the OpenDoors configuration file system, which begins on page 224. =============================================================================== OpenDoors 6.00 Manual End of Page 59 OD_DISP() ------------------------------------------------------------------------------ PURPOSE Sends a buffer of text with optional local echo FORMAT void od_disp(char *pachBuffer, INT nSize, BOOL bLocalEcho); RETURNS N/A DESCRIPTION This function allows you to send a buffer of text of any specified length, with the option of enabling or disabling local echo. You will probably have little use for this function - instead you will most likely display strings using either the od_disp_str() or od_printf() functions, depending on whether or not you wish to use printf()'s formatting options. For a breakdown of the uses of the various OpenDoors display functions, see the description of the od_disp_str() function, on page 63. There are two cases when this function will come in useful: 1.)If you wish to display a buffer of characters of known length, which may contain null (ASCII 0) characters. Since this character is used by the C language to indicate the end of a string, the other two string display functions (od_disp_str() and od_printf()) will not send this character to the remote system. 2.)If you wish to send text to the remote system without having it displayed on the local screen, or if you wish to send strings to the modem when it is in command mode, without having these characters displayed on the local screen. The od_disp() function is called with three parameters. The first parameter, pachBuffer, is a pointer to a buffer of characters you wish to have displayed. The second parameter, nSize, is simply the number of characters in the buffer to be displayed. If the third parameter, bLocalEcho, is set to TRUE, then all characters sent to the modem will also be displayed on the local screen. If the third parameter is set to FALSE, then the buffer will be sent to the modem without being echoed to the sysop's screen. SEE ALSO od_disp_str(), od_printf(), od_putch(), od_repeat(), od_disp_emu() =============================================================================== OpenDoors 6.00 Manual End of Page 60 EXAMPLES The following are a few examples of the use of the od_disp() function: In order to display a single character, contained in the variable "character", without echo to the local screen: od_disp(&character,1,FALSE); In order to send a command to the modem (only if you know that the modem is in command mode), with the command contained in the null-terminated string "string": od_disp(string,strlen(string),FALSE); In order to send exactly 5 characters from the buffer "buffer", WITH echo to the local screen: od_disp(buffer,5,TRUE); =============================================================================== OpenDoors 6.00 Manual End of Page 61 OD_DISP_EMU() ------------------------------------------------------------------------------- PURPOSE Displays a string with ANSI/AVATAR terminal emulation FORMAT void od_disp_emu(char *pszToDisplay, BOOL bRemoteEcho); RETURNS N/A DESCRIPTION The od_disp_emu() function allows you to display your own ANSI / AVATAR graphics sequences. This function passes the characters you wish to display to the OpenDoors terminal emulator, which is fully documented in the description of the od_send_file() function, on page 124. This function can be used to send these control sequences to the user's terminal, and also have them displayed on the local screen as they will appear to the user. The string passed to od_disp_emu() contains any stream of text to display, and may include both normal text and terminal emulation control sequences. If the bRemoteEcho parameter is set to TRUE, the string passed to od_disp_emu() will be sent to the remote terminal in addition to being displayed locally. If this parameter is set to FALSE, the string will only be displayed locally. Note that if you wish to display an entire file containing ANSI/AVATAR/RIP graphics sequences (perhaps as your program's menu or title screen), you can use the od_send_file() function. SEE ALSO od_send_file(), od_disp(), od_disp_str() od_printf(). For a breakdown of the uses of the various OpenDoors display functions, see the od_disp_str() function, on page 63. EXAMPLE For an example of the use of the od_disp_emu() function, see the SpaceRight() and MoveLeft() functions included in the example program ex_ski.c. =============================================================================== OpenDoors 6.00 Manual End of Page 62 OD_DISP_STR() ------------------------------------------------------------------------------- PURPOSE Displays a string to the screen (remote and local) FORMAT od_disp_str(char *pszToDisplay); RETURNS N/A DESCRIPTION The two functions most often used for displaying strings within a door are the od_disp_str() and od_printf() functions. The od_printf() function allows for formatted output, whereas the od_disp_str function simply displays the actual contents of the string passed to it. If you wish to display a single character, use the od_putch() function. If you wish to send a string or buffer to the modem without local echo, use the od_disp() function. If you wish to send a sequence of the same character to the modem, the od_repeat() function will use graphics control codes, if available to display the sequence much faster than simply sending the same character in repetition. Also, if you wish to send ANSI, AVATAR or RIP graphics control codes, and have them emulated on the local screen, use the od_disp_emu() function. The od_disp_str() function displays the contents of the null- terminated string pointed to by *string. Display is sent to both the local screen and modem (presuming the door is not running in local mode). An important thing to keep in mind when using the od_disp_str() function, is that you should use "/n/r" instead of simply "/n" for a new line. This is due to the fact that terminal programs usually require a carriage-return line-feed sequence (/n/r), instead of just a line-feed (/n). For example, instead of using: od_disp_str("Hello world!\n"); You should use: od_disp_str("Hello world!\n\r"); To change the cursor color or location of output with the od_disp_str() function, refer to the od_set_cursor() and the od_set_attrib() functions. SEE ALSO od_disp(), od_printf(), od_putch(), od_repeat(), od_disp_emu() =============================================================================== OpenDoors 6.00 Manual End of Page 63 EXAMPLES Below are a few examples of various uses of the od_disp_str() function: Displaying three string constants on separate lines: od_disp_str("This is an example\n\r"); od_disp_str("of the OpenDoors\n\r"); od_disp_str("od_disp_str() function\n\r"); Displaying three string constants on the same line: od_disp_str("Another "); od_disp_str("od_disp_str() "); od_disp_str("example\n\r"); Displaying a string variable: char string[80]; strcpy(string,"This is a string!\n\r"); od_disp_str(string); =============================================================================== OpenDoors 6.00 Manual End of Page 64 OD_DRAW_BOX() ------------------------------------------------------------------------------- PURPOSE Draws a box on the screen in ANSI, AVATAR or RIP graphics modes. FORMAT BOOL od_draw_box(BYTE btLeft, BYTE btTop, BYTE btRight, BYTE btBottom); RETURNS TRUE on success, FALSE on failure DESCRIPTION This function is for use in ANSI, AVATAR or RIP graphics modes. This function will draw a box in the current display attribute, at the specified location on the screen. The boarder of the box is made up of the characters specified in the od_control. od_box_chars[] array. If AVATAR graphics mode is available, this function uses AVATAR control codes to display the box in less than 1/10 the length of time required to display the box in ANSI mode. The first two parameters of this function, btLeft and btTop, specify the coordinates of the top, left-hand corner of the box to be draw. The third and fourth parameters, btRight and btBottom, specify the coordinates of the bottom, left-hand corner of the box. Like the values passed to the od_set_cursor() function, these coordinates are relative to the upper left-hand corner of the screen, with the position (1,1) being this corner. As mentioned above, this function will display the window in the current text color. Thus, before calling this function, you should use either the od_set_color() or the od_set_attrib() function to specify the color in which you would like to have the window displayed. Normally, the boarder of the window will be displayed using the IBM extended ASCII characters which produce a single line boarder. However, you may wish to have the boarder displayed using different characters. In this case, the characters used to display the boarder can be specified by the od_control. od_box_chars variable, described in the OpenDoors control structure section of this manual. SEE ALSO od_set_color(), od_set_attrib(), od_clr_scr(), od_edit_str(), od_set_cursor() EXAMPLE As an example of the use of the od_draw_box() function in conjunction with the od_edit_str() function, we show a portion of a program which displays a window, and allows the user to input the name of a file they would like to upload, a =============================================================================== OpenDoors 6.00 Manual End of Page 65 description of the file, and whether they want it to be a private upload. The user is able to move among fields using the tab key, and select a "continue" button when they are finished. The function returns TRUE if the user selects continue, and FALSE if the user presses [ESCape]. // Main "dialog box" function int get_information(char *filename, char *description, char *private) { char current_field=1; // Currently selected field int choice; // User's choice od_set_color(L_WHITE,D_BLUE); // Display window od_draw_box(10,5,70,13); od_set_cursor(5,25); // Display window title od_set_color(L_GREEN,D_BLUE); od_disp_str(" ENTER FILENAME INFORMATION "); od_set_color(L_CYAN,D_BLUE); // Display fields and titles od_set_cursor(6,15); od_disp_str("FILENAME : "); od_repeat(176,13); od_set_cursor(7,12); od_disp_str("DESCRIPTION : "); od_repeat(176,43); od_set_cursor(8,16); od_disp_str("PRIVATE : "); od_repeat(176,2); draw_button(); filename[0]='\0'; // Blank out contents of input variables description[0]='\0'; private[0]='\0'; for(;;) // Main dialog box loop { if(current_field==4) // If field is the button { od_set_color(L_GREEN,D_BLUE); // Highlight button draw_button(); do // Loop until user presses [TAB], [ENTER], or [ESC] { choice=od_get_key(TRUE); } while(choice!=9 && choice!=13 && choice!=27); od_set_color(L_CYAN,D_BLUE); // Un-highlight button draw_button(); if(choice==13) return(TRUE); // If [ENTER] was pressed =============================================================================== OpenDoors 6.00 Manual End of Page 66 if(choice==27) return(FALSE); // If [ESC] was pressed current_field=1; // Otherwise, [TAB] was pressed } switch(current_field) // According to selected field { // Input from the appropriate line case 1: choice=od_edit_str(filename,"FFFFFFFFFFFF",6,26, 0x1b,0x1a,176, EDIT_FLAG_EDIT_STRING| EDIT_FLAG_ALLOW_CANCEL| EDIT_FLAG_FIELD_MODE| EDIT_FLAG_KEEP_BLANK); break; case 2: choice=od_edit_str(description, "*******************", 7,26,0x1b,0x1a,176, EDIT_FLAG_EDIT_STRING| EDIT_FLAG_ALLOW_CANCEL| EDIT_FLAG_FIELD_MODE| EDIT_FLAG_KEEP_BLANK); break; case 3: choice=od_edit_str(private,"Y",8,26, 0x1b,0x1a,176, EDIT_FLAG_EDIT_STRING| EDIT_FLAG_ALLOW_CANCEL| EDIT_FLAG_FIELD_MODE); } // If user pressed [ESCape] if(choice==EDIT_RETURN_CANCEL) return(FALSE); // If user choice to go to previous field if(choice==EDIT_RETURN_PREVIOUS) { if(current_field==1) // If at first field current_field=4; // Go to last field else // If not at first field --current_field; // Go to previous field } else // If user chose next field ++current_field; // Go to next field } } void draw_button(void) // Function to display the button { od_draw_box(12,10,23,12); // Draw box for button od_set_cursor(11,14); od_disp_str("Continue"); // Display text in button } =============================================================================== OpenDoors 6.00 Manual End of Page 67 OD_EDIT_STR() ------------------------------------------------------------------------------- PURPOSE Allows you to perform formatted input with full line editing features, etc., in ANSI/AVATAR/RIP graphics mode. FORMAT WORD od_edit_str(char *pszInput, char *pszFormat, INT nRow, INT nColumn, BYTE btNormalColor, BYTE btHighlightColor, char chBlank, WORD nFlags); RETURNS This function will return one of the following values: EDIT_RETURN_ERROR Indicates that an error has occurred, and the edit function was unable to run. This will occur if there is an error in one of the parameters, or if ANSI/AVATAR/RIP graphics is not available EDIT_RETURN_CANCEL Indicates that the user pressed the cancel key [ESC], and that the string was left unaltered. EDIT_RETURN_ACCEPT Indicates that the user pressed the accept key [Enter], or that the auto- enter feature was activated. EDIT_RETURN_PREVIOUS Indicates that the user wishes to move to the previous field, by pressing [UP ARROW], [SHIFT]-[TAB], etc. EDIT_RETURN_NEXT Indicates that the user wishes to move to the next field, by pressing [DOWN ARROW], [TAB], etc. DESCRIPTION To perform string input within OpenDoors, one of two functions can be used, od_input_str() and od_edit_str(). The first function, od_input_str(), allows simple line input and editing, and can be used in ASCII, ANSI, AVATAR and RIP modes. The second function, od_edit_str(), allows many formatted input options, advanced line editing, and other features, but requires the use of ANSI, AVATAR or RIP terminal modes. As mentioned above, the od_edit_str() function allows for advanced line editing, such as inputting and deleting text from the middle of the string (whereas the od_input_str() function only allows editing from the end of the string, such as backspacing to erase a mistake). The edit functions available from the od_edit_str() are listed below. Note that some of these =============================================================================== OpenDoors 6.00 Manual End of Page 68 functions may or may not be available, depending upon the capabilities of the user's terminal program. While there is no single standard used for the transmission of special edit keys such as the arrow keys, the od_edit_str() function makes as much effort as possible to make all of the edit features available to most terminal programs. Many of the edit functions can be accesses using either [CONTROL]-key combinations or special keys such as the arrow keys, delete key, and so on. OpenDoors will recognize most of these special control keys when sent as either an ANSI control sequence (which is sent by most terminal programs), or as a DoorWay style scan code / ASCII code sequence (which is also available from many terminal programs, but is not usually required). The od_edit_str() edit functions are as follows. Note that all edit functions are always available from the local keyboard. HOME - Moves the cursor to the beginning of the line being edited. Press the [HOME] key, either in DoorWay mode or from the local keyboard. END - Moves the cursor to the end of the line being edited. Press the [END] key, either in DoorWay mode or from the local keyboard. DELETE CHARACTER - Deletes the character under the cursor. Press [DELete] on the local keyboard, in DoorWay mode, and under many terminal programs without DoorWay mode. Alternatively, press [CONTROL]-[G]. BACKSPACE - Deletes the character left of the cursor. Press [BACKSPACE] or [CONTROL]-[H]. TOGGLE INSERT MODE - Switches the od_edit_str() function between insert mode and overwrite mode. Press [INSert], either in DoorWay mode, or from the local keyboard. Alternatively, press [CONTROL]-[V]. CURSOR LEFT - Moves the cursor left one character. Press [LEFT ARROW] on the local keyboard, in DoorWay mode, and under many terminal programs without DoorWay mode. Alternatively, press [CONTROL]-[S]. CURSOR RIGHT - Moves the cursor right one character. Press [RIGHT ARROW] on the local keyboard, in DoorWay mode, and under many terminal programs without DoorWay mode. Alternatively, press [CONTROL]-[D]. ERASE ENTIRE LINE - Press [CONTROL]-[Y]. ACCEPT INPUT - Press the [ENTER] / [RETURN] line to accept the input. Alternatively, press [CONTROL]-[Z]. Note that this key will only work when the current input is =============================================================================== OpenDoors 6.00 Manual End of Page 69 "valid" (ie, it conforms to the format string, which is described below) CANCEL INPUT - Only available if specifically enabled on the od_edit_str() command line. Press [ESCape]. NEXT FIELD - If enabled, allows the user to move to the next field in a dialog box / form. Press [DOWN ARROW] in DoorWay mode and under many terminal programs without DoorWay mode. Alternatively, press [TAB]. Note that the [DOWN ARROW] key is NOT usually available from the local keyboard, as it is usually used to adjust the user's remaining time. PREVIOUS FIELD - If enabled, allows the user to move to the previous field in a dialog box / form. Press [UP ARROW] in DoorWay mode and under many terminal programs without DoorWay mode. Alternatively, press [SHIFT]-[TAB] on the local keyboard or in DoorWay mode. Again, note that the [UP ARROW] key is NOT usually available from the local keyboard, as it is usually used to adjust the user's remaining time. Let us now look at the parameters which the od_edit_str() function accepts. The first parameter, pszInput, is a pointer to the string where the user's input should be stored. It is important that this string be long enough to accommodate the longest input your format string will permit, including the '\0' C string terminator (ie, the string should be one character greater than the length of the format string, not including the format string's ' and " characters). The second parameter, pszFormat, is a pointer to a string which specifies the format and maximum length of the input the od_edit_str() function should accept. Using the format string, not only do you specify the length of the input field, but you can also force the user's input into certain formats. For example, if you wished to input a North American style phone number, you could use a format string of "###-###-####". Then regardless of whether the user typed any dash character or not, their input would be converted, as they type, to the format of the phone number 613-599-5554. You could also specify a format string such of "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM", which would permit the user to enter a name of up to 30 characters. Note that since the cursor can be moved to the position immediately following the last character, a the input field for a 30 character string will occupy 31 columns on the screen. The od_edit_str() function would then automatically capitalize the name, so that the first character of each word is capitalized, and the remain characters of the word is in lower case. Even if the user were to move the cursor to the middle of the string =============================================================================== OpenDoors 6.00 Manual End of Page 70 they had entered, and add or delete a space (and thus either make one work two or two words one), od_edit_str() would re- format the string to reflect the change. The valid characters for the format sting, along with their meanings, are listed below. Note that the format string is NOT case sensitive (except for literal strings delimited by the '' or "" characters), and space characters can be added at any point to increase legibility. # Indicates that numeric characters from '0' to '9' are valid for this position % Indicates that numeric characters from '0' to '9', and the space character (' ') are valid for this position. 9 Indicates that numeric characters from '0' to '9', along with '.', '-' and '+' are valid for this position. This format style is intended for floating-point numeric input. ? Indicates that any character is valid for this position. * Indicates that any printable character, from ASCII 32 to ASCII 127, is valid for this position. A Indicates that alphabetical characters 'A' to 'Z', 'a' to 'z' and space (' ') are valid for this position. C Indicates that city name characters are valid for this position. As with the 'M' format character, words are automatically capitalized so that the first letter is in upper case, and all subsequent letters are in lower case. In addition to permitting alphabetical characters and the space (' ') character, the ',' and '.' characters are also accepted in this position. D Indicates that date characters '0' to '9', '-' and '/' are valid for this position. F Indicates that MS-DOS filename characters are valid for this position. H Indicates that hexidecimal character '0' to '9', 'A' to 'F' and 'a' to 'f' are valid for this position. L Indicates that only lower case alphabetical characters 'a' to 'z', and the space (' ') character is valid for this position. However, if the user attempts to enter an upper case alphabetical character in this position, it will automatically be converted to the lower case equivalent. M Indicates that name characters are valid for this position. These characters are the alphabetical characters 'A' to =============================================================================== OpenDoors 6.00 Manual End of Page 71 'Z', 'a' to 'z', and the space character (' '). A character's case is converted such that the first character of a word is in upper case, and all other letters are in lower case. T Indicates that telephone number character '0' to '9', '(', ')', '-' and ' ' are valid for this position. U Indicates that only upper case alphabetical characters 'A' to 'Z', and the space (' ') character is valid for this position. However, if the user attempts to enter a lower case alphabetical character in this position, it will automatically be converted to the upper case equivalent. W Indicates that MS-DOS filename characters are permitted in this position, including the '*' and '?' wildcard characters. X Indicates that alphanumeric characters 'A' to 'Z', 'a' to 'z', '0' to '9' and ' ' are valid for this position. Y Indicates that yes/no characters 'Y', 'N', 'y', 'n' are valid for this position. The characters are automatically converted to upper case. '/" Single or double quotes can be used to specify sequences of characters that should appear at the same location in the input string (referred to elsewhere as "literal strings"). When the user is entering the string, these characters are automatically supplied, and the user is not required to type them. Literal strings must begin and end with the same quote character. Remember that the double quote (") character must be imbedded in C strings by preceding the quote character with a \ (backslash) character. The third and fourth parameters, nRow and nColumn specify the location on the screen where the first (left most) character of the input field should be located. These parameters are identical to the nRow and nColumn parameters passed to the od_set_cursor() function. In other words, nRow specifies the line number on the screen, where 1 is the first line, and nColumn specifies the column across the screen, where 1 is the first column. The fifth and sixth parameters, btNormalColor and btHighlightColor, allow you to specify the color of the input field. The fifth parameter, btNormalColor, specifies the color of the input field when input is not taking place and the sixth parameter, btHighlightColor, specifies the color of the field while input is taking place. Thus, if you had several input fields on the screen at one time, you would be able to make is easier for the user to identify the currently active field by =============================================================================== OpenDoors 6.00 Manual End of Page 72 having the field currently accepting input highlighted in a color distinct from the other fields. When the od_edit_str() function begins, it will change the current color of the field from the normal color to the highlighted color. Then, when the od_edit_str() function exits, it will change the current color of the field back to its normal color. If you do not wish to have the field highlighted, you can set both of these parameters to the same value, and disable field re-drawing by using the eighth parameter, flags. The seventh parameter accepted by the od_edit_str() function, chBlank, will serve one of two purposes. Normally, this parameter will specify a background character to display in the unfilled portion at the end of the input field. This can be set to a character, such as the ASCII 177 grey block character, to produce a visual background to the field. Doing this will show the user visually how long the field is, and how many character they will be permitted to type into the field. Normally, this field will be displayed during input, and removed when the od_edit_str() function exits. However, you may cause the background to remain in place using the eighth parameter, flags. If you do not wish to have this "background" visual field effect, simply set the character parameter to a space (ASCII 32). In password input mode, this parameter will instead specify the character to display in place of characters typed by the user. In this case, the background display character defaults to the space (ASCII 32) character. The eighth, and last, parameter accepted by the od_edit_str() function is the nFlags parameter. This parameter is a bit-mapped flags variable which allows you to control special features of the od_edit_str() function. More than one of these settings may be specified by listing a chain of the values, separated by the bitwise-or (|) operator. If you do not wish to turn on any of these modes, simply pass the EDIT_FLAG_NORMAL value as the flags parameter. EDIT_FLAG_NORMAL - Default setting, use this value of none of the other flags below are active. EDIT_FLAG_NO_REDRAW - When set, prevents the od_edit_str() function from re-drawing the input string and field when it starts up and exits. If you set this flag, the normal color and highlight color should contain the same value. If background character (the character parameter) is not a space (ASCII 32) character, you must draw the field background prior to calling od_edit_str(). Also, if you are calling od_edit_str() with the EDIT_FLAG_EDIT_STRING flag set, you must display the existing string in the field prior to calling od_edit_str(). =============================================================================== OpenDoors 6.00 Manual End of Page 73 EDIT_FLAG_FIELD_MODE - Setting this flag specifies that od_edit_str() should operate in field input mode. In field input mode, the user may finish entering their input by pressing the previous field or next field button (arrow keys, tab keys, etc.), as described above. If the user chooses to finish and accept their input by pressing one of these keys, the od_edit_str() return value will reflect which choice they made. This will allow you to make it possible for the user to move between a number of input fields in a form / dialog box, as demonstrated in the example accompanying the od_draw_box() function. EDIT_FLAG_EDIT_STRING - Setting this flag specifies that od_edit_str() should edit a pre-existing string, instead of starting with a blank string. In this case, the input_string parameter MUST point to an initialized string. This string may either contain some text, or be empty, but od_edit_str() will expect to find a string terminator ('\0') character, and will begin editing the contents of the string prior to that character. If you do not set the EDIT_FLAG_EDIT_STRING flag, the previous contents of the input_string parameter is not significant, as od_edit_str() will automatically start with a blank string. EDIT_FLAG_STRICT_INPUT - Setting this flag causes the od_edit_str() function to operate in "strict" input mode, which may be desirable if your input format contains more than one type of input. Normally, if you were inputting such a string, the user would be able to move to the middle of the string, and insert any text. Doing so would cause the rest of the input line to shift right. However, in cases where your format string specifies different types of character to be permitted in different positions, this can cause the input to be changed so that it no longer conforms to the format string. In this case, the user's input will no longer be valid, and the user will not be able to exit the function by pressing [ENTER] (although [ESCAPE] will still be available, if you activated it) until they change their input. However, when strict input mode is turned on, od_edit_str() will restrict the ways in which the user is permitted to edit the string, to prevent just such a case from occurring. EDIT_FLAG_PASSWORD_MODE - Setting this flag causes the od_edit_str() function to operate in "password" mode. In password mode, the characters typed by the user will be hidden, displayed instead as the blank character specified in the "character" parameter. =============================================================================== OpenDoors 6.00 Manual End of Page 74 EDIT_FLAG_ALLOW_CANCEL - When this flag is set, the user will be able to cancel their current input and abort the editing process by pressing their [ESCAPE] key. When they do so, any changes they have made to the input field will be canceled, and replaced by the original contents of the string. The od_edit_str() function will then exit, indicating that the user has canceled their input. EDIT_FLAG_FILL_STRING - When set, this flag will force the user to enter a string that fills the entire length of the format string. Normally, the user will be able to enter a string of any length up to the maximum length specified by the format string. However in some cases, such as when inputting a date, you will want to have the input field filled. (Otherwise, the user would be able to enter only the first part of the date.) EDIT_FLAG_AUTO_ENTER - When set, this flag will cause the od_edit_str() function to automatically simulate pressing of the [ENTER] key when the string is filled. This can be used to cause the od_edit_str() function to finish inputting as soon as a valid string is entered, instead of having to wait for the user to press [ENTER] / [RETURN]. EDIT_FLAG_AUTO_DELETE - When set, along with the EDIT_FLAG_EDIT_STRING flag, this flag will activate the auto-delete feature of the od_edit_str() function. When auto-delete is active, if the first key pressed by the user is not an edit control key, the existing text will automatically be deleted, and a totally new string accepted from the user. This could be useful when you are allowing the user to go back to edit a previous input. If the user wishes to only change part of the old string, they can move the cursor to the location where they wish to make the change, and perform their editing. However, if the user wishes to completely replace the old string with a new one, they can simply begin to type, and the old string will automatically be deleted, and the new string accepted. EDIT_FLAG_KEEP_BLANK - Normally, OpenDoors will only display the input field background (as passed in the "character" parameter) while the user is editing the string, and will remove it when the od_edit_str() function exits. However, you may wish to continue having this field displayed after input has taken place, and the od_edit_str() function has exited. In this case, setting this flag will cause the background characters to remain visible after input has finished. =============================================================================== OpenDoors 6.00 Manual End of Page 75 EDIT_FLAG_PERMALITERAL - When the format string contains literal characters (such as forcing a ':' character to be added to a time input by using the format string "##':'##':'##"), the od_edit_str() function can operate in one of two modes. In the default mode, the literal characters will only be displayed when they have been automatically added to the string. For instance, if you were inputting the current time using the above format string, this mode would result in the input field initially being blank. When the user types the first digit of the time, that number would appear. When the user types the second digit of the time, that number will appear, and then the colon character will automatically be added by OpenDoors. However, you can also set the od_edit_str() function to operate in "PermaLiteral" mode, by setting this flag. When the EDIT_FLAG_PERMALITERAL flag is set, the input field will initially contain the literal characters (ie, the colons in our example), with the cursor still located at the leftmost position in the input field. In this mode, the literal character become a permanent part of the input field, and can not be moved or deleted by the user - instead the cursor simply skips over the literal character's position. EDIT_FLAG_LEAVE_BLANK - This flag applies to the special case where the first character or characters of the format string are literals. By default, the od_edit_str() function will always return a string containing at least these first literal characters. However, you can alter this behaviors by setting this flag. When set, if no non-literal characters have been entered in the string, od_edit_str() will return an empty string. EDIT_FLAG_SHOW_SIZE - Normally, od_edit() adds an extra blank to the end of the input field, to give the cursor a space to move into when the field is full. However, you may prefer to have the input field be shown as exactly the maximum size of input that is permitted. Setting EDIT_FLAG_SHOW_SIZE does just this. In this case, the cursor will be positioned immediately past the end of the input field when the maximum number of characters have been entered. SEE ALSO od_input_str(), od_get_char(), od_clear_keybuffer() EXAMPLE Below are several examples of typical uses of the od_edit_str() function. For the sake of simplicity, all of these examples perform their input beginning at the top, left hand corner of the screen, and store the user's input in the string variable =============================================================================== OpenDoors 6.00 Manual End of Page 76 named "string". For an example of the user of the od_edit_str() function in a dialog-box / form entry application, see the example accompanying the od_draw_box() function. To input a name with a maximum of 25 characters, having the first letter of each word automatically capitalized: od_edit_str(string, "MMMMMMMMMMMMMMMMMMMMMMMMM", 1, 1, 0x03, 0x21, 176, EDIT_FLAG_NORMAL); To input a North American style phone number, requiring that all digits be filled, and running in "strict input" mode: od_edit_str(string, "###'-'###'-'####", 1, 1, 0x03, 0x21, 176, EDIT_FLAG_FILL_STRING| EDIT_FLAG_STRICT_INPUT); To allow the user to edit a previously entered 20 character string, with auto-delete mode on. Any characters will be permitted in the string. Remember that when the EDIT_FLAG_EDIT_STRING flag is set, the string must be initialized prior to calling the od_edit_str() function. od_edit_str(string, "????????????????????", 1, 1, 0x03, 0x21, 176, EDIT_FLAG_EDIT_STRING| EDIT_FLAG_AUTO_DELETE); To input a password of up to 16 characters from the user. Here, the password will only be permitted to contain upper case characters, and the od_edit_str() password mode is used, with a small block displayed in place of any characters typed: od_edit_str(string, "UUUUUUUUUUUUUUUU", 1, 1, 0x03, 0x21, 254, EDIT_FLAG_PASSWORD_MODE); To input a two-digit number from the user, requiring that both digits be filled, and automatically accepting the input after the two digits have been entered (not requiring the user to press [ENTER]): od_edit_str(string, "##", 1, 1, 0x03, 0x21, 176, EDIT_FLAG_FILL_STRING| EDIT_FLAG_AUTO_ENTER); To input a filename to download, as a field in a dialog box. Here, the filename will be permitted to contain valid filename characters, and the od_input_str() function will operate in field mode, with the cancel [ESCape] key enabled. Also, string =============================================================================== OpenDoors 6.00 Manual End of Page 77 edit mode will be enabled, allowing the user to edit a previously entered line, and the EDIT_FLAG_KEEP_BLANK flag will be set, causing the field background to remain displayed after the user exits. This time, however, auto-delete mode will not be used. Note that this combination of parameters expects that the field and it's contents will have already been displayed, prior to calling the od_edit_str() function. od_edit_str(string, "WWWWWWWWWWWW", 1, 1, 0x03, 0x21, 176, EDIT_FLAG_EDIT_STRING| EDIT_FLAG_FIELD_MODE| EDIT_FLAG_ALLOW_CANCEL| EDIT_FLAG_KEEP_BLANK); To input a string without the field background and line redrawing before and after input takes place: od_edit_str(string, "******************************", 1, 1, 0x07, 0x07, ' ', EDIT_FLAG_NO_REDRAW); To input a date, using PermaLiteral mode. Here, the month is entered by a three digit short form ("JAN", "FEB", etc.), and the literal characters such as the '-' and the "19" are a permanent part of the input field: od_edit_str(string,"UUU'-'##'-19'##", 1, 1, 0x03, 0x21, 176, EDIT_FLAG_PERMALITERAL| EDIT_FLAG_FILL_STRING); =============================================================================== OpenDoors 6.00 Manual End of Page 78 OD_EXIT() ------------------------------------------------------------------------------- PURPOSE The OpenDoors program termination function FORMAT void od_exit(INT nErrorLevel, BOOL bTermCall); RETURNS N/A DESCRIPTION You MUST USE THIS FUNCTION when you want your program to exit. This function will close the serial port, re-write changed information to the door information (drop), call your end-of- program function (if any), and then exit with the errorlevel specified in the first parameter. Also, if the second parameter, bTermCall, is set to TRUE, od_exit() will also log the user off (for options such as logging off within the door - as shown in the example below). This is accomplished by lowering the DTR line to the modem, causing the modem to hangup. When control is returned to the BBS, it will then detect that the user is no longer online, and will carry out its own logoff processing. If you wish for your program to always perform any activities prior to exiting, such as updating or closing data files, you should set a function to be executed from within the od_exit() function. This is accomplished by using the od_control. od_before_exit variable, as described in the section on the OpenDoors control structure in chapter 5. Use of this variable will allow your program to always carry out these activates, even if OpenDoors decides to call the od_exit() function itself, such as when a user hangs up on the door. Note that in special cases, you may use the od_control.od_disable variable to prevent the od_exit() function from re-writing the door information file. Also, you may use the od_control.od_noexit variable to shutdown door operations without actually exiting your program. Both of these variables are described in chapter 5. SEE ALSO od_init() EXAMPLE The example below demonstrates a function which a door could execute when the user chooses to exit the door. This function will ask the user whether they wish to exit the door and return to the BBS, simply logoff of the BBS, or continue using the door. The example function will then call od_exit() if the user =============================================================================== OpenDoors 6.00 Manual End of Page 79 wishes to exit the door, or return control to the function which called it, if the user does not wish to exit: void goodbye(void) { char pressed; /* Display choices to user */ od_disp_str("You have chosen to exit this door.\n\r"); od_disp_str("Do you wish to:\n\r"); od_disp_str(" [R]eturn to the BBS\n\r"); od_disp_str(" [L]ogoff of the BBS\n\r"); od_disp_str(" [C]ontinue using the door\n\r"); for(;;) /* loop until user makes valid choice */ { pressed=od_get_key(TRUE); /* Get key from user */ /* If user selects R, exit without hanging up */ if(pressed=='R' || pressed=='r') od_exit(40,FALSE); /* If user selects L, hangup and then exit */ if(pressed=='L' || pressed=='l') od_exit(41,TRUE); /* If user selects C, return and allow door to continue */ if(pressed=='C' || pressed=='c') return; } } =============================================================================== OpenDoors 6.00 Manual End of Page 80 OD_GET_ANSWER() ------------------------------------------------------------------------------- PURPOSE Function to allow the user to respond to a prompt using only certain keys. FORMAT char od_get_answer(char *pszOptions); RETURNS Character that user entered DESCRIPTION This function can be used to get a response from the user, when only particular responses should be accepted. The parameter to the od_get_answer() function is simply a string listing the valid responses. The function will wait until the user selects one of the valid responses, and then return that response. The function is case insensitive, and will return the character in the same case that was supplied to it in the string. SEE ALSO od_get_key(), od_hotkey_menu() EXAMPLES od_get_answer("YN"); - If the user presses 'y', will return 'Y'. od_get_answer("yn"); - If the user presses 'y', will return 'y'. od_get_answer("ABC 123\n\rZ"); - Valid responses will be: [A], [B], [C], [SPACE], [1], [2], [3], [ENTER], [Z] =============================================================================== OpenDoors 6.00 Manual End of Page 81 OD_GET_INPUT() ------------------------------------------------------------------------------- PURPOSE This function allows a single input event (e.g. keystroke) to be retrieved, optionally translating extended key sequences such as arrow keys and the insert key. FORMAT BOOL od_get_input(tODInputEvent *pInputEvent, tODMilliSec TimeToWait, WORD wFlags); RETURNS TRUE on success, FALSE if no input event was retrieved. DESCRIPTION Like od_get_key(), od_get_input() can be used to retrieve a single key of input from the user. However, od_get_input() has been designed to be easily extended in future versions of OpenDoors. The information retrieved by this new function is placed in a structure, which contains information on whether the input event was generated by the remote user or the local console, and what type of input event it was. This function also has built-in the ability to recognize and translate the multiple- character sequences that are generated when the user presses extended keys such as arrow keys, insert, delete, etc. The first parameter points to a tODInputEvent structure, which is defined as follows: typedef struct { tODInputEventType EventType; BOOL bFromRemote; char chKeyPress; } tODInputEvent; When od_get_input() successfully retrieves an input event, this structure is filled with information about the input. The EventType member can be either EVENT_CHARACTER (indicating a single character keystroke) or EVENT_EXTENDED_KEY (indicating an extended key, such as an arrow key). In the case of EVENT_CHARACTER, chKeyPress is set to the character that was received. In the case of EVENT_EXTENDED_KEY, chKeyPress is set to one of the following values: =============================================================================== OpenDoors 6.00 Manual End of Page 82 +------------------+---------------+-------------------------+ | chKeyPress Value | Meaning | Control Key Alternative | +------------------+---------------+-------------------------+ | OD_KEY_F1 | [F1] | None | | OD_KEY_F2 | [F2] | None | | OD_KEY_F3 | [F3] | None | | OD_KEY_F4 | [F4] | None | | OD_KEY_F5 | [F5] | None | | OD_KEY_F6 | [F6] | None | | OD_KEY_F7 | [F7] | None | | OD_KEY_F8 | [F8] | None | | OD_KEY_F9 | [F9] | None | | OD_KEY_F10 | [F10] | None | | OD_KEY_UP | [UP ARROW] | [CTRL]-[E] | | OD_KEY_DOWN | [DOWN ARROW] | [CTRL]-[X] | | OD_KEY_LEFT | [LEFT ARROW] | [CTRL]-[S] | | OD_KEY_RIGHT | [RIGHT ARROW] | [CTRL]-[D] | | OD_KEY_INSERT | [INSERT] | [CTRL]-[V] | | OD_KEY_DELETE | [DELETE] | [CTRL]-[G] | | OD_KEY_HOME | [HOME] | None | | OD_KEY_END | [END] | None | | OD_KEY_PGUP | [PAGE UP] | None | | OD_KEY_PGDN | [PAGE DOWN] | None | | OD_KEY_SHIFTTAB | [SHIFT]-[TAB] | None | +------------------+---------------+-------------------------+ The bFromRemote member of the tODInputEvent structure will be set to TRUE if the input event originated from the remote system, or FALSE if the event originated from the local system. The second parameter, TimeToWait specifies how long the function should wait for input before returning, in milliseconds. A value of 0 causes the function to return immediately if no input is waiting in OpenDoor's internal input buffer. The is equivalent to a value of FALSE being passed to the od_get_key() function. A value of OD_NO_TIMEOUT causes this function to wait and only return after the next input event has been received. This is equivalent to a value of TRUE being passed to the od_get_key() function. An other value specifies the maximum number of milliseconds that od_get_input() should wait for input. If input is received before this time elapses, od_get_key() will return immediately with a value of TRUE, and the tODInputEvent structure will be fill accordingly. If no input is received before this time elapses, od_get_key() will return FALSE. The number of milliseconds to wait is rounded to the nearest 55 milliseconds in the DOS version of OpenDoors. The third parameter allows you to specify flags to further control the behavior of od_get_input(). Normally, this parameter will be set to GETIN_NORMAL. However, you can disable all translation of extended keystrokes by setting this value to GETIN_RAW. In this mode, od_get_input() works just like =============================================================================== OpenDoors 6.00 Manual End of Page 83 od_get_key(), returning every individual character received from the remote system. Since extended keys are not directly supported by all terminal programs, od_get_input() provides alternatives for some of the extended keys, in the form of control-key combinations. The control key combinations recognized by od_get_input() are listed in the table above. However, these control key alternatives can be ignored by setting the GETIN_RAWCTRL flag. The od_get_input() function is used internally by od_popup_menu(), od_edit_str() and od_multiline_edit(). SEE ALSO od_get_key(), od_clear_keybuffer() EXAMPLE The following example shows the structure of how od_get_input() might be used in your program: tODInputEvent InputEvent; od_get_input(&InputEvent, OD_NO_TIMEOUT, GETIN_NORMAL); if(InputEvent.EventType == EVENT_EXTENDED_KEY) { switch(InputEvent.chKeyPress) { case OD_KEY_UP: /* The up arrow key has been pressed. */ break; case OD_KEY_DOWN: /* The down arrow key has been pressed. */ break; } } else if(InputEvent.EventType == EVENT_CHARACTER) { /* A single character key has been pressed, and is */ /* stored in InputEvent.chKeyPress. */ } =============================================================================== OpenDoors 6.00 Manual End of Page 84 OD_GET_KEY() ------------------------------------------------------------------------------- PURPOSE Function to input a key from the user FORMAT char od_get_key(BOOL bWait); RETURNS The next key waiting from the keyboard, or 0 if none. DESCRIPTION This function retrieves the next key waiting in the OpenDoors keyboard buffer (see the description of the od_clear_keybuffer() function, on page 53, for more information on the OpenDoors keyboard buffer). The od_get_key() function allows your door to retrieve both those keystrokes pressed by the user, and the keystrokes pressed on the sysop keyboard (other than the sysop function keys), in the sequence they were pressed. Since input is accepted from both sources, it is possible for the sysop, as well as the remote user, to make selections and control the door. Door input with OpenDoors can be accomplished with this function, with the od_input_str() function or with the od_edit_str() function. The od_input_str() and od_edit_str() functions is used to input an entire sequence of characters from the user (a string), and requires the user to press the [Enter] key when they are finished typing their input. On the other hand, the od_get_key() function is used to input a single keystroke (one character) from the user, and allows the user to make choices without having to press the enter key. The od_get_key() function accepts a single parameter, which determines whether or not it should wait for the user to press a key, if they have not already done so. If you pass a FALSE value to od_get_key(), then the function will not wait for a key to be pressed at the keyboard, but instead return a 0 if there are no keys waiting in the buffer. If you pass a TRUE value to od_get_key(), then this function will instead wait for a key to be pressed. Also, while waiting for the user to press a key, the od_get_key() function will give up the processor to other waiting programs, if you door is running under DesqView. If you are waiting for the user to make a choice from a menu or list of options, you will most likely pass a TRUE to the od_get_key() function, indicating that you wish for it to wait until a key is pressed. However, if you wish to continue other processing if no key is yet available from the keyboard, you should pass a FALSE to the od_get_key() function. For example, if you are displaying a screen of text, and wish to allow the user to pause or abort the display, you would simply call the =============================================================================== OpenDoors 6.00 Manual End of Page 85 od_get_key() function every few moments, passing it a value of FALSE. You would then be able to check if any control keys have been pressed, and if not, continue displaying text. The od_get_key() function returns the ASCII value representing the keystroke that was made. If you are waiting for the user to make a particular choice, perhaps from a menu, you will most likely store the value returned by od_get_key() in a variable of type char. For example: char key; ... key=od_get_key(TRUE); You would then be able to determine which key the user pressed by testing the value of key, either by comparing it's numerical ASCII value, or by comparing it to a character constant. If you are testing for a non-character key, such as [ESCape], [Tab] or [Return], you may wish to use the ASCII value of that key. For example, if you wished to take some action in the case that the user presses the [Enter]/[Return] key, who's ASCII value is 13, you could do: key=od_get_key(TRUE); /* Get keypress from user */ if(key==13) /* If key was [Enter]/[Return] */ { ... /* Whatever you want to do */ } If you wish, instead, to respond to the user pressing a character key (perhaps as a choice from a menu), you can do so by using character constants, such as 'c', '6', or 'F'. Also, when testing for an alphabetical character, you will probably want to check for the user pressing either the upper or lower- case version of the letter. For example, if you wished to have the user press the [Y] key to continue, you could test for either an upper or lower-case Y as follows: key=od_get_key(TRUE); /* Get keypress from user */ if(key=='y' || key=='Y') /* If key was [y]/[Y] */ { ... /* Whatever you want to do */ } The charts on the following page lists the decimal value and corresponding keystroke(s) of each of the ASCII values from 0 to 127. =============================================================================== OpenDoors 6.00 Manual End of Page 86 ASCII KEYSTROKE | ASCII KEYSTROKE ----- ------------------------------ | ----- ---------------------- 0 [Control]-[@] | 15 [Control]-[O] 1 [Control]-[A] | 16 [Control]-[P] 2 [Control]-[B] | 17 [Control]-[Q] 3 [Control]-[C] | 18 [Control]-[R] 4 [Control]-[D] | 19 [Control]-[S] 5 [Control]-[E] | 20 [Control]-[T] 6 [Control]-[F] | 21 [Control]-[U] 7 [Control]-[G] | 22 [Control]-[V] 8 [Control]-[H]/[Backspace] | 23 [Control]-[W] 9 [Control]-[I]/[Tab] | 24 [Control]-[X] 10 [Control]-[J] | 25 [Control]-[Y] 11 [Control]-[K] | 26 [Control]-[Z] 12 [Control]-[L] | 27 [ESCape] 13 [Control]-[M]/[Enter]/[Return] | 32 [SpaceBar] 14 [Control]-[N] | ASCII KEYSTROKE | ASCII KEYSTROKE | ASCII KEYSTROKE | ASCII KEYSTROKE ----- --------- | ----- --------- | ----- --------- | ----- --------- 33 '!' | 57 '9' | 80 'P' | 104 'h' 34 '"' | 58 ':' | 81 'Q' | 105 'i' 35 '#' | 59 ';' | 82 'R' | 106 'j' 36 '