Newsgroups: comp.sources.unix From: glover@credit.erin.utoronto.ca (Mike Glover) Subject: v29i105: cdk-4.7.0 - Curses Development Kit, V4.7.0, Part01/10 Message-id: <1.833427459.28242@gw.home.vix.com> Sender: unix-sources-moderator@gw.home.vix.com Approved: vixie@gw.home.vix.com Submitted-By: glover@credit.erin.utoronto.ca (Mike Glover) Posting-Number: Volume 29, Issue 105 Archive-Name: cdk-4.7.0/part01 Cdk Version 4.7.0 Overview of Cdk --------------- Cdk stands for 'Curses Development Kit' and it currently contains 17 ready to use widgets which facilitate the speedy development of full screen curses programs. This little project of mine started as a test to see how compatible my Linux machine was to other UNIX breeds. While doing this I discovered Ncurses, and played with it. These widgets are the result of a years worth of playing. The current complement of widgets are: Widget Type Quick Description =========================================================================== Dialog Prompts the user with a message, and the user can pick an answer from the buttons provided. Entry Allows the user to enter information. File Selector A file selector built from Cdk base widgets. This example shows how to create more complicated widgets using the Cdk widget library. Graph Draws a graph. Histogram Draws a histogram. Item List Creates a pop up field which allows the user to select one of several choices in a small field. Very useful for things like days of the week or month names. Label Displays messages in a pop up box, or the label can be considered part of the screen. Marquee Displays a message in a scrolling marquee. Matrix Creates a complex matrix with lots of options. Menu Creates a pull-down menu interface. Multiple Line Entry A multiple line entry field. Very useful for long fields. (like a description field) Radio List Creates a radio button list. Scale Creates a numeric scale. Used for allowing a user to pick a numeric value and restrict them to a range of values. Scrolling List Creates a scrolling list/menu list. Scrolling Window Creates a scrolling log file viewer. Can add information into the window while its running. A good widget for displaying the progress of something. (akin to a console window) Selection List Creates a multiple option selection list. Template Creates a entry field with character sensitive positions. Used for pre-formatted fields like dates and phone numbers. Viewer This is a file/information viewer. Very useful when you need to display loads of information. =========================================================================== Each widget has the ability to display color, or other character attributes. Cdk comes with a attribute/color format command set which allows a programmer to add colors and characters attributes simply. The code has been cleaned using both Purify(TM) and Sun's Testcenter(TM), so it is as clean as a babies butt. :) Any leaks I have seen are in the curses libraries; there is nothing I can do about that, sorry. There are no memory leaks within the code, it shouldn't core dump, and it shouldn't do anything unexpected. If you do see something like this tell me after you read the BUGS file. Distribution: ------------- This distribution has a full complement of manual pages, so any specifics to the widgets will not be addressed in this read me. If you want to get right in there, nroff the cdk.3x file in the man directory. It is the starting point for all the manual pages. There are some other files to look at if you want to get anywhere. They are: INSTALL - This will show you how to build Cdk and install it on your system. If there are any personal modifications that you think may be needed, read this file. In fact read it regardless. :) COPYING - The legal stuff to protect my butt and all of the hard work that I have put into this library. EXPANDING - You feel creative enough to add a widget, here are my requirements that you have to follow to make the integration of a new widget seamless. BUGS - What to do when you find a bug. It also lists all of the bugs found, who found then, who fixed them, and when they were fixed. If you think you have found a bug look at this file. If you do not think you have the most up to date version of Cdk, go get it and try to replicate the problem. Then look at the BUGS file again. If it is NOT there, then you can mail me notifying me of a possible bug. I will try my hardest to get back to you, but I have a pretty busy schedule so don't expect an instant reply. This file will also explain how I would like any bug fixes sent to me. NOTES - Misc babblings of myself somewhat related to this distribution. VERSION - Contains the current rev level, when it was released, and what is different from the previous release. (I promise to make sure I keep this up to date. :) ) TODO - A list of things I plan to do in the future. (sleep) CHANGES - A list of changes from one release to another. If you have any comments, questions, or complaints mail me at glover@tuzo.erin.utoronto.ca ttfn, Mike PS: There is also a Perl5 extension of this library for you Perl5 fans. ########################### CUT HERE #################################### #!/bin/sh # This is a shell archive (produced by GNU sharutils 4.1). # To extract the files from this archive, save it to some FILE, remove # everything before the `!/bin/sh' line above, then type `sh FILE'. # # Made on 1996-05-03 19:13 EDT by . # Source directory was `/home/glover/tmp/cdk4.7.0'. # # Existing files will *not* be overwritten unless `-c' is specified. # # This is part 1 of a multipart archive. # Do not concatenate these parts, unpack them in order with `/bin/sh'. # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 2954 -r--r--r-- BUGS # 20514 -r--r--r-- COPYING # 2680 -r--r--r-- EXPANDING # 2787 -r--r--r-- INSTALL # 6333 -rw-r--r-- Makefile # 2167 -r--r--r-- NOTES # 5546 -r--r--r-- README # 908 -r--r--r-- TODO # 369 -r--r--r-- VERSION # 15039 -r--r--r-- binding.c # 28144 -r--r--r-- cdk.c # 38118 -r--r--r-- cdk.h # 43144 -r--r--r-- cdkscreen.c # 10047 -r--r--r-- curdefs.h # 854 -r--r--r-- debug.c # 2521 -r--r--r-- demo/fileview.c # 50056 -r--r--r-- demo/rolodex.c # 6439 -r--r--r-- demo/command.c # 3225 -r--r--r-- demo/rolodex.h # 265 -r--r--r-- demo/Makefile.demos # 10522 -r--r--r-- dialog.c # 9313 -r--r--r-- draw.c # 19470 -r--r--r-- entry.c # 1855 -r--r--r-- exam/dialog_ex.c # 1386 -r--r--r-- exam/entry_ex.c # 2363 -r--r--r-- exam/graph_ex.c # 2544 -r--r--r-- exam/fselect_ex.c # 3940 -r--r--r-- exam/histogram_ex.c # 1871 -r--r--r-- exam/itemlist_ex.c # 1359 -r--r--r-- exam/label_ex.c # 1357 -r--r--r-- exam/marquee_ex.c # 2180 -r--r--r-- exam/matrix_ex.c # 1388 -r--r--r-- exam/mentry_ex.c # 1740 -r--r--r-- exam/menu_ex.c # 1942 -r--r--r-- exam/radio_ex.c # 1209 -r--r--r-- exam/scale_ex.c # 1931 -r--r--r-- exam/scroll_ex.c # 2052 -r--r--r-- exam/selection_ex.c # 2382 -r--r--r-- exam/swindow_ex.c # 1476 -r--r--r-- exam/template_ex.c # 2218 -r--r--r-- exam/viewer_ex.c # 1569 -r--r--r-- exam/subwindow_ex.c # 4262 -r--r--r-- exam/bind_ex.c # 1148 -r--r--r-- exam/hello_ex.c # 271 -r--r--r-- exam/Makefile.examples # 19186 -r--r--r-- fselect.c # 7952 -r--r--r-- graph.c # 18649 -r--r--r-- histogram.c # 10970 -r--r--r-- itemlist.c # 4146 -r--r--r-- label.c # 8137 -r--r--r-- man/dialog.3 # 11568 -r--r--r-- man/entry.3 # 3889 -r--r--r-- man/graph.3 # 7898 -r--r--r-- man/fselect.3 # 5095 -r--r--r-- man/histogram.3 # 8972 -r--r--r-- man/itemlist.3 # 3495 -r--r--r-- man/label.3 # 3509 -r--r--r-- man/marquee.3 # 13420 -r--r--r-- man/matrix.3 # 12146 -r--r--r-- man/mentry.3 # 7720 -r--r--r-- man/menu.3 # 8653 -r--r--r-- man/radio.3 # 9658 -r--r--r-- man/scale.3 # 9355 -r--r--r-- man/scroll.3 # 8970 -r--r--r-- man/selection.3 # 9633 -r--r--r-- man/swindow.3 # 9974 -r--r--r-- man/template.3 # 7552 -r--r--r-- man/viewer.3 # 4334 -r--r--r-- man/cdk.3 # 4470 -r--r--r-- man/screen.3 # 8383 -r--r--r-- man/binding.3 # 9802 -r--r--r-- man/display.3 # 5909 -r--r--r-- marquee.c # 42377 -r--r--r-- matrix.c # 24525 -r--r--r-- mentry.c # 15005 -r--r--r-- menu.c # 15203 -r--r--r-- radio.c # 9595 -r--r--r-- scale.c # 21661 -r--r--r-- scroll.c # 16736 -r--r--r-- selection.c # 17611 -r--r--r-- swindow.c # 18485 -r--r--r-- template.c # 25291 -r--r--r-- viewer.c # touch -am 1231235999 $$.touch >/dev/null 2>&1 if test ! -f 1231235999 && test -f $$.touch; then shar_touch=touch else shar_touch=: echo echo 'WARNING: not restoring timestamps. Consider getting and' echo "installing GNU \`touch', distributed in GNU File Utilities..." echo fi rm -f 1231235999 $$.touch # if test -r _sharseq.tmp; then echo 'Must unpack archives in sequence!' echo Please unpack part `cat _sharseq.tmp` next exit 1 fi # ============= BUGS ============== if test -f 'BUGS' && test X"$1" != X"-c"; then echo 'x - skipping BUGS (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting BUGS (text)' sed 's/^X//' << 'SHAR_EOF' > 'BUGS' && Cdk Bugs Guide Copyright Mike Glover, 1995 ------------------------------------------------------------------------------- If you find a bug, and want me to fix it, you will need to do a few things for me. X * Give me a copy or part of the code which demonstrates this bug. If X you can't do this, then replicate the bug in a piece of test code X and send me that. X * Make sure you can replicate the bug. Then send me the of instructions X on how to replicate the noted bug. X If you do this, I will mail you back telling you if the information was sufficient or not. If it is, I will tell you when I hope to have this bug licked by. If you need an urgent update (ie: your boss is crawling down your throat for your program to work) tell me, I'll get to it ASAP. BTW, thanks for trusting my code enough to use in the 'real world' :). X If you find a bug and fixed it yourself, I will need the same as above with a few extras. X * I will need a patch of any piece of code you made so I can apply it X to what I have. X * Tar this up and send it to me. X If you have found and fixed a valid bug, you will be noted in the next distribution of this bugs file, and my warmest thanks for reducing my ever growing workload. :) X Here is the noted list of outstanding bugs and bugs of the past... ------------------------------------------------------------------------------ X Release Widget Problem Fixed ------- ------ ------- ----- 4.6.0 Label Label widget would not map itself to the screen Jan/96 X via refreshCDKScreen. 4.6.0 Mentry When inserting into the middle of a string, the Jan/96 X cursor would not move to the right. 4.6.0 Scroll When scrolling the list to the right, the Jan/96 X window border would not get refreshed. 4.6.0 Scale The scale window was always too large. Jan/96 4.6.0 Matrix Fixed cleanCDKMatrix function. (FATAL) Jan/96 4.6.0 Viewer Changed activate->set, manage->activate, and Jan/96 X removed set. Cleaned the function setCDKViewer. 4.6.0 Viewer When loading up a small file, garbage would Jan/96 X appear under the last line to the bottom of X the viewer. 4.6.0 Graph When drawing the graph in line mode, the lines Jan/96 X would be too far off the x axis. 4.6.0 Template When calling mixCDKTemplate, the widget would Jan/96 X core out. 4.6.0 Swindow Fixed leak in trimCDKSwindow, cleanCDKSwindow. Jan/96 4.6.0 Selection Fixed scrolling bug. Jan/96 4.6.1 Fselect The entry field would never get mapped on Mar/96 X the first instantiation. 4.6.1 Viewer Centered text did not scroll correctly. Mar/96 4.6.1 Radio Centered text did not scroll correctly. Mar/96 4.6.1 Scroll Centered text did not scroll correctly. Mar/96 4.6.1 Selection Centered text did not scroll correctly. Mar/96 4.6.1 All Fixed the function char2Chtype to expand Mar/96 X tab characters. 4.6.1 Template Fixed problem with cursor not being adjusted Mar/96 X correctly if the plate started with a X 'drawing' character. SHAR_EOF $shar_touch -am 0503190996 'BUGS' && chmod 0444 'BUGS' || echo 'restore of BUGS failed' shar_count="`wc -c < 'BUGS'`" test 2954 -eq "$shar_count" || echo "BUGS: original size 2954, current size $shar_count" rm -f _sharnew.tmp fi # ============= COPYING ============== if test -f 'COPYING' && test X"$1" != X"-c"; then echo 'x - skipping COPYING (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting COPYING (text)' sed 's/^X//' << 'SHAR_EOF' > 'COPYING' && Cdk Copying Guide Copyright Mike Glover, 1995 ------------------------------------------------------------------------------- In order to copy Cdk around I have some requirements that will protect me, and possibly even you. First thing, I feel I should say that this little project of mine has taken about a year of my 'free' time and I have put a lot of work into it. I do ask that if anyone asks you about Cdk, tell them where you got it and who wrote it. If you see Cdk installed without this file on the system somewhere, then assume the copy the person has is a 'corrupt' version. I will not be responsible for any unfortunate results if someone else makes a personal modification to the Cdk library. I will also not be responsible if for some reason the installation of Cdk creates a negative effect on your machine. You do have my word that there are no "Trojan horses", worms, or other security worries lurking in this code. If there are I did not put them there and you should remove the version of Cdk you have and go get a proper copy. I hate virus writers as much as anyone else! X Instead of writing my own license (I'm a programmer, not a lawyer!) I'm going to borrow the GNU public license on public software. If you do not agree to this license then remove the Cdk distribution and we all will be happier in the end. Here is the complete GNU public license in it's true form. I have not made any modifications to it. X I will say one thing, Cdk is my copyright. I will continue to support any released versions out there as long as they are in their released form. I am releasing this into the "public" because I feel I have benefited from other people's hard work, I'd like to chip into the pot as well. This does NOT make Cdk public domain though. Cdk is still my copyright, and owned by me, I am merely stating this so I don't see 40 different versions of my code floating around with other people's names attached. X With that ugly stuff said, I will happily take any comments or questions about Cdk. Input is more than welcomed. In fact I encourage it. Feel free to mail me and ask questions you thin the supplied documents don't cover. If I get enough I may build a FAQ to help newcomers. (we'll see how Cdk is accepted though) X For you Perl programmers, there is a Perl5 extension to Cdk being released at the same time. If you see this message, pop over to the Perl newsgroups and look for the Cdk Perl5 extension. X ttfn, X Mike ------------------------------------------------------------------------------- X GNU GENERAL PUBLIC LICENSE X Version 2, June 1991 X X Copyright (C) 1989, 1991 Free Software Foundation, Inc. X 675 Mass Ave, Cambridge, MA 02139, USA X Everyone is permitted to copy and distribute verbatim copies X of this license document, but changing it is not allowed. X X Preamble X X The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. X X When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. X X To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. X X For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. X X We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. X X Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. X X Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. X X The precise terms and conditions for copying, distribution and modification follow. X X X GNU GENERAL PUBLIC LICENSE X TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION X X 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". X Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. X X 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. X You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. X X 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: X X a) You must cause the modified files to carry prominent notices X stating that you changed the files and the date of any change. X X b) You must cause any work that you distribute or publish, that in X whole or in part contains or is derived from the Program or any X part thereof, to be licensed as a whole at no charge to all third X parties under the terms of this License. X X c) If the modified program normally reads commands interactively X when run, you must cause it, when started running for such X interactive use in the most ordinary way, to print or display an X announcement including an appropriate copyright notice and a X notice that there is no warranty (or else, saying that you provide X a warranty) and that users may redistribute the program under X these conditions, and telling the user how to view a copy of this X License. (Exception: if the Program itself is interactive but X does not normally print such an announcement, your work based on X the Program is not required to print an announcement.) X X These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. X Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. X In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. X X 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: X X a) Accompany it with the complete corresponding machine-readable X source code, which must be distributed under the terms of Sections X 1 and 2 above on a medium customarily used for software interchange; or, X X b) Accompany it with a written offer, valid for at least three X years, to give any third party, for a charge no more than your X cost of physically performing source distribution, a complete X machine-readable copy of the corresponding source code, to be X distributed under the terms of Sections 1 and 2 above on a medium X customarily used for software interchange; or, X X c) Accompany it with the information you received as to the offer X to distribute corresponding source code. (This alternative is X allowed only for noncommercial distribution and only if you X received the program in object code or executable form with such X an offer, in accord with Subsection b above.) X The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. X If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. X X X 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. X X 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. X X 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. X X 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. X If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. X It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. X This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. X X X 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. X X 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. X Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. X X 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. X X NO WARRANTY X X 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. X X 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. X X END OF TERMS AND CONDITIONS X X X Appendix: How to Apply These Terms to Your New Programs X X If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. X X To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. X X X Copyright (C) 19yy X X This program is free software; you can redistribute it and/or modify X it under the terms of the GNU General Public License as published by X the Free Software Foundation; either version 2 of the License, or X (at your option) any later version. X X This program is distributed in the hope that it will be useful, X but WITHOUT ANY WARRANTY; without even the implied warranty of X MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the X GNU General Public License for more details. X X You should have received a copy of the GNU General Public License X along with this program; if not, write to the Free Software X Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. X Also add information on how to contact you by electronic and paper mail. X If the program is interactive, make it output a short notice like this when it starts in an interactive mode: X X Gnomovision version 69, Copyright (C) 19yy name of author X Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. X This is free software, and you are welcome to redistribute it X under certain conditions; type `show c' for details. X The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. X You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: X X Yoyodyne, Inc., hereby disclaims all copyright interest in the program X `Gnomovision' (which makes passes at compilers) written by James Hacker. X X , 1 April 1989 X Ty Coon, President of Vice X This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. SHAR_EOF $shar_touch -am 0503190996 'COPYING' && chmod 0444 'COPYING' || echo 'restore of COPYING failed' shar_count="`wc -c < 'COPYING'`" test 20514 -eq "$shar_count" || echo "COPYING: original size 20514, current size $shar_count" rm -f _sharnew.tmp fi # ============= EXPANDING ============== if test -f 'EXPANDING' && test X"$1" != X"-c"; then echo 'x - skipping EXPANDING (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting EXPANDING (text)' sed 's/^X//' << 'SHAR_EOF' > 'EXPANDING' && Cdk New Widget Guide Copyright Mike Glover, 1995 ------------------------------------------------------------------------------- X If you want to create a new widget for Cdk, and want it in the standard dist of Cdk, you will have to follow some requisites that I have. I state these because Cdk has been worked on for quite some time and I finally got it to a state where the functions calls are somewhat consistent. Any new widgets should adhere to this. The requirements are as follows: X X * The function names should be like: X newCDKXXX, destroyCDKXXX, setCDKXXX, drawCDKXX,... X Any widgets with functions not in this format should be 'private'. X If this is not the case one of three things will happen: X 1) The widget will not get accepted X 2) I will mail you back asking you to follow the standards. X 3) I will do it myself. (HIGHLY unlikely) X X * The first parameter of the newCDKXXX function should be of type X CDKSCREEN. X * If applicable, the next two parameters should be xpos and ypos in X that order. X * If the widget has a label, the next parameter should be lpos followed X by char *label. X * The last two parameters of the newCDKXXX function should be: X Boolean box, Boolean shadow if the parameters apply. X * The drawCDKXXX function should only have the pointer to the object and X a Boolean box as it's parameters. (in that order) X * The first parameters of any other function relating to the widget X should be a pointer to the widget type. ie: CDKRADIO *, CDKFSELECT *... X * A destroyCDKXXX function has to be provided as well as a drawCDKXXX X function. X * Try to contain anything specific to the widget in a single file. This X keeps the overhead of misc. files from floating around. X If you follow the guidelines, then the files you need to change to sew the new widget into Cdk, are: X X cdkscreen.c So this widget will get refreshed on a refreshCDKScreen X function call. X binding.c To allow key bindings for the widget. If it is possible X to have key bindings I stress that this be incorporated. X cdk.h To add in the function def's to the header file. X Makefile Add in the new widget files. X If you have done all of this then what I need from you is the following: X X * A diff of all the files from the dist. that you modified. Use X patch, I prefer it. If you haven't got it, get it and use it. It makes X life easy. X * A copy of the new widget file. X * tar this up and send it to me at X glover@tuzo.erin.utoronto.ca X I will mail you back when I get it and I will tell you if everything is X OK or not. X I hate to be such a nit pick, but if we follow the above standards, Cdk will evolve into a very nice library, with a lot of really nice widgets. X ttfn, X Mike X SHAR_EOF $shar_touch -am 0503190996 'EXPANDING' && chmod 0444 'EXPANDING' || echo 'restore of EXPANDING failed' shar_count="`wc -c < 'EXPANDING'`" test 2680 -eq "$shar_count" || echo "EXPANDING: original size 2680, current size $shar_count" rm -f _sharnew.tmp fi # ============= INSTALL ============== if test -f 'INSTALL' && test X"$1" != X"-c"; then echo 'x - skipping INSTALL (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting INSTALL (text)' sed 's/^X//' << 'SHAR_EOF' > 'INSTALL' && Cdk Installation Guide Copyright Mike Glover, 1995 ------------------------------------------------------------------------------- X General ------- This document details how to build and install the Cdk library. The first thing you should know is what compile options you may require. I have had the fortunate luck of being able to compile this library on the following platforms: X * Sun/OS 4.1.* X * Solaris 2.3/2.4 X * AIX 3.2.* (and even AIX 4.1 but there is no mention of this in the X makefile. Sorry.) X * HPUX 9.* (and even HPUX 10.* but there is no mention of this in the X makefile. Sorry.) X * Linux, in both a.out and Elf. X If you have a machine that is not mentioned here and you would like to see it in the makefile, mail me the additions for the makefile and I will add them in. X CFLAGS ------ You may need to change a few things in the makefile as far as compile options are concerned, but also the C flags. There are a number of defined CFLAGS that should be explained. They are as follows: X X -DCOLOR Add in if your curses header file supports color. X Ncurses does. X -DWINCHBUG If your copy of curses has a bug in the routine winch. X -DNOUSLEEP If you haven't got the usleep library function. X -DNODYNALLOC If your compiler does not support the use of non X constants in variable definitions. Set -DDNODYNALLOC X can't support a definition like the following: X char *array[variableName]; X where variableName is a variable that was set to X dictate the size of the array. X -DAIX As always, AIX is the exception to the rule.... X -DOLDCURSES Use this flag if you suspect your version of curses X is very closely related to the older versions of BSD X curses. X Building -------- To build the library cd into the Cdk distribution directory and type in make cdklib This builds the file libcdk.a That's all there is to it. X Building the example programs ----------------------------- To build the programs in the exam directory type in make examples in the source root directory. This will build all the files under the directory exam. X Building the example programs ----------------------------- To build the programs in the demo directory type in make demos in the source root directory. This will build all the files under the directory demo. X Installing ---------- Modify the makefile to set the values of INST_ROOTDIR, INST_LIBDIR, INST_INCDIR, and INST_MANDIR. These variables set the location of the root install directory, the library directory, the include directory, and the man directory respectively. Once these have been set correctly, su to root and type make install This will install the files: cdk.h, curdefs.h, libcdk.a , the example files, the misc documents which come with Cdk, and all of the manual pages. SHAR_EOF $shar_touch -am 0503190996 'INSTALL' && chmod 0444 'INSTALL' || echo 'restore of INSTALL failed' shar_count="`wc -c < 'INSTALL'`" test 2787 -eq "$shar_count" || echo "INSTALL: original size 2787, current size $shar_count" rm -f _sharnew.tmp fi # ============= Makefile ============== if test -f 'Makefile' && test X"$1" != X"-c"; then echo 'x - skipping Makefile (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting Makefile (text)' sed 's/^X//' << 'SHAR_EOF' > 'Makefile' && # Generated automatically from Makefile.in by configure. # # This is the makefile for the CDK library. Uncomment the machine/os # type which best suits your machine. # X # Set up some global variables. CDKLIB = libcdk.a CDKSLIB = libcdk.so.1 VERSION = 4.7.0 X # Set up directory paths. MANDIR = ./man EXAMDIR = ./exam DEMODIR = ./demo RELDIR = ./cdk$(VERSION) INST_ROOTDIR = /usr INST_LIBDIR = ${exec_prefix}/lib INST_INCDIR = ${prefix}/include INST_MANDIR = ${prefix}/man/man2 INST_SRCDIR = ${prefix}/src X # Linux CC = gcc INCPATH = -I/usr/include/ncurses -I/usr/local/include LIBPATH = -L/usr/lib -L. LINKLIB = -lncurses SHARED = -fPIC SLINK = -shared -Wl,-soname,$(CDKSLIB) CFLAGS = $(INCPATH) -g -Wall -DWINCHBUG RANLIB = @ranlib $(CDKLIB) X # Linux XCurses (Use this if you have Xcurses support) #CC = gcc #INCPATH = -I/home/mark/PDCurses-2.3 #LIBPATH = -L/home/mark/PDCurses/pdcurses -L. #LINKLIB = $(LIBPATH) -lxcurses #SHARED = -fPIC #SLINK = -shared -Wl,-soname,$(CDKSLIB) #CFLAGS = $(INCPATH) -g -Wall -DLINUX -DCOLOR -DXCURSES X # SUN #CC = gcc #INCPATH = -I/usr/5include #LIBPATH = -L/usr/5lib -L/usr/lib #LINKLIB = -lcurses -ltermcap #CFLAGS = $(INCPATH) -g -DNOSTRERR -DOLDCURSES #RANLIB = @ranlib $(CDKLIB) X # SOLARIS #CC = cc #INCPATH = #LIBPATH = -L/usr/ccs/lib #LINKLIB = -lcurses -ltermcap #SLINK = -G #CFLAGS = $(INCPATH) -g -DNOBZERO -DNOUSLEEP -DNODYNALLOC #SFLAGS = -Fpic #RANLIB = echo X # AIX #CC = cc #INCPATH = #LIBPATH = #LINKLIB = $(LIBPATH) -lcurses -ltermcap #CFLAGS = $(INCPATH) -g -qlanglvl=ansi -DAIX -DNODYNALLOC #RANLIB = @ranlib $(CDKLIB) X # HP-UX #CC = c89 #INCPATH = #LIBPATH = #LINKLIB = $(LIBPATH) -lcurses #CFLAGS = $(INCPATH) -g -Aa -D_HPUX_SOURCE -DNODYNALLOC -DNOCHTYPE #RANLIB = @ranlib $(CDKLIB) X ############################################################### # Do Not change anything under this line. # ############################################################### X # Create the file lists. CDKHDR = cdk.h curdefs.h CDKWIDGETS = dialog.c entry.c graph.c fselect.c \ X histogram.c itemlist.c label.c marquee.c \ X matrix.c mentry.c menu.c radio.c \ X scale.c scroll.c selection.c \ X swindow.c template.c viewer.c CDKSRC = draw.c cdk.c cdkscreen.c binding.c debug.c $(CDKWIDGETS) CDKOBJS = $(CDKSRC:.c=.o) CDKEXAMSRC = $(CDKWIDGETS:.c=_ex.c) subwindow_ex.c bind_ex.c hello_ex.c CDKEXAMBIN = $(CDKEXAMSRC:_ex.c=) CDKDEMOSRC = fileview.c rolodex.c command.c CDKDEMOHDR = rolodex.h CDKDEMOBIN = $(CDKDEMOSRC:.c=) CDKMAN = $(CDKWIDGETS:.c=.3) cdk.3 screen.3 binding.3 display.3 CDKDOCS = BUGS EXPANDING INSTALL NOTES README TODO VERSION COPYING X # Create the compile information for the executables. tst: tst.o $(CDKOBJS) X $(CC) $(CFLAGS) -o tst tst.o $(CDKOBJS) $(INCPATH) $(LIBPATH) $(LINKLIB) X stst: tst.o X $(CC) $(CFLAGS) -o stst tst.o $(CDKSLIB).0 $(INCPATH) $(LIBPATH) $(LINKLIB) X lib: $(CDKOBJS) X @ar r $(CDKLIB) $(CDKOBJS) X @$(RANLIB) X # Standard library directive. cdklib $(CDKLIB): X @$(MAKE) clean X $(CC) $(CFLAGS) -c $(CDKSRC) X @ar r $(CDKLIB) $(CDKOBJS) X @$(RANLIB) X # Shared library directive. cdkslib $(CDKSLIB): X @$(MAKE) clean X $(CC) $(CFLAGS) $(SFLAGS) -c $(CDKSRC) X $(CC) $(SLINK) -o $(CDKSLIB).0 $(CDKOBJS) X # Install the library and realted files. install: X @$(MAKE) instman X @$(MAKE) instsrc X @$(MAKE) instlib X @echo "Installation done."; X # Install the manual pages. instman: X @echo "Installing manual pages..."; X @mkdir -p $(INST_MANDIR); X @(cd $(MANDIR); for i in $(CDKMAN); do \ X echo " $(INST_MANDIR)/cdk_$${i}"; \ X rm -f $(INST_MANDIR)/cdk_$${i}; \ X cp $$i $(INST_MANDIR)/cdk_$${i}; \ X done) X # Install the source and release documents. instsrc: X @if [ ! -d $(INST_SRCDIR)/cdk ]; then \ X echo "Making directory $(INST_SRCDIR)/cdk ... "; \ X mkdir -p $(INST_SRCDIR)/cdk; \ X fi; X @echo "Installing source example files..."; X @(cd $(EXAMDIR); for i in $(CDKEXAMSRC); do \ X echo " $(INST_SRCDIR)/cdk/$$i" ; \ X rm -f $(INST_SRCDIR)/cdk/$$i; \ X cp $$i $(INST_SRCDIR)/cdk/$$i; \ X done) X @echo "Installing release documents..."; X @for i in $(CDKDOCS) ; do \ X echo " $(INST_SRCDIR)/cdk/$$i"; \ X rm -f $(INST_SRCDIR)/cdk/$$i; \ X cp $$i $(INST_SRCDIR)/cdk/$$i; \ X done X # Install the libraries and header files. instlib: X @echo "Installing Cdk library files..."; X @if [ -f $(CDKLIB) ] ; then \ X echo " $(INST_LIBDIR)/$(CDKLIB)"; \ X cp $(CDKLIB) $(INST_LIBDIR)/$(CDKLIB); \ X fi X @if [ -f $(CDKSLIB) ] ; then \ X echo " $(INST_LIBDIR)/$(CDKSLIB).0"; \ X cp $(CDKSLIB).0 $(INST_LIBDIR)/$(CDKSLIB).0; \ X fi X @mkdir -p $(INST_INCDIR); X @echo " $(INST_INCDIR)/cdk.h"; X @rm -f $(INST_INCDIR)/cdk.h X @cp cdk.h $(INST_INCDIR) X @echo " $(INST_INCDIR)/curdefs.h"; X @rm -f $(INST_INCDIR)/curdefs.h X @cp curdefs.h $(INST_INCDIR) X examples: X @(cd $(EXAMDIR); \ X make -f Makefile.examples CFLAGS="$(CFLAGS)" CDKEXAMBIN="$(CDKEXAMBIN)" \ X INCPATH="$(INCPATH)" CC="$(CC)" LIBPATH="$(LIBPATH)" LINKLIB="$(LINKLIB)") X cleanexam: X @(cd $(EXAMDIR); make CDKEXAMBIN="$(CDKEXAMBIN)" -f Makefile.examples clean) X demos: X @(cd $(DEMODIR); \ X make -f Makefile.demos CFLAGS="$(CFLAGS)" CDKDEMOBIN="$(CDKDEMOBIN)" \ X INCPATH="$(INCPATH)" CC="$(CC)" LIBPATH="$(LIBPATH)" LINKLIB="$(LINKLIB)") X cleandemo: X @(cd $(DEMODIR); make CDKDEMOBIN="$(CDKDEMOBIN)" -f Makefile.demos clean) X clean: X rm -f *.o core tst stst $(CDKLIB) $(CDKSLIB).0 X @$(MAKE) cleanexam X @$(MAKE) cleandemo X update: X @co $(CDKSRC) $(CDKHDR) $(CDKDOCS) X @(cd $(EXAMDIR); co $(CDKEXAMSRC)) X @(cd $(DEMODIR); co $(CDKDEMOSRC) $(CDKDEMOHDR)) X @(cd man; co $(CDKMAN)) X release: X @$(MAKE) update X @rm -rf $(RELDIR) $(RELDIR).tgz X @mkdir $(RELDIR) X @mkdir $(RELDIR)/exam X @mkdir $(RELDIR)/demo X @mkdir $(RELDIR)/man X @for i in $(CDKSRC) $(CDKDOCS) $(CDKHDR); do \ X cp $$i $(RELDIR); \ X done X @for i in $(CDKMAN); do \ X cp $(MANDIR)/$$i $(RELDIR)/man ; \ X done X @for i in $(CDKEXAMSRC); do \ X cp $(EXAMDIR)/$$i $(RELDIR)/exam ; \ X done X @for i in $(CDKDEMOSRC); do \ X cp $(DEMODIR)/$$i $(RELDIR)/demo ; \ X done X @for i in $(CDKDEMOHDR); do \ X cp $(DEMODIR)/$$i $(RELDIR)/demo ; \ X done X @chmod +w Makefile X @cp Makefile $(RELDIR) X @cp $(EXAMDIR)/Makefile.examples $(RELDIR)/exam; X @cp $(DEMODIR)/Makefile.demos $(RELDIR)/demo; X @tar cvf $(RELDIR).tar $(RELDIR) X @gzip $(RELDIR).tar X @mv $(RELDIR).tar.gz $(RELDIR).tgz X @rm -rf $(RELDIR) SHAR_EOF $shar_touch -am 0503191196 'Makefile' && chmod 0644 'Makefile' || echo 'restore of Makefile failed' shar_count="`wc -c < 'Makefile'`" test 6333 -eq "$shar_count" || echo "Makefile: original size 6333, current size $shar_count" rm -f _sharnew.tmp fi # ============= NOTES ============== if test -f 'NOTES' && test X"$1" != X"-c"; then echo 'x - skipping NOTES (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting NOTES (text)' sed 's/^X//' << 'SHAR_EOF' > 'NOTES' && Cdk Notes Copyright Mike Glover, 1995 ------------------------------------------------------------------------------- X This document states some of the testing and history of the Cdk widget set. X Cdk has gone through a major facelift since I first created it, and it's current look I like enough to release and attach my name to. :) I have made sure to remain as consistent as possible with function parameter positions, names, purposes, and what-not. I hope I have been, if not mail me tell me what you find inconsistent and I may change it. I say may because I don't want to kill anyone's code if I can help it. That is why I waited so long before releasing Cdk. I wanted it to be as stable as possible before sending it out into the world. I think it's stable, and hopefully so will you. There are a few things worth noting before continuing. X Cdk has gone through some fairly rigorous testing, but since I did the testing it may not be complete. I have complied the code with Purify (TM) and Centerline's Testcenter (TM) and both say my code is clean. There are no memory leaks, and the only problems exist in the curses library. If you use the Ncurses library, it has been cleaned. Of course I am not the best to ask. The only reason why I can say this is because I asked the Ncurses author. I don't know how clean it is. I will assume very clean. X But since I may not be able to see the forest for the trees, I'm willing to bet that bugs still do exist, and you folks will find them. If you do find bugs read the BUGS document supplied with this release to find out what to do. X I do not plan on changing the interface to Cdk, so any code developed in it now should pass the test of time. The only changes I can see are bug fixes and new widgets. Lets hope this wish of mine remains true... X There is an examples directory available which demonstrates all of the widgets and some extra concepts, it's a great place to tool around in before banging away at your own code. X Have fun. :) X ttfn, X Mike X PS: If you want to get a hold of me mail me at glover@tuzo.erin.utoronto.ca I would like to know your opinions of this library and how I could make it better. SHAR_EOF $shar_touch -am 0503190996 'NOTES' && chmod 0444 'NOTES' || echo 'restore of NOTES failed' shar_count="`wc -c < 'NOTES'`" test 2167 -eq "$shar_count" || echo "NOTES: original size 2167, current size $shar_count" rm -f _sharnew.tmp fi # ============= README ============== if test -f 'README' && test X"$1" != X"-c"; then echo 'x - skipping README (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting README (text)' sed 's/^X//' << 'SHAR_EOF' > 'README' && Cdk Readme Guide Copyright Mike Glover, 1995 ------------------------------------------------------------------------------- X Overview: --------- Cdk stands for 'Curses Development Kit' and it currently contains 17 ready to use widgets which facilitate the speedy development of full screen curses programs. This little project of mine started as a test to see how compatible my Linux machine was to other UNIX breeds. While doing this I discovered Ncurses, and played with it. These widgets are the result of a years worth of playing. The current complement of widgets are: X Widget Type Quick Description =========================================================================== Dialog Prompts the user with a message, and the user X can pick an answer from the buttons provided. Entry Allows the user to enter information. File Selector A file selector built from Cdk base widgets. This X example shows how to create more complicated widgets X using the Cdk widget library. Graph Draws a graph. Histogram Draws a histogram. Item List Creates a pop up field which allows the user to select X one of several choices in a small field. Very useful X for things like days of the week or month names. Label Displays messages in a pop up box, or the label can be X considered part of the screen. Marquee Displays a message in a scrolling marquee. Matrix Creates a complex matrix with lots of options. Menu Creates a pull-down menu interface. Multiple Line Entry A multiple line entry field. Very useful X for long fields. (like a description X field) Radio List Creates a radio button list. Scale Creates a numeric scale. Used for allowing a user to X pick a numeric value and restrict them to a range of X values. Scrolling List Creates a scrolling list/menu list. Scrolling Window Creates a scrolling log file viewer. Can add X information into the window while its running. X A good widget for displaying the progress of X something. (akin to a console window) Selection List Creates a multiple option selection list. Template Creates a entry field with character sensitive X positions. Used for pre-formatted fields like X dates and phone numbers. Viewer This is a file/information viewer. Very useful X when you need to display loads of information. =========================================================================== X Each widget has the ability to display color, or other character attributes. Cdk comes with a attribute/color format command set which allows a programmer to add colors and characters attributes simply. X The code has been cleaned using both Purify(TM) and Sun's Testcenter(TM), so it is as clean as a babies butt. :) Any leaks I have seen are in the curses libraries; there is nothing I can do about that, sorry. There are no memory leaks within the code, it shouldn't core dump, and it shouldn't do anything unexpected. If you do see something like this tell me after you read the BUGS file. X Distribution: ------------- This distribution has a full complement of manual pages, so any specifics to the widgets will not be addressed in this read me. If you want to get right in there, nroff the cdk.3x file in the man directory. It is the starting point for all the manual pages. X There are some other files to look at if you want to get anywhere. They are: X INSTALL - This will show you how to build Cdk and install it on your system. X If there are any personal modifications that you think may be X needed, read this file. In fact read it regardless. :) X COPYING - The legal stuff to protect my butt and all of the hard work that I X have put into this library. X EXPANDING - You feel creative enough to add a widget, here are my requirements X that you have to follow to make the integration of a new widget X seamless. X BUGS - What to do when you find a bug. It also lists all of the bugs found, X who found then, who fixed them, and when they were fixed. If you think X you have found a bug look at this file. If you do not think you have X the most up to date version of Cdk, go get it and try to replicate the X problem. Then look at the BUGS file again. If it is NOT there, then you X can mail me notifying me of a possible bug. I will try my hardest to get X back to you, but I have a pretty busy schedule so don't expect an instant X reply. This file will also explain how I would like any bug fixes sent to X me. X NOTES - Misc babblings of myself somewhat related to this distribution. X VERSION - Contains the current rev level, when it was released, and X what is different from the previous release. (I promise X to make sure I keep this up to date. :) ) X TODO - A list of things I plan to do in the future. (sleep) X CHANGES - A list of changes from one release to another. X If you have any comments, questions, or complaints mail me at glover@tuzo.erin.utoronto.ca X ttfn, X Mike X PS: There is also a Perl5 extension of this library for you Perl5 fans. SHAR_EOF $shar_touch -am 0503190996 'README' && chmod 0444 'README' || echo 'restore of README failed' shar_count="`wc -c < 'README'`" test 5546 -eq "$shar_count" || echo "README: original size 5546, current size $shar_count" rm -f _sharnew.tmp fi # ============= TODO ============== if test -f 'TODO' && test X"$1" != X"-c"; then echo 'x - skipping TODO (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting TODO (text)' sed 's/^X//' << 'SHAR_EOF' > 'TODO' && Cdk To-Do List Copyright Mike Glover, 1995 ------------------------------------------------------------------------------ X There are a few things that I am either currently working on, or going to work on in the near future. They are: X X * Add more functions to the drawing routines. X * I would like to be able to have a captive shell widget. This X would allow you to start a subshell and have the user interact X with a spawned command via the captive shell. This would allow X you to spawn an interactive command through the widget. If any X one knows how to do this, please mail me. Maybe we'll work this X through. X * I am thinking about adding an X windows element to Cdk using X the Xforms library, because it seems to have roughly the same X widgets as I do. The plan is to have a simple environment variable X which tells the program what you want curses/X windows. We'll X see how this goes. X ttfn, X Mike SHAR_EOF $shar_touch -am 0503190996 'TODO' && chmod 0444 'TODO' || echo 'restore of TODO failed' shar_count="`wc -c < 'TODO'`" test 908 -eq "$shar_count" || echo "TODO: original size 908, current size $shar_count" rm -f _sharnew.tmp fi # ============= VERSION ============== if test -f 'VERSION' && test X"$1" != X"-c"; then echo 'x - skipping VERSION (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting VERSION (text)' sed 's/^X//' << 'SHAR_EOF' > 'VERSION' && Cdk Version Guide Copyright Mike Glover, 1995 ------------------------------------------------------------------------------- X Current Version: 4.6.1 X Version # Release Date ========= ============ 4.6.0 December, 1995 4.6.1 January, 1996. (Sent to comp.unix.sources moderator, but X never seemed to get posted.) :( 4.7.0 May, 1996. (lets hope this one gets posted.) SHAR_EOF $shar_touch -am 0503190996 'VERSION' && chmod 0444 'VERSION' || echo 'restore of VERSION failed' shar_count="`wc -c < 'VERSION'`" test 369 -eq "$shar_count" || echo "VERSION: original size 369, current size $shar_count" rm -f _sharnew.tmp fi # ============= binding.c ============== if test -f 'binding.c' && test X"$1" != X"-c"; then echo 'x - skipping binding.c (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting binding.c (text)' sed 's/^X//' << 'SHAR_EOF' > 'binding.c' && #include "cdk.h" X /* X * $Author: mikeg $ X * $Date: 1996/02/28 14:59:06 $ X * $Revision: 1.17 $ X */ X /* X * This inserts a binding. X */ void bindCDKObject (EObjectType cdktype, void *object, chtype key, BINDFN function, void * data) { X int index = mapChtype (key); X X /* Since dereferencing a void pointer is a no-no, we have to cast */ X /* our pointer correctly. */ X if (cdktype == vENTRY) X { X ((CDKENTRY *)object)->bindFunction[index] = function; X ((CDKENTRY *)object)->bindData[index] = data; X } X else if (cdktype == vMENTRY) X { X ((CDKMENTRY *)object)->bindFunction[index] = function; X ((CDKMENTRY *)object)->bindData[index] = data; X } X else if (cdktype == vSCROLL) X { X ((CDKSCROLL *)object)->bindFunction[index] = function; X ((CDKSCROLL *)object)->bindData[index] = data; X } X else if (cdktype == vDIALOG) X { X ((CDKDIALOG *)object)->bindFunction[index] = function; X ((CDKDIALOG *)object)->bindData[index] = data; X } X else if (cdktype == vSCALE) X { X ((CDKSCALE *)object)->bindFunction[index] = function; X ((CDKSCALE *)object)->bindData[index] = data; X } X else if (cdktype == vMENU) X { X ((CDKMENU *)object)->bindFunction[index] = function; X ((CDKMENU *)object)->bindData[index] = data; X } X else if (cdktype == vMATRIX) X { X ((CDKMATRIX *)object)->bindFunction[index] = function; X ((CDKMATRIX *)object)->bindData[index] = data; X } X else if (cdktype == vSELECTION) X { X ((CDKSELECTION *)object)->bindFunction[index] = function; X ((CDKSELECTION *)object)->bindData[index] = data; X } X else if (cdktype == vVIEWER) X { X ((CDKVIEWER *)object)->bindFunction[index] = function; X ((CDKVIEWER *)object)->bindData[index] = data; X } X else if (cdktype == vRADIO) X { X ((CDKRADIO *)object)->bindFunction[index] = function; X ((CDKRADIO *)object)->bindData[index] = data; X } X else if (cdktype == vTEMPLATE) X { X ((CDKTEMPLATE *)object)->bindFunction[index] = function; X ((CDKTEMPLATE *)object)->bindData[index] = data; X } X else if (cdktype == vSWINDOW) X { X ((CDKSWINDOW *)object)->bindFunction[index] = function; X ((CDKSWINDOW *)object)->bindData[index] = data; X } X else if (cdktype == vITEMLIST) X { X ((CDKITEMLIST *)object)->bindFunction[index] = function; X ((CDKITEMLIST *)object)->bindData[index] = data; X } X else if (cdktype == vFSELECT) X { X bindCDKObject (vENTRY, ((CDKFSELECT *)object)->filename, key, function, data); X bindCDKObject (vSCROLL, ((CDKFSELECT *)object)->fileList, key, function, data); X } } X /* X * This removes a binding on an object. X */ void unbindCDKObject (EObjectType cdktype, void *object, chtype key) { X int index = mapChtype(key); X X /* Since dereferencing a void pointer is a no-no, we have to cast */ X /* our pointer correctly. */ X if (cdktype == vENTRY) X { X ((CDKENTRY *)object)->bindFunction[index] = (BINDFN)NULL; X ((CDKENTRY *)object)->bindData[index] = (void *)NULL; X } X else if (cdktype == vMENTRY) X { X ((CDKMENTRY *)object)->bindFunction[index] = (BINDFN)NULL; X ((CDKMENTRY *)object)->bindData[index] = (void *)NULL; X } X else if (cdktype == vSCROLL) X { X ((CDKSCROLL *)object)->bindFunction[index] = (BINDFN)NULL; X ((CDKSCROLL *)object)->bindData[index] = (void *)NULL; X } X else if (cdktype == vDIALOG) X { X ((CDKDIALOG *)object)->bindFunction[index] = (BINDFN)NULL; X ((CDKDIALOG *)object)->bindData[index] = (void *)NULL; X } X else if (cdktype == vSCALE) X { X ((CDKSCALE *)object)->bindFunction[index] = (BINDFN)NULL; X ((CDKSCALE *)object)->bindData[index] = (void *)NULL; X } X else if (cdktype == vMENU) X { X ((CDKMENU *)object)->bindFunction[index] = (BINDFN)NULL; X ((CDKMENU *)object)->bindData[index] = (void *)NULL; X } X else if (cdktype == vMATRIX) X { X ((CDKMATRIX *)object)->bindFunction[index] = (BINDFN)NULL; X ((CDKMATRIX *)object)->bindData[index] = (void *)NULL; X } X else if (cdktype == vSELECTION) X { X ((CDKSELECTION *)object)->bindFunction[index] = (BINDFN)NULL; X ((CDKSELECTION *)object)->bindData[index] = (void *)NULL; X } X else if (cdktype == vVIEWER) X { X ((CDKVIEWER *)object)->bindFunction[index] = (BINDFN)NULL; X ((CDKVIEWER *)object)->bindData[index] = (void *)NULL; X } X else if (cdktype == vRADIO) X { X ((CDKRADIO *)object)->bindFunction[index] = (BINDFN)NULL; X ((CDKRADIO *)object)->bindData[index] = (void *)NULL; X } X else if (cdktype == vTEMPLATE) X { X ((CDKTEMPLATE *)object)->bindFunction[index] = (BINDFN)NULL; X ((CDKTEMPLATE *)object)->bindData[index] = (void *)NULL; X } X else if (cdktype == vSWINDOW) X { X ((CDKSWINDOW *)object)->bindFunction[index] = (BINDFN)NULL; X ((CDKSWINDOW *)object)->bindData[index] = (void *)NULL; X } X else if (cdktype == vITEMLIST) X { X ((CDKITEMLIST *)object)->bindFunction[index] = (BINDFN)NULL; X ((CDKITEMLIST *)object)->bindData[index] = (void *)NULL; X } X else if (cdktype == vFSELECT) X { X unbindCDKObject (vENTRY, ((CDKFSELECT *)object)->filename, key); X unbindCDKObject (vSCROLL, ((CDKFSELECT *)object)->fileList, key); X } } X /* X * This sets all the bindings for the given objects. X */ void cleanCDKObjectBindings (EObjectType cdktype, void *object) { X /* Since dereferencing a void pointer is a no-no, we have to cast */ X /* our pointer correctly. */ X if (cdktype == vENTRY) X { X int x; X for (x=0; x < MAXBINDINGS; x++) X { X ((CDKENTRY *)object)->bindFunction[x] = (BINDFN)NULL; X ((CDKENTRY *)object)->bindData[x] = (void *)NULL; X } X } X else if (cdktype == vMENTRY) X { X int x; X for (x=0; x < MAXBINDINGS; x++) X { X ((CDKMENTRY *)object)->bindFunction[x] = (BINDFN)NULL; X ((CDKMENTRY *)object)->bindData[x] = (void *)NULL; X } X } X else if (cdktype == vSCROLL) X { X int x; X for (x=0; x < MAXBINDINGS; x++) X { X ((CDKSCROLL *)object)->bindFunction[x] = (BINDFN)NULL; X ((CDKSCROLL *)object)->bindData[x] = (void *)NULL; X } X } X else if (cdktype == vDIALOG) X { X int x; X for (x=0; x < MAXBINDINGS; x++) X { X ((CDKDIALOG *)object)->bindFunction[x] = (BINDFN)NULL; X ((CDKDIALOG *)object)->bindData[x] = (void *)NULL; X } X } X else if (cdktype == vSCALE) X { X int x; X for (x=0; x < MAXBINDINGS; x++) X { X ((CDKSCALE *)object)->bindFunction[x] = (BINDFN)NULL; X ((CDKSCALE *)object)->bindData[x] = (void *)NULL; X } X } X else if (cdktype == vMENU) X { X int x; X for (x=0; x < MAXBINDINGS; x++) X { X ((CDKMENU *)object)->bindFunction[x] = (BINDFN)NULL; X ((CDKMENU *)object)->bindData[x] = (void *)NULL; X } X } X else if (cdktype == vMATRIX) X { X int x; X for (x=0; x < MAXBINDINGS; x++) X { X ((CDKMATRIX *)object)->bindFunction[x] = (BINDFN)NULL; X ((CDKMATRIX *)object)->bindData[x] = (void *)NULL; X } X } X else if (cdktype == vSELECTION) X { X int x; X for (x=0; x < MAXBINDINGS; x++) X { X ((CDKSELECTION *)object)->bindFunction[x] = (BINDFN)NULL; X ((CDKSELECTION *)object)->bindData[x] = (void *)NULL; X } X } X else if (cdktype == vVIEWER) X { X int x; X for (x=0; x < MAXBINDINGS; x++) X { X ((CDKVIEWER *)object)->bindFunction[x] = (BINDFN)NULL; X ((CDKVIEWER *)object)->bindData[x] = (void *)NULL; X } X } X else if (cdktype == vRADIO) X { X int x; X for (x=0; x < MAXBINDINGS; x++) X { X ((CDKRADIO *)object)->bindFunction[x] = (BINDFN)NULL; X ((CDKRADIO *)object)->bindData[x] = (void *)NULL; X } X } X else if (cdktype == vTEMPLATE) X { X int x; X for (x=0; x < MAXBINDINGS; x++) X { X ((CDKTEMPLATE *)object)->bindFunction[x] = (BINDFN)NULL; X ((CDKTEMPLATE *)object)->bindData[x] = (void *)NULL; X } X } X else if (cdktype == vSWINDOW) X { X int x; X for (x=0; x < MAXBINDINGS; x++) X { X ((CDKSWINDOW *)object)->bindFunction[x] = (BINDFN)NULL; X ((CDKSWINDOW *)object)->bindData[x] = (void *)NULL; X } X } X else if (cdktype == vITEMLIST) X { X int x; X for (x=0; x < MAXBINDINGS; x++) X { X ((CDKITEMLIST *)object)->bindFunction[x] = (BINDFN)NULL; X ((CDKITEMLIST *)object)->bindData[x] = (void *)NULL; X } X } X else if (cdktype == vFSELECT) X { X cleanCDKObjectBindings (vENTRY, ((CDKFSELECT *)object)->filename); X cleanCDKObjectBindings (vSCROLL, ((CDKFSELECT *)object)->fileList); X } } X /* X * This checks to see iof the binding for the key exists. If it does then it X * runs the command and returns a TRUE. If it doesn't it returns a FALSE. This X * way we can 'overwrite' coded in bindings. X */ int checkCDKObjectBind (EObjectType cdktype, void *object, chtype key) { X int index = mapChtype (key); X X /* Since dereferencing a void pointer is a no-no, we have to cast */ X /* our pointer correctly. */ X if (cdktype == vENTRY) X { X if ( ((CDKENTRY *)object)->bindFunction[index] != (BINDFN) NULL ) X { X BINDFN function = (BINDFN) ((CDKENTRY *)object)->bindFunction[index]; X void * data = (void *) ((CDKENTRY *)object)->bindData[index]; X function (vENTRY, object, data); X return (TRUE); X } X } X else if (cdktype == vMENTRY) X { X if ( ((CDKMENTRY *)object)->bindFunction[index] != (BINDFN) NULL ) X { X BINDFN function = ((CDKMENTRY *)object)->bindFunction[index]; X void * data = ((CDKMENTRY *)object)->bindData[index]; X function (vMENTRY, object, data); X return (TRUE); X } X } X else if (cdktype == vSCROLL) X { X if ( ((CDKSCROLL *)object)->bindFunction[index] != (BINDFN) NULL ) X { X BINDFN function = ((CDKSCROLL *)object)->bindFunction[index]; X void * data = ((CDKSCROLL *)object)->bindData[index]; X function (vSCROLL, object, data); X return (TRUE); X } X } X else if (cdktype == vDIALOG) X { X if ( ((CDKDIALOG *)object)->bindFunction[index] != (BINDFN) NULL ) X { X BINDFN function = ((CDKDIALOG *)object)->bindFunction[index]; X void * data = ((CDKDIALOG *)object)->bindData[index]; X function (vDIALOG, object, data); X return (TRUE); X } X } X else if (cdktype == vSCALE) X { X if ( ((CDKSCALE *)object)->bindFunction[index] != (BINDFN) NULL ) X { X BINDFN function = ((CDKSCALE *)object)->bindFunction[index]; X void * data = ((CDKSCALE *)object)->bindData[index]; X function (vSCALE, object, data); X return (TRUE); X } X } X else if (cdktype == vMENU) X { X if ( ((CDKMENU *)object)->bindFunction[index] != (BINDFN) NULL ) X { X BINDFN function = ((CDKMENU *)object)->bindFunction[index]; X void * data = ((CDKMENU *)object)->bindData[index]; X function (vMENU, object, data); X return (TRUE); X } X } X else if (cdktype == vMATRIX) X { X if ( ((CDKMATRIX *)object)->bindFunction[index] != (BINDFN) NULL ) X { X BINDFN function = ((CDKMATRIX *)object)->bindFunction[index]; X void * data = ((CDKMATRIX *)object)->bindData[index]; X function (vMATRIX, object, data); X return (TRUE); X } X } X else if (cdktype == vSELECTION) X { X if ( ((CDKSELECTION *)object)->bindFunction[index] != (BINDFN) NULL ) X { X BINDFN function = ((CDKSELECTION *)object)->bindFunction[index]; X void * data = ((CDKSELECTION *)object)->bindData[index]; X function (vSELECTION, object, data); X return (TRUE); X } X } X else if (cdktype == vVIEWER) X { X if ( ((CDKVIEWER *)object)->bindFunction[index] != (BINDFN) NULL ) X { X BINDFN function = ((CDKVIEWER *)object)->bindFunction[index]; X void * data = ((CDKVIEWER *)object)->bindData[index]; X function (vVIEWER, object, data); X return (TRUE); X } X } X else if (cdktype == vRADIO) X { X if ( ((CDKRADIO *)object)->bindFunction[index] != (BINDFN) NULL ) X { X BINDFN function = ((CDKRADIO *)object)->bindFunction[index]; X void * data = ((CDKRADIO *)object)->bindData[index]; X function (vRADIO, object, data); X return (TRUE); X } X } X else if (cdktype == vTEMPLATE) X { X if ( ((CDKTEMPLATE *)object)->bindFunction[index] != (BINDFN) NULL ) X { X BINDFN function = ((CDKTEMPLATE *)object)->bindFunction[index]; X void * data = ((CDKTEMPLATE *)object)->bindData[index]; X function (vTEMPLATE, object, data); X return (TRUE); X } X } X else if (cdktype == vSWINDOW) X { X if ( ((CDKSWINDOW *)object)->bindFunction[index] != (BINDFN) NULL ) X { X BINDFN function = ((CDKSWINDOW *)object)->bindFunction[index]; X void * data = ((CDKSWINDOW *)object)->bindData[index]; X function (vSWINDOW, object, data); X return (TRUE); X } X } X else if (cdktype == vITEMLIST) X { X if ( ((CDKITEMLIST *)object)->bindFunction[index] != (BINDFN) NULL ) X { X BINDFN function = ((CDKITEMLIST *)object)->bindFunction[index]; X void * data = ((CDKITEMLIST *)object)->bindData[index]; X function (vITEMLIST, object, data); X return (TRUE); X } X } X return (FALSE); } X /* X * This translates non ascii characters like KEY_UP to an 'equivalent' X * ascii value. X */ int mapChtype (chtype key) { X if (key == KEY_UP) X { X return (257); X } X else if (key == KEY_DOWN) X { X return (258); X } X else if (key == KEY_LEFT) X { X return (259); X } X else if (key == KEY_RIGHT) X { X return (260); X } X else if (key == KEY_NPAGE) X { X return (261); X } X else if (key == KEY_PPAGE) X { X return (262); X } X else if (key == KEY_HOME) X { X return (263); X } X else if (key == KEY_END) X { X return (264); X } X else if (key == KEY_F0) X { X return (265); X } X else if (key == KEY_F1) X { X return (266); X } X else if (key == KEY_F2) X { X return (267); X } X else if (key == KEY_F3) X { X return (268); X } X else if (key == KEY_F4) X { X return (269); X } X else if (key == KEY_F5) X { X return (270); X } X else if (key == KEY_F6) X { X return (271); X } X else if (key == KEY_F7) X { X return (272); X } X else if (key == KEY_A1) X { X return (273); X } X else if (key == KEY_A3) X { X return (274); X } X else if (key == KEY_B2) X { X return (275); X } X else if (key == KEY_C1) X { X return (276); X } X else if (key == KEY_C3) X { X return (277); X } X else if (key == KEY_ESC) X { X return (278); X } X else X { X return ( (char) key ); X } } SHAR_EOF $shar_touch -am 0503190896 'binding.c' && chmod 0444 'binding.c' || echo 'restore of binding.c failed' shar_count="`wc -c < 'binding.c'`" test 15039 -eq "$shar_count" || echo "binding.c: original size 15039, current size $shar_count" rm -f _sharnew.tmp fi # ============= cdk.c ============== if test -f 'cdk.c' && test X"$1" != X"-c"; then echo 'x - skipping cdk.c (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting cdk.c (text)' sed 's/^X//' << 'SHAR_EOF' > 'cdk.c' && #include "cdk.h" X /* X * $Author: glover $ X * $Date: 1996/04/21 04:47:06 $ X * $Revision: 1.105 $ X */ X /* X * As much as I hate to do this, I need to define a global char * pointer. X * This is for the injectCDKXXX routines which return a char * type. Since X * returning a NULL pointer is acceptable, this is the only other solution. X */ char *GCdkObjects[] = {"ENTRY", "MENTRY", "LABEL", "SCROLL", "DIALOG", \ X "SCALE", "MARQUEE", "MENU", "MATRIX", "HISTOGRAM", \ X "SELECTION", "VIEWER", "GRAPH", "RADIO", "TEMPLATE", \ X "SWINDOW", "ITEMLIST", "FSELECT"}; char *GPasteBuffer = (char *)NULL; char *GEarlyExit = "ThE_uSeR_HaS_N0T_FiNiShEd_eDiTiNg_tHiS_WiDgEt_yEt_!!"; char *GEscapeHit = "ThE_uSeR_JuSt_HiT_ThE_EsCaPe_KeY.ThEy_WaNt_To_LeAvE!"; X /* This beeps then flushes the stdout stream. */ void Beep() { X beep(); X fflush (stdout); } X /* This is my 'own' version of bzero. */ void cleanChar (char *s, int len, char character) { X int x; X for (x=0; x < len; x++) X { X s[x] = character; X } X s[--x] = '\0'; } void cleanChtype (chtype *s, int len, chtype character) { X int x; X for (x=0; x < len; x++) X { X s[x] = character; X } X s[--x] = '\0'; } X /* X * This takes an x and y position and realigns the values iff they sent in X * values like CENTER, LEFT, RIGHT, ... X */ void alignxy (WINDOW *window, int *xpos, int *ypos, int boxwidth, int boxheight) { X /* Justify the X position, if we need to. */ X if ((*xpos) == LEFT) X { X (*xpos) = window->_begy + 1; X } X else if ((*xpos) == RIGHT) X { X (*xpos) = (window->_maxx - boxwidth) + window->_begy - 1; X } X else if ((*xpos) == CENTER) X { X (*xpos) = (int)(((window->_maxx)-boxwidth) / 2) + window->_begy; X } X else X { X /* If we have gone out of bounds, then readjust. */ X if (((*xpos) + boxwidth) > window->_maxx) X { X (*xpos) = (window->_maxx - boxwidth); X } X else if ((*xpos) < 0) X { X (*xpos) = window->_begy + 1; X } X } X X /* Justify the Y position, if we need to. */ X if ((*ypos) == TOP) X { X (*ypos) = window->_begx + 1; X } X else if ((*ypos) == BOTTOM) X { X (*ypos) = (window->_maxy) - boxheight + window->_begx - 1; X } X else if ((*ypos) == CENTER) X { X (*ypos) = (int)((window->_maxy - boxheight) / 2) + window->_begx; X } X else X { X /* If we have gone out of bounds, then readjust */ X if (((*ypos) + boxheight) > window->_maxy) X { X (*ypos) = (window->_maxy - boxheight); X } X else if ((*ypos) < 0) X { X (*ypos) = window->_begx + 1; X } X } } X /* X * This creates the x and y offset values given the location and size of the X * given label for the object. X */ void alignlabel (char *label, int lplace, int fieldwidth, int *boxwidth, int *boxheight, int *labelxoffset, int *labelyoffset, int *fieldxoffset, int *fieldyoffset) { X /* Declare local variables. */ X int labelLength = strlen (label); X X /* Set the offset values. */ X if (lplace == LEFT) X { X (*boxwidth) = fieldwidth + labelLength + 3; X (*labelxoffset) = 1; X (*labelyoffset) = 1; X (*fieldxoffset) = labelLength + 2; X (*fieldyoffset) = 1; X } X else if (lplace == RIGHT) X { X (*boxwidth) = fieldwidth + labelLength + 3; X (*labelxoffset) = ((*boxwidth) - labelLength - 1); X (*labelyoffset) = 1; X (*fieldxoffset) = 1; X (*fieldyoffset) = 1; X } X else if (lplace == TOP) X { X (*boxwidth) = (fieldwidth < labelLength ? labelLength : fieldwidth); X (*boxwidth) += 3; X (*boxheight) = (*boxheight) + 1; X (*labelxoffset) = (int) (((*boxwidth)-labelLength)/2); X (*labelyoffset) = 1; X (*fieldyoffset) = 2; X (*fieldxoffset) = 1; X } X else if (lplace == BOTTOM) X { X (*boxwidth) = (fieldwidth < labelLength ? labelLength : fieldwidth) + 3; X (*boxheight) = (*boxheight) + 1; X (*labelxoffset) = (int) (((*boxwidth)-labelLength)/2); X (*labelyoffset) = (*boxheight)-2; X (*fieldxoffset) = 1; X (*fieldyoffset) = 1; X } X else X { X /* X * Give me something I don't understand and I X * will choose a default for you ie: LEFT X */ X (*boxwidth) = fieldwidth + labelLength + 3; X (*labelxoffset) = 1; X (*labelyoffset) = 1; X (*fieldxoffset) = labelLength + 2; X (*fieldyoffset) = 1; X } } X /* X * This takes a string, a field width and a justifycation type X * and returns the justifcation adjustment to make, to fill X * the justification requirement. X */ int justifyMessage (int width, char *mesg, int justify) { X int mesglen = strlen (mesg); X X /* Make sure the message isn't longer than the width. */ X /* If it is, return 0. */ X if (mesglen >= width) X { X return (0); X } X X /* Try to justify the message. */ X if (justify == LEFT) X { X return (1); X } X else if (justify == RIGHT) X { X return ((width - mesglen)); X } X else if (justify == CENTER) X { X return ((int)((width - mesglen) / 2)); X } X else X { X return (justify); X } } int justifyString (int boxWidth, int mesgLength, int justify) { X /* Make sure the message isn't longer than the width. */ X /* If it is, return 1. */ X if (mesgLength >= boxWidth) X { X return (1); X } X X /* Try to justify the message. */ X if (justify == LEFT) X { X return (1); X } X else if (justify == RIGHT) X { X return ((boxWidth - mesgLength - 1)); X } X else if (justify == CENTER) X { X return ((int)((boxWidth - mesgLength) / 2)); X } X else X { X return (justify); X } } X /* X * This returns a substring of the given string. X */ char *substring(char *string, int start, int width) { X char *newstring = (char *)NULL; X int mesglen = (strlen (string)); X int y = 0; X int x = 0; X int lastchar = 0; X X if (start > mesglen) X { X return (newstring); X } X X newstring = (char *)malloc (sizeof (char) * (width+3)); X cleanChar (newstring, width+3, '\0'); X if ((start+width) > mesglen) X { X lastchar = mesglen; X } X else X { X lastchar = width + start; X } X X for (x=start; x<=lastchar; x++) X { X newstring[y++] = string[x]; X } X return (newstring); } X /* X * This frees a string if it is not null. This is a safety X * measure. Some compilers let you free a null string. I X * don't like that idea. X */ void freeChar (char *string) { X if (string != (char *)NULL) X { X free (string); X } } void freeChtype (chtype *string) { X if (string != (chtype *)NULL) X { X free (string); X } } X /* X * This performs a safe copy of a string. This means it adds the NULL X * terminator on the end of the string. X */ char *copyChar (char *original) { X /* Declare local variables. */ X char *newstring; X int len; X X /* Make sure the string is not NULL. */ X if (original == (char *)NULL) X { X return (char *)NULL; X } X X /* Create the new string. */ X len = strlen (original); X newstring = (char *)malloc (sizeof(char) * (len+3)); X cleanChar (newstring, len+3, '\0'); X X /* Copy from one to the other... */ X strcpy (newstring, original); X X /* Return the new string. */ X return (newstring); } chtype *copyChtype (chtype *original) { X /* Declare local variables. */ X chtype *newstring; X int len, x; X X /* Make sure the string is not NULL. */ X if (original == (chtype *)NULL) X { X return (chtype *)NULL; X } X X /* Create the new string. */ X len = chlen (original); X newstring = (chtype *)malloc (sizeof(chtype) * (len+4)); X cleanChtype (newstring, len+3, '\0'); X X /* Copy from one to the other... */ X for (x=0; x < len; x++) X { X newstring[x] = original[x]; X } X X /* Return the new string. */ X return (newstring); } X X /* X * This draws a line in a scrolling list or a selection list. X */ void drawScrollItem (WINDOW *win, char *item, int woffset, int hoffset, int voffset, int width, chtype attr) { X char *tmp = substring(item, voffset, width); X if (tmp != (char *)NULL) X { X printattr (win, hoffset, woffset, HORIZONTAL, attr, tmp); X free (tmp); X } } X /* X * This reads a file and sticks it into the char ** provided. X */ int readFile (char *filename, char **array, int maxlines) { X FILE *fd; X char temp[515]; X int lines = 0; X X /* Clean out temp... */ X cleanChar (temp, 514, '\0'); X X /* Can we open the file? */ X if ((fd = fopen (filename, "r")) == NULL) X { X return (0); X } X X /* Start reading the file in. */ X while ((fgets (temp, 512, fd) != (char *)NULL) && lines < maxlines) X { X int len = strlen(temp); X temp[len-1] = '\0'; X array[lines] = copyChar (temp); X lines++; X } X fclose (fd); X X /* Clean up and return. */ X array[lines] = ""; X return (lines); } X /* X * This function takes a character string, full of format markers X * and translates them into a chtype * array. This is better suited X * to curses, because curses uses chtype almost exclusively X */ chtype *char2Chtype (char *string, int *to, int *align) { X chtype attrib = A_NORMAL; X int insideMarker = FALSE; X int start = 0; X int from = 0; X int pair = 0; X int x = 3; X int len = 0; X chtype newstring[500], lastChar; X char temp[50]; X int adjust; X X /* Is the string NULL??? */ X if (string == (char *)NULL) X { X return ((chtype *)NULL); X } X X /* Get the length of the string. */ X len = strlen(string); X X /* Set up some default values... */ X (*to) = 0; X (*align) = LEFT; X temp[0] = '\0'; X pair = 0; X X /* Lets make some room for the chtype string... */ X cleanChtype (newstring, 500, '\0'); X X /* Look for an alignment marker. */ X if (string[0] == '<' && string[1] == 'C' && string[2] == '>') X { X (*align) = CENTER; X start = 3; X } X else if (string[0] == '<' && string[1] == 'R' && string[2] == '>') X { X (*align) = RIGHT; X start = 3; X } X else if (string[0] == '<' && string[1] == 'L' && string[2] == '>') X { X (*align) = LEFT; X start = 3; X } X else if (string[0] == '<' && string[1] == 'B' && string[2] == '=') X { X /* Set the item index value in the string. */ X newstring[0] = ' '; newstring[1] = ' '; newstring[2] = ' '; X X /* Pull out the bullet marker. */ X while (string[x] != '>') X { X newstring[x] = string[x] | A_BOLD; X x++; X } X newstring[x++] = ' '; X X /* Set the alignment variables. */ X (*align) = LEFT; X start = x; X (*to) = x; X } X else if (string[0] == '<' && string[1] == 'I' && string[2] == '=') X { X cleanChar (temp, 49, '\0'); X from=2; X x=0; X X /* Strip out the number. */ X while (string[++from] != '>') X { X if (isdigit(string[from])) X { X temp[x++] = string[from]; X } X } X X /* Set the alignment variables. */ X (*align) = LEFT; X start = x + 4; X X /* Add on the spaces. */ X adjust = atoi (temp); X for (x=0; x < adjust; x++) X { X newstring[(*to)++] = ' '; X } X } X X /* Set the format marker boolean to false. */ X insideMarker = FALSE; X X /* Start parsing the character string... */ X for (from=start; from < len; from++) X { X /* Are we inside a format marker??? */ X if (! insideMarker) X { X if (string[from] == '<' && string[from+1] == '/') X { X insideMarker = 1; X } X else if (string[from] == '<' && string[from+1] == '!') X { X insideMarker = 2; X } X else if (string[from] == '<' && string[from+1] == '#') X { X insideMarker = 3; X } X else if (string[from] == '\\' && string[from+1] == '<') X { X from++; X newstring[(*to)++] = string[from++] | attrib; X } X else if (string[from] == '\t') X { X for (x=0; x < 8; x++) X { X newstring[(*to)++] = ' '; X } X } X else X { X newstring[(*to)++] = string[from] | attrib; X } X } X else X { X /* We are in the format marker. */ X if (string[from] == '>') X { X insideMarker = 0; X } X else if (string[from] == '#') X { X lastChar = (chtype)NULL; X if (string[from+1] == 'L' && string[from+2] == 'L') X { X newstring[(*to)++] = ACS_LLCORNER | attrib; X lastChar = ACS_LLCORNER; X from += 2; X } X else if (string[from+1] == 'L' && string[from+2] == 'R') X { X newstring[(*to)++] = ACS_LRCORNER | attrib; X lastChar = ACS_LRCORNER; X from += 2; X } X else if (string[from+1] == 'U' && string[from+2] == 'R') X { X newstring[(*to)++] = ACS_URCORNER | attrib; X lastChar = ACS_URCORNER; X from += 2; X } X else if (string[from+1] == 'U' && string[from+2] == 'L') X { X newstring[(*to)++] = ACS_ULCORNER | attrib; X lastChar = ACS_ULCORNER; X from += 2; X } X else if (string[from+1] == 'R' && string[from+2] == 'T') X { X newstring[(*to)++] = ACS_RTEE | attrib; X lastChar = ACS_RTEE; X from += 2; X } X else if (string[from+1] == 'L' && string[from+2] == 'T') X { X newstring[(*to)++] = ACS_LTEE | attrib; X lastChar = ACS_LTEE; X from += 2; X } X else if (string[from+1] == 'B' && string[from+2] == 'T') X { X newstring[(*to)++] = ACS_BTEE | attrib; X lastChar = ACS_BTEE; X from += 2; X } X else if (string[from+1] == 'T' && string[from+2] == 'T') X { X newstring[(*to)++] = ACS_TTEE | attrib; X lastChar = ACS_TTEE; X from += 2; X } X else if (string[from+1] == 'H' && string[from+2] == 'L') X { X newstring[(*to)++] = ACS_HLINE | attrib; X lastChar = ACS_HLINE; X from += 2; X } X else if (string[from+1] == 'V' && string[from+2] == 'L') X { X newstring[(*to)++] = ACS_VLINE | attrib; X lastChar = ACS_VLINE; X from += 2; X } X else if (string[from+1] == 'P' && string[from+2] == 'L') X { X newstring[(*to)++] = ACS_PLUS | attrib; X lastChar = ACS_PLUS; X from += 2; X } X else if (string[from+1] == 'D' && string[from+2] == 'I') X { X newstring[(*to)++] = ACS_DIAMOND | attrib; X lastChar = ACS_DIAMOND; X from += 2; X } X else if (string[from+1] == 'C' && string[from+2] == 'B') X { X newstring[(*to)++] = ACS_CKBOARD | attrib; X lastChar = ACS_CKBOARD; X from += 2; X } X else if (string[from+1] == 'D' && string[from+2] == 'G') X { X newstring[(*to)++] = ACS_DEGREE | attrib; X lastChar = ACS_DEGREE; X from += 2; X } X else if (string[from+1] == 'P' && string[from+2] == 'M') X { X newstring[(*to)++] = ACS_PLMINUS | attrib; X lastChar = ACS_PLMINUS; X from += 2; X } X else if (string[from+1] == 'B' && string[from+2] == 'U') X { X newstring[(*to)++] = ACS_BULLET | attrib; X lastChar = ACS_BULLET; X from += 2; X } X else if (string[from+1] == 'S' && string[from+2] == '1') X { X newstring[(*to)++] = ACS_S1 | attrib; X lastChar = ACS_S1; X from += 2; X } X else if (string[from+1] == 'S' && string[from+2] == '9') X { X newstring[(*to)++] = ACS_S9 | attrib; X lastChar = ACS_S9; X from += 2; X } X X /* Check for a possible numeric modifier. */ X if (string[from+1] == '(' && lastChar != (chtype)NULL) X { X /* Set up some variables. */ X cleanChar (temp, 49, '\0'); X from++; X x=0; X X /* Strip out the number. */ X while (string[++from] != ')') X { X if (isdigit(string[from])) X { X temp[x++] = string[from]; X } X } X X /* Convert the number. */ X if (x != 0) X { X adjust = atoi (temp); X for (x=0; x < adjust; x++) X { X newstring[(*to)++] = lastChar | attrib; X } X } X } X } X else if (string[from] == '/' && string[from+1] == 'B') X { X attrib = attrib | A_BOLD; X from++; X } X else if (string[from] == '!' && string[from+1] == 'B') X { X attrib = attrib & (~A_BOLD); X from++; X } X else if (string[from] == '/' && string[from+1] == 'U') X { X attrib = attrib | A_UNDERLINE; X from++; X } X else if (string[from] == '!' && string[from+1] == 'U') X { X attrib = attrib & (~A_UNDERLINE); X from++; X } X else if (string[from] == '/' && string[from+1] == 'S') X { X attrib = attrib | A_STANDOUT; X from++; X } X else if (string[from] == '!' && string[from+1] == 'S') X { X attrib = attrib & (~A_STANDOUT); X from++; X } X else if (string[from] == '/' && string[from+1] == 'R') X { X attrib = attrib | A_REVERSE; X from++; X } X else if (string[from] == '!' && string[from+1] == 'R') X { X attrib = attrib & (~A_REVERSE); X from++; X } X else if (string[from] == '/' && string[from+1] == 'K') X { X attrib = attrib | A_BLINK; X from++; X } X else if (string[from] == '!' && string[from+1] == 'K') X { X attrib = attrib & (~A_BLINK); X from++; X } X else if (string[from] == '/' && string[from+1] == 'D') X { X attrib = attrib | A_DIM; X from++; X } X else if (string[from] == '!' && string[from+1] == 'D') X { X attrib = attrib & (~A_DIM); X from++; X } X else if (string[from] == '/' && isdigit(string[from+1]) && isdigit(string[from+2])) X { #ifdef COLOR X sprintf (temp, "%c%c", string[from+1],string[from+2]); X pair = atoi(temp); X attrib = attrib | COLOR_PAIR(pair); #else X from += 2; #endif X } X else if (string[from] == '!' && isdigit(string[from+1]) && isdigit(string[from+2])) X { #ifdef COLOR X sprintf (temp, "%c%c", string[from+1],string[from+2]); X pair = atoi(temp); X attrib = attrib & (~COLOR_PAIR(pair)); #else X from += 2; #endif X } X else if (string[from] == '/' && isdigit(string[from+1])) X { #ifdef COLOR X pair = string[++from] - '0'; X attrib = attrib | COLOR_PAIR(pair); #else X from++; #endif X } X else if (string[from] == '!' && isdigit(string[from+1])) X { #ifdef COLOR X pair = string[++from] - '0'; X attrib = attrib & (~COLOR_PAIR(pair)); #else X from++; #endif X } X } X } X X /* Return the new string... */ X return (copyChtype (newstring)); } X /* X * This determines the length of a chtype string X */ int chlen (chtype *string) { X /* Declare local variables. */ X int x = 0; X X /* Make sure we wern't given a NULL string. */ X if (string == (chtype *)NULL) X { X return (0); X } X X /* Find out how long this string is. */ X while (string[x++] != (chtype)'\0'); X return ((x-1)); } X /* X * This returns a pointer to char * of a chtype * X */ char *chtype2Char (chtype *string) { X /* Declare local variables. */ X char *newstring; X int len = 0; X int x; X X /* Is the string NULL??? */ X if (string == (chtype *)NULL) X { X return ((char *)NULL); X } X X /* Get the length of the string. */ X len = chlen(string); X X /* Make the new string. */ X newstring = (char *)malloc (sizeof (char) * (len+1)); X cleanChar (newstring, len+1, '\0'); X X /* Start translating... */ X for (x=0; x < len; x++) X { X newstring[x] = string[x] & A_CHARTEXT; X } X X /* Force a NULL character on the end of the string. */ X newstring[len] = (char)NULL; X X /* Return it. */ X return (newstring); } X void printattr (WINDOW *window, int xpos, int ypos, int align, chtype attr, char *mesg) { X int x; X X /* Check the alignment of the message. */ X if (align == VERTICAL) X { X int mesgLength = ((int)strlen (mesg) <= window->_maxy ? (int)strlen (mesg) : window->_maxy); X X /* Draw the message on a vertical axis. */ X for (x=0; x < mesgLength ; x++) X { X if (attr == A_NOATTRIB) X { X mvwaddch (window, xpos+x, ypos, mesg[x]); X } X else X { X mvwaddch (window, xpos+x, ypos, mesg[x] | attr); X } X } X } X else X { X int mesgLength = ((int)strlen (mesg) <= window->_maxx ? (int)strlen (mesg) : window->_maxx); X X /* Draw the message on a horizontal axis. (default) */ X for (x=0; x < mesgLength ; x++) X { X if (attr == A_NOATTRIB) X { X mvwaddch (window, xpos, ypos+x, mesg[x]); X } X else X { X mvwaddch (window, xpos, ypos+x, mesg[x] | attr); X } X } X } } X /* X * This swaps two elements in an array. X */ void swapIndex (char *list[], int i, int j) { X char *temp; X temp = list[i]; X list[i] = list[j]; X list[j] = temp; } X /* X * This function is a quick sort alg which sort an array of X * char *. I wanted to use to stdlib qsort, but couldn't get the X * thing to work, so I wrote my own. I'll use qsort if I can get X * it to work. X */ void quickSort (char *list[], int left, int right) { X int i, last; X X /* If there are fewer than 2 elements, return. */ X if (left >= right) X { X return; X } X X swapIndex (list, left, (left+right)/2); X last = left; X X for (i=left+1; i <= right; i++) X { X if (strcmp (list[i], list[left]) < 0) X { X swapIndex (list, ++last, i); X } X } X X swapIndex (list, left, last); X quickSort (list, left, last-1); X quickSort (list, last+1, right); } X /* X * This strips white space off of the given string. X */ void stripWhiteSpace (EStripType stripType, char *string) { X /* Declare local variables. */ X int stringLength = 0; X int alphaChar = 0; X int x = 0; X X /* Make sure the string is not NULL. */ X if (string == (char *)NULL) X { X return; X } X X /* Get the length of the string. */ X stringLength = (int)strlen(string); X X /* Strip the white space from the front. */ X if (stripType == vFRONT || stripType == vBOTH) X { X /* Find the first non-whitespace character. */ X while (string[alphaChar] == ' ' || string[alphaChar] == '\t') X { X alphaChar++; X } X X /* Trim off the white space. */ X if (alphaChar != stringLength) X { X for (x=0; x < (stringLength-alphaChar); x++) X { X string[x] = string[x+alphaChar]; X } X string[stringLength-alphaChar] = '\0'; X } X else X { X /* Set the string to zero. */ X string = (char *)memset (string, 0, stringLength); X } X } X X /* Get the length of the string. */ X stringLength = (int)strlen(string)-1; X X /* Strip the space from behind if it was asked for. */ X if (stripType == vBACK || stripType == vBOTH) X { X /* Find the first non-whitespace character. */ X while (string[stringLength] == ' ' || string[stringLength] == '\t') X { X string[stringLength--] = '\0'; X } X } } X /* X * This splits a string into X parts given the split character. X */ int splitString (char *string, char *items[], char splitChar) { X /* Declare local variables. */ X char temp[100]; X int stringLength = 0; X int chunks = 0; X int pos = 0; X int x; X X /* Check if the given string is NULL. */ X if (string == (char *)NULL) X { X return (0); X } X X /* Get the length of the string. */ X stringLength = (int)strlen (string); X X /* Zero out the temp string. */ X cleanChar (temp, 100, '\0'); X X /* Start looking for the string. */ X for (x=0; x < stringLength; x++) X { X if (string[x] == splitChar) X { X /* Copy the string into the array. */ X items[chunks++] = strdup (temp); X X /* Zero out the temp string. */ X cleanChar (temp, 100, '\0'); X X /* Reset the position counter. */ X pos = 0; X } X else X { X temp[pos++] = string[x]; X } X } X X /* Don't forget the last one. */ X items[chunks++] = strdup (temp); X return chunks; } X /* X * This function takes a mode_t type and creates a string represntation X * of the permission mode. X */ int mode2Char (char *string, mode_t mode) { X /* Declare local variables. */ X int permissions = 0; X X /* Clean the string. */ X cleanChar (string, 10, '-'); X string[10] = '\0'; X X /* Determine the file type. */ X if (S_ISLNK (mode)) X { X string[0] = 'l'; X } X else if (S_ISSOCK (mode)) X { X string[0] = '@'; X } X else if (S_ISREG(mode)) X { X string[0] = '-'; X } X else if (S_ISDIR(mode)) X { X string[0] = 'd'; X } X else if (S_ISCHR(mode)) X { X string[0] = 'c'; X } X else if (S_ISBLK(mode)) X { X string[0] = 'b'; X } X else if (S_ISFIFO(mode)) X { X string[0] = '&'; X } X else X { X return -1; X } X X /* Readable by owner? */ X if ((mode&S_IRUSR) != 0) X { X string[1] = 'r'; X permissions += 400; X } X X /* Writable by owner? */ X if ((mode & S_IWUSR) != 0) X { X string[2] = 'w'; X permissions += 200; X } X X /* Executable by owner? */ X if ((mode & S_IXUSR) != 0) X { X string[3] = 'x'; X permissions += 100; X } X X /* Readable by group? */ X if ((mode & S_IRGRP) != 0) X { X string[4] = 'r'; X permissions += 40; X } X X /* Writable by group? */ X if ((mode & S_IWGRP) != 0) X { X string[5] = 'w'; X permissions += 20; X } X X /* Executable by group? */ X if ((mode & S_IXGRP) != 0) X { X string[6] = 'x'; X permissions += 10; X } X X /* Readable by other? */ X if ((mode & S_IROTH) != 0) X { X string[7] = 'r'; X permissions += 4; X } X X /* Writable by other? */ X if ((mode & S_IWOTH) != 0) X { X string[8] = 'w'; X permissions += 2; X } X X /* Executable by other? */ X if ((mode & S_IXOTH) != 0) X { X string[9] = 'x'; X permissions += 1; X } X X /* Check for suid. */ X if ((mode & S_ISUID) != 0) X { X string[3] = 's'; X permissions += 4000; X } X X /* Check for sgid. */ X if ((mode & S_ISGID) != 0) X { X string[6] = 's'; X permissions += 2000; X } X X /* Check for sticky bit. */ X if ((mode & S_ISVTX) != 0) X { X string[0] = 't'; X permissions += 1000; X } X X /* Check for unusual permissions. */ X if (((mode & S_IXUSR) == 0) && X ((mode & S_IXGRP) == 0) && X ((mode & S_IXOTH) == 0) && X (mode & S_ISUID) != 0) X { X string[3] = 'S'; X } X X return permissions; } SHAR_EOF $shar_touch -am 0503190896 'cdk.c' && chmod 0444 'cdk.c' || echo 'restore of cdk.c failed' shar_count="`wc -c < 'cdk.c'`" test 28144 -eq "$shar_count" || echo "cdk.c: original size 28144, current size $shar_count" rm -f _sharnew.tmp fi # ============= cdk.h ============== if test -f 'cdk.h' && test X"$1" != X"-c"; then echo 'x - skipping cdk.h (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting cdk.h (text)' sed 's/^X//' << 'SHAR_EOF' > 'cdk.h' && #ifndef CDK_H #define CDK_H X /* X * $Author: glover $ X * $Date: 1996/05/01 02:05:22 $ X * $Revision: 1.161 $ X */ X #ifdef NCURSES #include #else #include #endif #include #include #include #include #include #include #include #include #include #include #include #include "curdefs.h" X /* X * ========================================================= X * Delcare Global Generic Defines and Typedefs X * ========================================================= X */ typedef enum {vENTRY, X vMENTRY, X vLABEL, X vSCROLL, X vDIALOG, X vSCALE, X vMARQUEE, X vMENU, X vMATRIX, X vHISTOGRAM, X vSELECTION, X vVIEWER, X vGRAPH, X vRADIO, X vTEMPLATE, X vSWINDOW, X vITEMLIST, X vFSELECT X } EObjectType; typedef enum {vCHAR, X vHCHAR, X vINT, X vHINT, X vMIXED, X vHMIXED, X vUCHAR, X vLCHAR, X vUHCHAR, X vLHCHAR, X vUMIXED, X vLMIXED, X vUHMIXED, X vLHMIXED, X vVIEWONLY X } EDisplayType; typedef enum {vNONE, X vPERCENT, X vFRACTION, X vREAL X } EHistogramDisplayType; typedef enum {vPLOT, X vLINE X } EGraphDisplayType; typedef enum {vFRONT, X vBACK, X vBOTH X } EStripType; X typedef int boolean; X #define LEFT 9000 #define RIGHT 9001 #define CENTER 9002 #define TOP 9003 #define BOTTOM 9004 #define HORIZONTAL 9005 #define VERTICAL 9006 #define FULL 9007 X #define NONE 0 #define ROW 1 #define COL 2 X #define BOX 1 #define NOBOX 0 X #define DIFF(a,b) (abs(a-b)) #define MAX(a,b) (a > b ? a : b) #define MIN(a,b) (a < b ? a : b) #define HALF(a) (a>>1) X #ifndef COLOR_PAIR #define COLOR_PAIR(a) A_NORMAL #endif X /* Define the GLOBAL DEBUG FILEHANBDLE */ FILE *CDKDEBUG; X /* X * This is for the Cdk Screen object. X */ #define MAXOBJECTS 30 struct _screen_st { X WINDOW *window; X void *object[MAXOBJECTS]; X EObjectType cdktype[MAXOBJECTS]; X int objectCount; }; typedef struct _screen_st CDKSCREEN; X /* X * This is for the key bindings. X */ #define MAXBINDINGS 300 #define MAXARGS 100 typedef void (*BINDFN) (EObjectType cdktype, void *object, void *clientData); typedef int (*PROCESSFN) (EObjectType cdktype, void *object, void *clientData, chtype input); SHAR_EOF : || echo 'restore of cdk.h failed' fi echo 'End of archive part 1' echo 'File cdk.h is continued in part 2' echo 2 > _sharseq.tmp exit 0