From 8876fe2dc9c9322573235eb2adf15249719dcf77 Mon Sep 17 00:00:00 2001 From: Packit Service Date: Dec 09 2020 23:34:37 +0000 Subject: newt-0.52.20 base --- diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..4b8b7d7 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,46 @@ +Current maintainer: + Miroslav Lichvar + +Original author: + Erik Troan + +Authors: + Adrian Havill + Elliot Lee + Matt Wilson + Miroslav Lichvar + Petr Rockai + +Contributors: + Akira Tagoh + Arnaldo Carvalho de Melo + Bill Nottingham + Bruce Perens + Crutcher Dunnavant + Dan Winship + Florian La Roche + Forest Bond + Greg Swift + Gwenole Beauchesne + Jakob Kemi + Jakub Jelinek + Jason Tibbitts + Jeremy Katz + Joe Orton + Joey Boggs + Kang Kai + Matthias Klose + Michael Fulbright + Michael K. Johnson + Michael Scherer + Michael Vogt + Mikhail T. + Nalin Dahyabhai + Natanael Copa + Otavio Salvador + Preston Brown + Richard W.M. Jones + Shawn Starr + Thomas Jarosch + Trond Eivind Glomsrød + Yanko Kaneti diff --git a/CHANGES b/CHANGES new file mode 100644 index 0000000..c8c5ec8 --- /dev/null +++ b/CHANGES @@ -0,0 +1,369 @@ +0.52.20 +- improve handling of long strings in whiptail menu (#1353792) +- support screen resize as hotkey in form (#1432926) + +0.52.19 +- support --notags in whiptail checklist and radiolist (#1319794) +- don't hard-code -I/usr/include/slang in CPPFLAGS (Alex Suykov) +- use $(CC) instead of $(CPP) to generate .depend files (Samuel Martin) +- update translations from Zanata + +0.52.18 +- fix widget key collision in snack on 64-bit archs (#1151455) +- handle NEWT_EXIT_ERROR in snack +- fix preprocessor warnings in snack +- optimize textbox reflowing +- remove newtListitem declarations (#1074092) + +0.52.17 +- add python3 support (Matthias Klose) (#963839) +- implement newtComponentAddCallback() for forms as a focus-change + callback (Dan Winship) +- add newtEntryGet/SetCursorPosition and newtFormGet/SetScrollPosition + (Dan Winship) +- restore cursor position after changing help line (Dan Winship) +- rename snackmodule to snack (#963839) +- update CHANGES from spec changelog +- add AUTHORS and README + +0.52.16 +- add newtComponentGetSize and newtComponentGetPosition + (Dan Winship) (#987596) +- modify Makefile to use SOEXT (#971168) +- free gpm socket name and unlink gpm socket on form exit +- fix memory leaks in whiptail +- add missing whiptail options to help and man page + +0.52.15 +- fix errors found by gcc-with-cpychecker (#800075) +- fix building with tcl8.6 (#902561) +- add fallback to python-config (#783627) +- replace tabs in snack.py (#870647) +- compile snackmodule.c with flag -fPIC (Kang Kai) +- include new translations from transifex +- allow newtWinMenu and newtWinEntries with no buttons or items +- don't draw scale when not mapped +- build with large-file support for stat64 +- remove unused variables in test code +- update FSF address + +0.52.14 +- fix returning strings in whiptail and whiptcl (#752818) +- fix configure to work with multiple python versions (#737998) + +0.52.13 +- add support for changing colors in individual labels, scrollbars, entries, + textboxes and scales, add custom colorsets +- add support for NEWT_COLORS and NEWT_COLORS_FILE variables (#689903) +- allow resizing of form +- fix errors found by coverity +- fix va_list usage (Gwenole Beauchesne) +- fix building and installing on Mac OS X (#652479) +- check for slang.h header, support DESTDIR variable, add --without-python + option (Otavio Salvador) +- add Persian, Low German translations +- don't hang in form when stdin disappears + +0.52.12 +- fix whiptail --gauge and its description in man page (#620083) +- remove space after \n in whiptail texts (#620083) +- remove NLS code from snack (#599608) +- expose more keys to python as shortcuts in dialogs (Jakob Kemi) +- release python global-thread-lock during dialog displays (Jakob Kemi) +- fix warnings in whiptcl.c and include Tcl_PkgProvide() call (Mikhail T.) +- don't NULL deref when an invalid array is specified in checkboxtree + (Arnaldo Carvalho de Melo) + +0.52.11 +- fix buffer overflow in textbox when reflowing (#523955, CVE-2009-2905) +- use full textbox width when reflowing and allow minimal width 1 +- fix writing lines longer than width in textbox +- don't use va_list in newtvwindow more than once (#523696) +- bind \E[Z to back-tab in built-in keymap (#468046) +- terminate string after reading file in whiptail +- add newtRadioSetCurrent function (Thomas Jarosch) +- add pkgconfig support (Thomas Jarosch) +- add Malay, Malayalam, Assamese, Gujarati, Bengali India, Kannada, Telugu + translations +- include debian patches + - fix crash in textbox SetText when topLines != 0 + - don't link modules with libraries already linked with libnewt + - add Asturian and Marathi translations + +0.52.10 +- improve --noitem description (#456305) +- add setHeight to Textbox class +- fix fixedheight forms +- free keymap in newtFinished() +- fix memory leak in textbox +- fix valgrind error in checkboxtree +- don't crash when running empty form +- don't crash or hang when form has no focusable elements +- before checkboxtree drawing return first item in GetCurrent() +- redraw textbox in SetText() +- add setColor description to SnackScreen docstring (Greg Swift) +- make sure Widget isn't used directly (Greg Swift) (#452920) +- add Serbian translations (Miloš Komarčević) +- add Balochi translation (Mostafa Daneshvar) + +0.52.9 +- handle component destruction (patch by Richard W.M. Jones) +- fix newtWinEntry definition +- don't use uninitialized values in newtWinMenu +- remove workarounds for old bug in SLsmg_write_nstring +- improve SIGWINCH handling in form +- don't abort from whiptail gauge on SIGWINCH +- redisplay also last line +- update Polish translation (Piotr Drąg) + +0.52.8 +- enable slang utf8 mode (#425992) +- support --disable-nls option (patch by Natanael Copa) +- redraw screen when using entry in euc encodings +- fix segfault in whiptail when no entry is selected in radiolist +- add back support for list of Entries in EntryWindow prompts in snack + (#248878) + +0.52.7 +- add support to snack for multiple selection and border in listbox + and cursorAtEnd in entry (patch by Shawn Starr) +- fix scrollbar positioning in listbox +- cope with backward system time jumps (#240691) +- free helplines and windows in newtFinished, check for overflow (#239992) +- fix cursor positioning when setting entry or checkbox flags +- fix counting of items in checkboxtree +- fix some memory leaks +- fix entry scrolling (#234829) +- fix multibyte character handling in entry + +0.52.6 +- add newtSetColor() to allow changing individual colors +- add newtPopWindowNoRefresh() (patch by Forest Bond) + +0.52.5 +- provide option to change text of buttons (#126768) +- don't add escape key to hot keys by default (#216157) +- fix cursor position in checkboxtree, radio button and checkbox +- don't force monochrome terminals to output colors +- highlight active compact button on monochrome terminals +- update translations from debian +- fix memory allocation in snack to be consistent (#212780) + +0.52.4 +- fix entry corruption when reading multibyte characters + and double width character handling +- avoid overflow/crash in scale +- patches from debian + - fix crash of snack in EntryWindow when prompts is list of tuples + - put cursor at beginning of text for better accessibility + in button, scale and textbox + - add topleft option to whiptail + +0.52.3 +- makefile and configure cleanup +- fix warnings +- fix screen corruption when half of double width character is overwritten + (#137957) +- fix double width character handling in checkboxtree and listbox +- unfocus when displaying help +- fix help dialog in popcorn.py (#81352) +- fix checkboxtree positioning +- make textbox with scrollbar focusable (#83203) +- turn off cursor when entry terminated form (#86074) +- handle listbox and checkboxtree focus better (#186053) +- make default colors more friendly to 8-color terminals (#187545) +- fix handling windows larger than screen size (#189981) +- fix a crash in checkboxtree.c where pressing pgup/pgdown + on a checkboxtree with less items than its height would + cause segmentation violation (#165347) +- apply patch by Bill Nottingham (thanks) to improve scrollbar appearance + (#174771) + +0.52.2 +- minor fixes + +0.52.1 +- revert bidi patch, objections by Jeremy Katz about + anaconda breaking +- this version still only exists as a "ghastly" upstream tarball; + the patches are now cleaned up and will be integrated into + rhlinux cvs unless some more breakage akin to bidi occurs +- only do gpmclose if gpmopen succeeed (#118530) + +0.52.0 +- use versioned symbols, patch by Alastair McKinstry, mckinstry at + debian dot org, thanks +- need private wstrlen due to versioned syms, patch from debian + package of newt + +0.51.5 +- incorporated listbox cursor location patch (#69903) + +0.51.4 +- fixed help line drawing in UTF-8 (#81718) +- calculate the width of text in entries using wstrlen +- always set component width to the new label width in newtLabelSetText +- fixed snack.CListbox to work properly with UTF-8 (#81718) + +0.51.3 +- cleaned up const qualifiers in interfaces +- added Ctrl-L screen refresh +- fixed segfault in test.c when listbox items are selected +- accessibility: made newt useable with monochrome terms (#60931) +- leave the symbols in the libs (#60400) +- fixed grammar in tutorial (#63496) +- error checking (curcomp exists) for formEvent, newtFormGetCurrent, + removed fifty button limit (#59027) + +0.51.2 +- fixed wstrlen() it was calculating wcwidth(first wide char in + string) * strlen(str) instead of the actual width of the whole + string +- fixed newtRedrawHelpLine() to copy all the bytes from a multibyte + string + +0.51.0 +- changes for element width calculation for UTF-8 +- fix textwrap for UTF-8 in general +- bump soname to avoid shared library collisions with slang + +0.50.39 +- changed a test to check for 'None' the correct way + +0.50.38 +- don't hardcode linedrawing characters in the scrollbar code + +0.50.37 +- minor tweaks for use with UTF-8 slang + +0.50.36 +- add newtListboxGetItemCount() API call +- include numeric percentage in scale widget appearace +- add support for ESC key using NEWT_KEY_ESCAPE + +0.50.35 +- build for whatever version of python happens to be installed + +0.50.32 +- re-ordered the width key of CheckboxTree.__init__; #52319 + +0.50.31 +- right anchor the internal Listbox of CListboxes, so that empty +- scrollable CListboxes do not look like crape. + +0.50.30 +- padded hidden checkboxes on CheckboxTrees + +0.50.29 +- taught CheckboxTrees about width. Whohoo! 2-D!!! + +0.50.28 +- added 'hide_checkbox' and 'unselectable' options to CheckboxTrees + +0.50.27 +- CListBox -> CListbox for API consistency +- fixup replace() method of CListbox + +0.50.26 +- few bugfixes to the CListBox + +0.50.25 +- added python binding for newtListboxClear() for Listbox and CListBox +- let ButtonBars optionally be made of CompactButtons + +0.50.24 +- added CListBox python convenience class + +0.50.23 +- added python binding for CompactButton() +- change from using SLsmg_touch_screen to SLsmg_touch_lines to prevent + excessive flashing due to screen clears when using touch_screen (more + Japanese handling) + +0.50.22 +- redraw the screen in certain situations when LANG=ja_JP.eucJP to + prevent corrupting kanji characters (#34362) +- allow python scripts to watch file handles +- fix 64-bit warnings in snackmodule +- misc snack.py cleanups +- add NEWT_FD_EXCEPT to allow watching for fd exceptions +- in newtExitStruct, return the first file descriptor that an event occurred on + +0.50.21 +- don't blow the stack if we push a help line that is longer than the + curret number of columns +- clip window to screen bounds so that if we get a window that is + larger than the screen we can still redraw the windows behind it + when we pop + +0.50.20 +- added newtCheckboxTreeSetCurrent() and snack binding + +0.50.19 +- fix use of append in snack.py + +0.50.17 +- fixed cursor disappearing in suspend (again) + +0.50.16 +- fixed cursor disappearing in suspend + +0.50.15 +- added setValue method for checkboxes in snack + +0.50.14 +- added NEWT_FLAG_PASSWORD for entering passwords and having asterix echo'd + +0.50.10 +- added support for help +- added cusor on/off stuff + +0.50.9 +- minor fixes + +0.50.6 +- added newtCheckboxTreeSetEntry(), newtCheckboxTreeGetEntryValue() + and newtCheckboxTreeSetEntryValue() +- checkboxtree callbacks +- if collapsing branches at the end of the list and list length + is larger then height, move first visible entry accordingly +- allow selection of all checkboxes on current branch +- snack bindings for the above + +0.50.5 +- added newtCheckboxTreeGetCurrent() and snack bindings +- updated snack stuff to allow manual placement of grid + wrapped windows + +0.50.4 +- fix segfault in newtRadioGetCurrent + +0.50.3 +- place cursor in checkboxtree's more carefully + +0.50.2 +- listbox bug fixes + +0.50.1 +- added newtFormSetTimer() (and test case, and python) +- checkboxtree's could improperly leave info from closed trees + at the end of the display + +0.50 +- added CheckboxTree widget +- vastly improved python bindings + +0.40 +- GPM mouse support added + +0.31: +- pgdn could core dump on short textboxes + +0.30: +- newtDrawRootText() didn't use the specified position properly +- removed relics of original listbox code still handing around + checkbox.c +- renamed DOBORDER flag to simply BORDER +- listboxes no longer scroll by default +- newtListboxSetEntry() uses a key, not an index +- listbox scrollbars should work properly in borders diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..5bc8fb2 --- /dev/null +++ b/COPYING @@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + 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. + + 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 library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, 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 library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete 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 distribute a copy of this License along with the +Library. + + 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. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +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 Library, 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. + +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 Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. 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. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library 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. + + 9. 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 Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +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. + + 11. 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 Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library 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 Library. + +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. + +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. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library 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. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library 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. + +Each version is given a distinguishing version number. If the Library +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 Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +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. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. 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 LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. 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. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..be203e4 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,189 @@ +LIBS = -lslang @LIBS@ +LIBTCL = @TCL_LIB_FLAG@ + +CC = @CC@ +CPP = @CPP@ +CFLAGS = @CFLAGS@ +LDFLAGS = @LDFLAGS@ +CPPFLAGS = -D_GNU_SOURCE @CPPFLAGS@ +GNU_LD = @GNU_LD@ + +VERSION = @VERSION@ +TAG = r$(subst .,-,$(VERSION)) +SONAME = @SONAME@ +SOEXT = so + +PYTHONVERS = @PYTHONVERS@ +WHIPTCLLIB = @WHIPTCLLIB@ +ifneq ($(WHIPTCLLIB),) +WHIPTCLSO = $(WHIPTCLLIB).$(SOEXT) +else +WHIPTCLSO = +endif + +PROGS = test whiptail $(WHIPTCLSO) testgrid testtree showchars showkey +TESTOBJS = test.o testgrid.o testtree.o showchars.o showkey.o +NDIALOGOBJS = whiptail.o dialogboxes.o +WHIPTCLOBJS = shared/whiptcl.o shared/dialogboxes.o +LIBNEWT = libnewt.a +LIBNEWTSH = libnewt.$(SOEXT).$(VERSION) +LIBNEWTSONAME = libnewt.$(SOEXT).$(SONAME) +LIBOBJS = newt.o button.o form.o checkbox.o entry.o label.o listbox.o \ + scrollbar.o textbox.o scale.o grid.o windows.o buttonbar.o \ + checkboxtree.o + +ifneq ($(GNU_LD),) +SHLIBFLAGS= -Wl,--version-script,newt.0.52.ver -Wl,-soname,$(LIBNEWTSONAME) +else +SHLIBFLAGS= +endif + +SHCFLAGS = -fPIC + +prefix = @prefix@ +includedir = @includedir@ +exec_prefix = @exec_prefix@ +libdir = @libdir@ +bindir = @bindir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +mandir = @mandir@ +man1dir = $(mandir)/man1 +pkgconfigdir = $(libdir)/pkgconfig +instroot ?= $(DESTDIR) + +#-------------------------------------- + +SOURCES = $(subst .o,.c,$(TESTOBJS) $(NDIALOGOBJS) $(LIBOBJS)) + +SHAREDDIR = shared +SHAREDOBJS = $(patsubst %,$(SHAREDDIR)/%, $(LIBOBJS)) + +ifeq (.depend,$(wildcard .depend)) +TARGET=$(PROGS) +else +TARGET=depend $(PROGS) +endif + +all: $(TARGET) _snack.$(SOEXT) + +test: test.o $(LIBNEWT) + $(CC) -g -o test test.o $(LIBNEWT) $(LDFLAGS) $(LIBS) + +testgrid: testgrid.o $(LIBNEWT) + $(CC) -g -o testgrid testgrid.o $(LIBNEWT) $(LDFLAGS) $(LIBS) + +testtree: testtree.o $(LIBNEWT) + $(CC) -g -o testtree testtree.o $(LIBNEWT) $(LDFLAGS) $(LIBS) + +showchars: showchars.o $(LIBNEWT) + $(CC) -g -o showchars showchars.o $(LIBNEWT) $(LDFLAGS) $(LIBS) + +showkey: showkey.o $(LIBNEWT) + $(CC) -g -o showkey showkey.o $(LIBNEWT) $(LDFLAGS) $(LIBS) + +_snack.$(SOEXT): snack.c $(LIBNEWTSH) + @[ -n "$(PYTHONVERS)" ] && for ver in $(PYTHONVERS); do \ + pyconfig=$$ver-config; \ + if ! $$pyconfig --cflags > /dev/null 2>&1 && \ + python-config --cflags > /dev/null 2>&1; then \ + echo $$pyconfig not found, using python-config; \ + pyconfig=python-config; \ + fi; \ + mkdir -p $$ver; \ + PCFLAGS=`$$pyconfig --cflags`; \ + PIFLAGS=`$$pyconfig --includes`; \ + PLDFLAGS=`$$pyconfig --ldflags`; \ + PLFLAGS=`$$pyconfig --libs`; \ + echo $(CC) $(SHCFLAGS) $(CPPFLAGS) $$PIFLAGS $$PCFLAGS -c -o $$ver/snack.o snack.c; \ + $(CC) $(SHCFLAGS) $(CPPFLAGS) $$PIFLAGS $$PCFLAGS -c -o $$ver/snack.o snack.c; \ + echo $(CC) --shared $$PLDFLAGS $$PLFLAGS $(LDFLAGS) -o $$ver/_snack.$(SOEXT) $$ver/snack.o -L. -lnewt $(LIBS); \ + $(CC) --shared $$PLDFLAGS $$PLFLAGS $(LDFLAGS) -o $$ver/_snack.$(SOEXT) $$ver/snack.o -L. -lnewt $(LIBS); \ + done || : + touch $@ + +whiptail: $(NDIALOGOBJS) $(LIBNEWTSH) + $(CC) -g -o whiptail $(NDIALOGOBJS) -L. $(LDFLAGS) -lnewt $(LIBS) -lpopt + +whiptcl.$(SOEXT): $(WHIPTCLOBJS) $(LIBNEWTSH) + $(CC) -shared $(SHCFLAGS) $(LDFLAGS) -o whiptcl.$(SOEXT) $(WHIPTCLOBJS) -L. -lnewt $(LIBTCL) -lpopt $(LIBS) + +$(LIBNEWT): $(LIBOBJS) + ar rv $@ $^ + +newt.o $(SHAREDDIR)/newt.o: newt.c Makefile + +veryclean: clean + rm -f .depend *.pc + +clean: + rm -f $(PROGS) *.o $(LIBNEWT) core $(LIBNEWTSH) \ + $(SHAREDDIR)/*.o *.$(SOEXT)* + +depend: + $(CC) $(CFLAGS) $(CPPFLAGS) -M $(SOURCES) > .depend + +$(SHAREDDIR): + mkdir -p $(SHAREDDIR) + +sharedlib: $(LIBNEWTSH) + +$(LIBNEWTSH): $(SHAREDDIR) $(SHAREDOBJS) + $(CC) -shared -o $(LIBNEWTSH) $(SHLIBFLAGS) $(SHAREDOBJS) $(LDFLAGS) $(LIBS) + ln -fs $(LIBNEWTSONAME) libnewt.$(SOEXT) + ln -fs $(LIBNEWTSH) $(LIBNEWTSONAME) + +$(SHAREDDIR)/%.o : %.c + $(CC) $(SHCFLAGS) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< + +install: $(LIBNEWT) install-sh whiptail + [ -d $(instroot)/$(bindir) ] || install -m 755 -d $(instroot)/$(bindir) + [ -d $(instroot)/$(libdir) ] || install -m 755 -d $(instroot)/$(libdir) + [ -d $(instroot)/$(includedir) ] || install -m 755 -d $(instroot)/$(includedir) + [ -d $(instroot)/$(man1dir) ] || install -m 755 -d $(instroot)/$(man1dir) + [ -d $(instroot)/$(pkgconfigdir) ] || install -m 755 -d $(instroot)/$(pkgconfigdir) + install -m 644 newt.h $(instroot)/$(includedir) + install -m 644 $(LIBNEWT) $(instroot)/$(libdir) + install -m 755 whiptail $(instroot)/$(bindir) + install -m 644 whiptail.1 $(instroot)/$(man1dir) + make -C po datadir=$(instroot)/$(datadir) install + install -m 644 libnewt.pc $(instroot)/$(pkgconfigdir) + +install-sh: sharedlib $(WHIPTCLSO) _snack.$(SOEXT) + [ -d $(instroot)/$(libdir) ] || install -m 755 -d $(instroot)/$(libdir) + install -m 755 $(LIBNEWTSH) $(instroot)/$(libdir) + ln -sf $(LIBNEWTSONAME) $(instroot)/$(libdir)/libnewt.$(SOEXT) + ln -sf $(LIBNEWTSH) $(instroot)/$(libdir)/$(LIBNEWTSONAME) + [ -n "$(WHIPTCLSO)" ] && install -m 755 whiptcl.$(SOEXT) $(instroot)/$(libdir) || : + [ -n "$(PYTHONVERS)" ] && for ver in $(PYTHONVERS) ; do \ + [ -d $(instroot)/$(libdir)/$$ver/site-packages ] || install -m 755 -d $(instroot)/$(libdir)/$$ver/site-packages ;\ + install -m 755 $$ver/_snack.$(SOEXT) $(instroot)/$(libdir)/$$ver/site-packages ;\ + install -m 644 snack.py $(instroot)/$(libdir)/$$ver/site-packages ;\ + done || : + +Makefile: configure.ac + @echo "You need to rerun ./autogen.sh and ./configure before continuing" + @exit 1 + +create-archive: Makefile + @rm -rf /tmp/newt-$(VERSION) + @git archive --prefix=newt-$(VERSION)/ $(TAG) | tar x -C /tmp + @cd /tmp/newt-$(VERSION) && ./autogen.sh && rm -rf autom4te.cache .gitignore + @cd /tmp; tar c --owner root --group root newt-$(VERSION) | gzip -9 > newt-$(VERSION).tar.gz + @rm -rf /tmp/newt-$(VERSION) + @cp /tmp/newt-$(VERSION).tar.gz . + @rm -f /tmp/newt-$(VERSION).tar.gz + @echo " " + @echo "The final archive is ./newt-$(VERSION).tar.gz." + +tag-archive: Makefile + @git tag $(TAG) + +archive: tag-archive create-archive + +upload-archive: + scp -p newt-$(VERSION).tar.gz fedorahosted.org:newt + +ifeq (.depend,$(wildcard .depend)) +include .depend +endif diff --git a/README b/README new file mode 100644 index 0000000..f02f6cb --- /dev/null +++ b/README @@ -0,0 +1,25 @@ +Newt +---- + +Newt is a programming library for color text mode, widget based user +interfaces. Newt can be used to add stacked windows, entry widgets, +checkboxes, radio buttons, labels, plain text fields, scrollbars, +etc., to text mode user interfaces. Newt is based on the slang library. + +Homepage: + https://pagure.io/newt + +Copyright (C) 1996-2016 Red Hat, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License version 2 as published by the Free Software Foundation. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..7c748d3 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +autoheader +autoconf +automake --foreign -a -c -f +make -C po diff --git a/button.c b/button.c new file mode 100644 index 0000000..8eb5e5a --- /dev/null +++ b/button.c @@ -0,0 +1,208 @@ +#include +#include +#include + +#include "newt.h" +#include "newt_pr.h" + +struct button { + char * text; + int compact; +}; + +static void buttonDrawIt(newtComponent co, int active, int pushed); +static void buttonDrawText(newtComponent co, int active, int pushed); + +static void buttonDraw(newtComponent c); +static void buttonDestroy(newtComponent co); +static struct eventResult buttonEvent(newtComponent c, + struct event ev); +static void buttonPlace(newtComponent co, int newLeft, int newTop); + +static struct componentOps buttonOps = { + buttonDraw, + buttonEvent, + buttonDestroy, + buttonPlace, + newtDefaultMappedHandler, +} ; + +/* + * return NULL on malloc error. + * FIXME: all createButton calls should check for error + */ +static newtComponent createButton(int left, int row, const char * text, int compact) { + newtComponent co; + struct button * bu; + int width = wstrlen(text,-1); + + co = malloc(sizeof(*co)); + if (co == NULL) + return NULL; + bu = malloc(sizeof(struct button)); + if (bu == NULL) { + free (co); + return NULL; + } + co->data = bu; + co->destroyCallback = NULL; + + bu->text = strdup(text); + bu->compact = compact; + co->ops = &buttonOps; + + if (bu->compact) { + co->height = 1; + co->width = width + 3; + } else { + co->height = 4; + co->width = width + 5; + } + + co->top = row; + co->left = left; + co->takesFocus = 1; + co->isMapped = 0; + + newtGotorc(co->top, co->left); + + return co; + +} + +newtComponent newtCompactButton(int left, int row, const char * text) { + return createButton(left, row, text, 1); +} + +newtComponent newtButton(int left, int row, const char * text) { + return createButton(left, row, text, 0); +} + +static void buttonDestroy(newtComponent co) { + struct button * bu = co->data; + + free(bu->text); + free(bu); + free(co); +} + +static void buttonPlace(newtComponent co, int newLeft, int newTop) { + co->top = newTop; + co->left = newLeft; + + newtGotorc(co->top, co->left); +} + +static void buttonDraw(newtComponent co) { + buttonDrawIt(co, 0, 0); +} + +static void buttonDrawIt(newtComponent co, int active, int pushed) { + struct button * bu = co->data; + + if (!co->isMapped) return; + + SLsmg_set_color(NEWT_COLORSET_BUTTON); + + if (bu->compact) { + if (!active) + SLsmg_set_color(NEWT_COLORSET_COMPACTBUTTON); + else if (SLtt_Use_Ansi_Colors) + SLsmg_set_color(NEWT_COLORSET_BUTTON); + else + SLsmg_set_color(NEWT_COLORSET_ACTBUTTON); + newtGotorc(co->top+ pushed, co->left + 1 + pushed); + SLsmg_write_char('<'); + SLsmg_write_string(bu->text); + SLsmg_write_char('>'); + } else { + if (pushed) { + SLsmg_set_color(NEWT_COLORSET_BUTTON); + newtDrawBox(co->left + 1, co->top + 1, co->width - 1, 3, 0); + + SLsmg_set_color(NEWT_COLORSET_WINDOW); + newtClearBox(co->left, co->top, co->width, 1); + newtClearBox(co->left, co->top, 1, co->height); + } else { + newtDrawBox(co->left, co->top, co->width - 1, 3, 1); + } + + buttonDrawText(co, active, pushed); + } + /* put cursor at beginning of text for better accessibility */ + newtGotorc(co->top + (bu->compact ? 0 : 1) + pushed, co->left + 1 + pushed + 1); +} + +static void buttonDrawText(newtComponent co, int active, int pushed) { + struct button * bu = co->data; + + if (pushed) pushed = 1; + + if (active) + SLsmg_set_color(NEWT_COLORSET_ACTBUTTON); + else + SLsmg_set_color(NEWT_COLORSET_BUTTON); + + newtGotorc(co->top + 1 + pushed, co->left + 1 + pushed); + SLsmg_write_char(' '); + SLsmg_write_string(bu->text); + SLsmg_write_char(' '); +} + +static struct eventResult buttonEvent(newtComponent co, + struct event ev) { + struct eventResult er; + struct button * bu = co->data; + + er.result = ER_IGNORED; + + if (ev.when == EV_NORMAL) { + switch (ev.event) { + case EV_FOCUS: + buttonDrawIt(co, 1, 0); + er.result = ER_SWALLOWED; + break; + + case EV_UNFOCUS: + buttonDrawIt(co, 0, 0); + er.result = ER_SWALLOWED; + break; + + case EV_KEYPRESS: + if (ev.u.key == ' ' || ev.u.key == '\r') { + if (!bu->compact) { + /* look pushed */ + buttonDrawIt(co, 1, 1); + newtRefresh(); + newtDelay(150000); + buttonDrawIt(co, 1, 0); + newtRefresh(); + newtDelay(150000); + } + + er.result = ER_EXITFORM; + } else + er.result = ER_IGNORED; + break; + case EV_MOUSE: + if (ev.u.mouse.type == MOUSE_BUTTON_DOWN && + co->top <= ev.u.mouse.y && + co->top + co->height - !bu->compact > ev.u.mouse.y && + co->left <= ev.u.mouse.x && + co->left + co->width - !bu->compact > ev.u.mouse.x) { + if (!bu->compact) { + buttonDrawIt(co, 1, 1); + newtRefresh(); + newtDelay(150000); + buttonDrawIt(co, 1, 0); + newtRefresh(); + newtDelay(150000); + } + er.result = ER_EXITFORM; + } + break; + } + } + + return er; +} diff --git a/buttonbar.c b/buttonbar.c new file mode 100644 index 0000000..45473c9 --- /dev/null +++ b/buttonbar.c @@ -0,0 +1,46 @@ +#include + +#include "newt.h" + +/* if they try and pack more then 50 buttons, screw 'em */ +newtGrid newtButtonBarv(char * button1, newtComponent * b1comp, va_list args) { + newtGrid grid; + struct buttonInfo { + char * name; + newtComponent * compPtr; + } buttons[50]; + int num; + int i; + + buttons[0].name = button1, buttons[0].compPtr = b1comp, num = 1; + while (1) { + buttons[num].name = va_arg(args, char *); + if (!buttons[num].name) break; + buttons[num].compPtr = va_arg(args, newtComponent *); + num++; + } + + grid = newtCreateGrid(num, 1); + + for (i = 0; i < num; i++) { + *buttons[i].compPtr = newtButton(-1, -1, buttons[i].name); + newtGridSetField(grid, i, 0, NEWT_GRID_COMPONENT, + *buttons[i].compPtr, + num ? 1 : 0, 0, 0, 0, 0, 0); + } + + return grid; +} + +newtGrid newtButtonBar(char * button1, newtComponent * b1comp, ...) { + va_list args; + newtGrid grid; + + va_start(args, b1comp); + + grid = newtButtonBarv(button1, b1comp, args); + + va_end(args); + + return grid; +} diff --git a/checkbox.c b/checkbox.c new file mode 100644 index 0000000..1590762 --- /dev/null +++ b/checkbox.c @@ -0,0 +1,311 @@ +#include +#include +#include + +#include "newt.h" +#include "newt_pr.h" + +enum type { CHECK, RADIO }; + +struct checkbox { + char * text; + char * seq; + char * result; + newtComponent prevButton, lastButton; + enum type type; + char value; + int active, inactive; + const void * data; + int flags; + int hasFocus; +}; + +static void cbDraw(newtComponent c); +static void cbDestroy(newtComponent co); +struct eventResult cbEvent(newtComponent co, struct event ev); + +static struct componentOps cbOps = { + cbDraw, + cbEvent, + cbDestroy, + newtDefaultPlaceHandler, + newtDefaultMappedHandler, +} ; + +newtComponent newtRadiobutton(int left, int top, const char * text, int isDefault, + newtComponent prevButton) { + newtComponent co; + newtComponent curr; + struct checkbox * rb; + char initialValue; + + if (isDefault) + initialValue = '*'; + else + initialValue = ' '; + + co = newtCheckbox(left, top, text, initialValue, " *", NULL); + rb = co->data; + rb->type = RADIO; + + rb->prevButton = prevButton; + + for (curr = co; curr; curr = rb->prevButton) { + rb = curr->data; + rb->lastButton = co; + } + + return co; +} + +newtComponent newtRadioGetCurrent(newtComponent setMember) { + struct checkbox * rb = setMember->data; + + setMember = rb->lastButton; + rb = setMember->data; + + while (rb && rb->value != '*') { + setMember = rb->prevButton; + if (!setMember) + return NULL; + rb = setMember->data; + } + + return setMember; +} + +void newtRadioSetCurrent(newtComponent setMember) { + struct checkbox * cb = setMember->data; + struct checkbox * rb; + newtComponent curr; + + /* find the one that's turned on */ + curr = cb->lastButton; + rb = curr->data; + while (curr && rb->value == rb->seq[0]) { + curr = rb->prevButton; + if (curr) rb = curr->data; + } + if (curr) { + rb->value = rb->seq[0]; + cbDraw(curr); + } + cb->value = cb->seq[1]; + cbDraw(setMember); + + if (setMember->callback) + setMember->callback(setMember, setMember->callbackData); +} + +char newtCheckboxGetValue(newtComponent co) { + struct checkbox * cb = co->data; + + return cb->value; +} + +void newtCheckboxSetValue(newtComponent co, char value) { + struct checkbox * cb = co->data; + + *cb->result = value; + cbDraw(co); +} + +/* + * returns NULL on error. + * FIXME: Check all calls. + */ +newtComponent newtCheckbox(int left, int top, const char * text, char defValue, + const char * seq, char * result) { + newtComponent co; + struct checkbox * cb; + + if (!seq) seq = " *"; + + co = malloc(sizeof(*co)); + if (co == NULL) + return NULL; + cb = malloc(sizeof(struct checkbox)); + if (cb == NULL) { + free(co); + return NULL; + } + co->data = cb; + cb->flags = 0; + if (result) + cb->result = result; + else + cb->result = &cb->value; + + cb->text = strdup(text); + cb->seq = strdup(seq); + cb->type = CHECK; + cb->hasFocus = 0; + cb->inactive = COLORSET_CHECKBOX; + cb->active = COLORSET_ACTCHECKBOX; + defValue ? (*cb->result = defValue) : (*cb->result = cb->seq[0]); + + co->ops = &cbOps; + + co->callback = NULL; + co->destroyCallback = NULL; + co->height = 1; + co->width = wstrlen(text, -1) + 4; + co->top = top; + co->left = left; + co->takesFocus = 1; + co->isMapped = 0; + + return co; +} + +void newtCheckboxSetFlags(newtComponent co, int flags, enum newtFlagsSense sense) { + struct checkbox * cb = co->data; + int row, col; + + cb->flags = newtSetFlags(cb->flags, flags, sense); + + // If the flag just sets a property (eg. NEWT_FLAG_RETURNEXIT), + // don't redraw, etc. as the component might be 'hidden' and not to + // be drawn (eg. in a scrolled list) + if (flags == NEWT_FLAG_RETURNEXIT) + return; + + if (!(cb->flags & NEWT_FLAG_DISABLED)) + co->takesFocus = 1; + else + co->takesFocus = 0; + + newtGetrc(&row, &col); + cbDraw(co); + newtGotorc(row, col); +} + +static void cbDraw(newtComponent c) { + struct checkbox * cb = c->data; + + if (!c->isMapped) return; + + if (cb->flags & NEWT_FLAG_DISABLED) { + cb->inactive = NEWT_COLORSET_DISENTRY; + cb->active = NEWT_COLORSET_DISENTRY; + } else { + cb->inactive = COLORSET_CHECKBOX; + cb->active = COLORSET_ACTCHECKBOX; + } + + SLsmg_set_color(cb->inactive); + + newtGotorc(c->top, c->left); + + switch (cb->type) { + case RADIO: + SLsmg_write_string("( ) "); + break; + + case CHECK: + SLsmg_write_string("[ ] "); + break; + + default: + break; + } + + SLsmg_write_string(cb->text); + + if (cb->hasFocus) + SLsmg_set_color(cb->active); + + newtGotorc(c->top, c->left + 1); + SLsmg_write_char(*cb->result); + newtGotorc(c->top, c->left + 4); +} + +static void cbDestroy(newtComponent co) { + struct checkbox * cb = co->data; + + free(cb->text); + free(cb->seq); + free(cb); + free(co); +} + +struct eventResult cbEvent(newtComponent co, struct event ev) { + struct checkbox * cb = co->data; + struct eventResult er; + const char * cur; + + er.result = ER_IGNORED; + + if (ev.when == EV_NORMAL) { + switch (ev.event) { + case EV_FOCUS: + cb->hasFocus = 1; + cbDraw(co); + er.result = ER_SWALLOWED; + break; + + case EV_UNFOCUS: + cb->hasFocus = 0; + cbDraw(co); + er.result = ER_SWALLOWED; + break; + + case EV_KEYPRESS: + if (ev.u.key == ' ') { + if (cb->type == RADIO) { + newtRadioSetCurrent(co); + } else if (cb->type == CHECK) { + cur = strchr(cb->seq, *cb->result); + if (!cur) + *cb->result = *cb->seq; + else { + cur++; + if (! *cur) + *cb->result = *cb->seq; + else + *cb->result = *cur; + } + cbDraw(co); + er.result = ER_SWALLOWED; + + if (co->callback) + co->callback(co, co->callbackData); + } else { + er.result = ER_IGNORED; + } + } else if(ev.u.key == NEWT_KEY_ENTER) { + if (cb->flags & NEWT_FLAG_RETURNEXIT) + er.result = ER_EXITFORM; + else + er.result = ER_IGNORED; + } else { + er.result = ER_IGNORED; + } + break; + case EV_MOUSE: + if (ev.u.mouse.type == MOUSE_BUTTON_DOWN) { + if (cb->type == RADIO) { + newtRadioSetCurrent(co); + } else if (cb->type == CHECK) { + cur = strchr(cb->seq, *cb->result); + if (!cur) + *cb->result = *cb->seq; + else { + cur++; + if (! *cur) + *cb->result = *cb->seq; + else + *cb->result = *cur; + } + cbDraw(co); + er.result = ER_SWALLOWED; + + if (co->callback) + co->callback(co, co->callbackData); + } + } + } + } + + return er; +} diff --git a/checkboxtree.c b/checkboxtree.c new file mode 100644 index 0000000..95156eb --- /dev/null +++ b/checkboxtree.c @@ -0,0 +1,832 @@ +#include +#include +#include + +#include "newt.h" +#include "newt_pr.h" + +struct items { + char * text; + const void *data; + unsigned char selected; + struct items *next; + struct items *prev; + struct items *branch; + int flags; + int depth; +}; + +struct CheckboxTree { + newtComponent sb; + struct items * itemlist; + struct items ** flatList, ** currItem, ** firstItem; + int flatCount; + int flags; + int sbAdjust; + int curWidth; + int userHasSetWidth; + int isActive; + char * seq; + char * result; +}; + +static void ctDraw(newtComponent c); +static void ctDestroy(newtComponent co); +static void ctPlace(newtComponent co, int newLeft, int newTop); +struct eventResult ctEvent(newtComponent co, struct event ev); +static void ctMapped(newtComponent co, int isMapped); +static struct items * findItem(struct items * items, const void * data); +static void buildFlatList(newtComponent co); +static void doBuildFlatList(struct CheckboxTree * ct, struct items * item); +static int countItems(struct items * item, int what); +static inline void updateWidth(newtComponent co, struct CheckboxTree * ct, + int maxField); + +static struct componentOps ctOps = { + ctDraw, + ctEvent, + ctDestroy, + ctPlace, + ctMapped, +} ; + +static inline void updateWidth(newtComponent co, struct CheckboxTree * ct, + int maxField) { + ct->curWidth = maxField; + co->width = ct->curWidth + ct->sbAdjust; + + if (ct->sb) + ct->sb->left = co->left + co->width - 1; +} + +static int countItems(struct items * item, int what) { + int count = 0; + + while (item) { + if (what < 0 || (!item->branch && ((what > 0 && item->selected == what) + || (what == 0 && item->selected)))) + count++; + if (item->branch && (what >= 0 || (what < 0 && item->selected))) + count += countItems(item->branch, what); + item = item->next; + } + + return count; +} + +static void doBuildFlatList(struct CheckboxTree * ct, struct items * item) { + while (item) { + ct->flatList[ct->flatCount++] = item; + if (item->branch && item->selected) doBuildFlatList(ct, item->branch); + item = item->next; + } +} + +/* FIXME: Check what happens on malloc failure. + */ +static void buildFlatList(newtComponent co) { + struct CheckboxTree * ct = co->data; + + if (ct->flatList) free(ct->flatList); + ct->flatCount = countItems(ct->itemlist, -1); + + ct->flatList = malloc(sizeof(*ct->flatList) * (ct->flatCount+1)); + ct->flatCount = 0; + doBuildFlatList(ct, ct->itemlist); + ct->flatList[ct->flatCount] = NULL; +} + +int newtCheckboxTreeAddItem(newtComponent co, + const char * text, const void * data, + int flags, int index, ...) { + va_list argList; + int numIndexes; + int * indexes; + int i; + + va_start(argList, index); + numIndexes = 0; + i = index; + while (i != NEWT_ARG_LAST) { + numIndexes++; + i = va_arg(argList, int); + } + + va_end(argList); + + indexes = alloca(sizeof(*indexes) * (numIndexes + 1)); + va_start(argList, index); + numIndexes = 0; + i = index; + while (i != NEWT_ARG_LAST) { + indexes[numIndexes++] = i; + i = va_arg(argList, int); + } + va_end(argList); + + indexes[numIndexes++] = NEWT_ARG_LAST; + + return newtCheckboxTreeAddArray(co, text, data, flags, indexes); +} + +static int doFindItemPath(struct items * items, void * data, int * path, + int * len) { + int where = 0; + + while (items) { + if (items->data == data) { + if (path) path[items->depth] = where; + if (len) *len = items->depth + 1; + return 1; + } + + if (items->branch && doFindItemPath(items->branch, data, path, len)) { + if (path) path[items->depth] = where; + return 1; + } + + items = items->next; + where++; + } + + return 0; +} + +int * newtCheckboxTreeFindItem(newtComponent co, void * data) { + int len; + int * path; + struct CheckboxTree * ct = co->data; + + if (!doFindItemPath(ct->itemlist, data, NULL, &len)) return NULL; + + path = malloc(sizeof(*path) * (len + 1)); + doFindItemPath(ct->itemlist, data, path, NULL); + path[len] = NEWT_ARG_LAST; + + return path; +} + +int newtCheckboxTreeAddArray(newtComponent co, + const char * text, const void * data, + int flags, int * indexes) { + struct items * curList, * newNode, * item = NULL; + struct items ** listPtr = NULL; + int i, index, numIndexes, width; + struct CheckboxTree * ct = co->data; + + numIndexes = 0; + while (indexes[numIndexes] != NEWT_ARG_LAST) numIndexes++; + + if (!ct->itemlist) { + if (numIndexes > 1) return -1; + + ct->itemlist = malloc(sizeof(*ct->itemlist)); // FIXME: Error check? + item = ct->itemlist; + item->prev = NULL; + item->next = NULL; + } else { + curList = ct->itemlist; + listPtr = &ct->itemlist; + + i = 0; + index = indexes[i]; + while (i < numIndexes) { + item = curList; + + if (index == NEWT_ARG_APPEND) { + item = NULL; + } else { + while (index && item) + item = item->next, index--; + } + + i++; + if (i < numIndexes) { + if (item == NULL) + return -1; + curList = item->branch; + listPtr = &item->branch; + if (!curList && (i + 1 != numIndexes)) return -1; + + index = indexes[i]; + } + } + + if (!curList) { /* create a new branch */ + item = malloc(sizeof(*curList->prev)); + item->next = item->prev = NULL; + *listPtr = item; + } else if (!item) { /* append to end */ + item = curList; + while (item->next) item = item->next; + item->next = malloc(sizeof(*curList->prev)); // FIXME Error check + item->next->prev = item; + item = item->next; + item->next = NULL; + } else { + newNode = malloc(sizeof(*newNode)); // FIXME Error check ? + newNode->prev = item->prev; + newNode->next = item; + + if (item->prev) item->prev->next = newNode; + item->prev = newNode; + item = newNode; + if (!item->prev) *listPtr = item; + } + } + + item->text = strdup(text); + item->data = data; + if (flags & NEWT_FLAG_SELECTED) { + item->selected = 1; + } else { + item->selected = 0; + } + item->flags = flags; + item->branch = NULL; + item->depth = numIndexes - 1; + + i = 4 + (3 * item->depth); + width = wstrlen(text, -1); + + if ((ct->userHasSetWidth == 0) && ((width + i + ct->sbAdjust) > co->width)) { + updateWidth(co, ct, width + i); + } + + return 0; +} + +static struct items * findItem(struct items * items, const void * data) { + struct items * i; + + while (items) { + if (items->data == data) return items; + if (items->branch) { + i = findItem(items->branch, data); + if (i) return i; + } + + items = items->next; + } + + return NULL; +} + +static void listSelected(struct items * items, int * num, const void ** list, int seqindex) { + while (items) { + if ((seqindex ? items->selected==seqindex : items->selected) && !items->branch) + list[(*num)++] = (void *) items->data; + if (items->branch) + listSelected(items->branch, num, list, seqindex); + items = items->next; + } +} + +void newtCheckboxTreeSetWidth(newtComponent co, int width) { + struct CheckboxTree * ct = co->data; + + co->width = width; + ct->curWidth = co->width - ct->sbAdjust; + ct->userHasSetWidth = 1; + if (ct->sb) ct->sb->left = co->width + co->left - 1; + ctDraw(co); +} + +const void ** newtCheckboxTreeGetSelection(newtComponent co, int *numitems) +{ + return newtCheckboxTreeGetMultiSelection(co, numitems, 0); +} + +const void ** newtCheckboxTreeGetMultiSelection(newtComponent co, int *numitems, char seqnum) +{ + struct CheckboxTree * ct; + const void **retval; + int seqindex=0; + + if(!co || !numitems) return NULL; + + ct = co->data; + + if (seqnum) { + while( ct->seq[seqindex] && ( ct->seq[seqindex] != seqnum )) seqindex++; + } else { + seqindex = 0; + } + + *numitems = countItems(ct->itemlist, seqindex); + if (!*numitems) return NULL; + + retval = malloc(*numitems * sizeof(void *)); + *numitems = 0; + listSelected(ct->itemlist, numitems, retval, seqindex); + + return retval; +} + +newtComponent newtCheckboxTree(int left, int top, int height, int flags) { + return newtCheckboxTreeMulti(left, top, height, NULL, flags); +} + +newtComponent newtCheckboxTreeMulti(int left, int top, int height, char *seq, int flags) { + newtComponent co; + struct CheckboxTree * ct; + + co = malloc(sizeof(*co)); + ct = malloc(sizeof(struct CheckboxTree)); + co->callback = NULL; + co->destroyCallback = NULL; + co->data = ct; + co->left = left; + co->top = top; + co->ops = &ctOps; + co->takesFocus = 1; + co->height = height; + co->width = 0; + co->isMapped = 0; + ct->curWidth = 0; + ct->isActive = 0; + ct->userHasSetWidth = 0; + ct->itemlist = NULL; + ct->firstItem = NULL; + ct->currItem = NULL; + ct->flatList = NULL; + + ct->flags = flags; + + if (seq) + ct->seq = strdup(seq); + else + ct->seq = strdup(" *"); + if (flags & NEWT_FLAG_SCROLL) { + ct->sb = newtVerticalScrollbar(left, top, height, + COLORSET_LISTBOX, COLORSET_ACTLISTBOX); + ct->sbAdjust = 2; + } else { + ct->sb = NULL; + ct->sbAdjust = 0; + } + + return co; +} + +static void ctMapped(newtComponent co, int isMapped) { + struct CheckboxTree * ct = co->data; + + co->isMapped = isMapped; + if (ct->sb) + ct->sb->ops->mapped(ct->sb, isMapped); +} + +static void ctPlace(newtComponent co, int newLeft, int newTop) { + struct CheckboxTree * ct = co->data; + + co->top = newTop; + co->left = newLeft; + + if (ct->sb) + ct->sb->ops->place(ct->sb, co->left + co->width - 1, co->top); +} + +int ctSetItem(newtComponent co, struct items *item, enum newtFlagsSense sense) +{ + struct CheckboxTree * ct = co->data; + struct items * currItem; + struct items * firstItem; + + if (!item) + return 1; + + switch(sense) { + case NEWT_FLAGS_RESET: + item->selected = 0; + break; + case NEWT_FLAGS_SET: + item->selected = 1; + break; + case NEWT_FLAGS_TOGGLE: + if (item->branch) + item->selected = !item->selected; + else if (!(ct->flags & NEWT_CHECKBOXTREE_UNSELECTABLE)) { + item->selected++; + if (item->selected==strlen(ct->seq)) + item->selected = 0; + } + break; + } + + if (item->branch) { + currItem = *ct->currItem; + firstItem = *ct->firstItem; + + buildFlatList(co); + + ct->currItem = ct->flatList; + while (*ct->currItem != currItem) ct->currItem++; + + ct->firstItem = ct->flatList; + if (ct->flatCount > co->height) { + struct items ** last = ct->flatList + ct->flatCount - co->height; + while (*ct->firstItem != firstItem && ct->firstItem != last) + ct->firstItem++; + } + } + + return 0; +} + +static void ctSetItems(struct items *item, int selected) +{ + for (; item; item = item->next) { + if (!item->branch) + item->selected = selected; + else + ctSetItems(item->branch, selected); + } +} + +static void ctDraw(newtComponent co) { + struct CheckboxTree * ct = co->data; + struct items ** item; + int i, j; + char * spaces; + int currRow = co->top; + + if (!co->isMapped) return ; + + if (!ct->firstItem) { + buildFlatList(co); + ct->firstItem = ct->currItem = ct->flatList; + } + + item = ct->firstItem; + + i = 0; + + newtTrashScreen(); + + while (*item && i < co->height) { + newtGotorc(co->top + i, co->left); + SLsmg_set_color(NEWT_COLORSET_LISTBOX); + for (j = 0; j < (*item)->depth; j++) + SLsmg_write_string(" "); + + if ((*item)->branch) { + if ((*item)->selected) + SLsmg_write_string("<-> "); + else + SLsmg_write_string("<+> "); + } else { + if (ct->flags & NEWT_CHECKBOXTREE_HIDE_BOX) { + if ((*item)->selected) + SLsmg_set_color(NEWT_COLORSET_SELLISTBOX); + SLsmg_write_string(" "); + } else { + char tmp[5]; + snprintf(tmp,5,"[%c] ",ct->seq[(*item)->selected]); + SLsmg_write_string(tmp); + } + } + if (*item == *ct->currItem) { + SLsmg_set_color(ct->isActive ? + NEWT_COLORSET_ACTSELLISTBOX : NEWT_COLORSET_ACTLISTBOX); + currRow = co->top + i; + } + + SLsmg_write_nstring((*item)->text, co->width - 4 - (3 * (*item)->depth)); + + item++; + i++; + } + + /* There could be empty lines left (i.e. if the user closes an expanded + list which is the last thing in the tree, and whose elements are + displayed at the bottom of the screen */ + if (i < co->height) { + spaces = alloca(co->width + 1); + memset(spaces, ' ', co->width); + spaces[co->width] = '\0'; + SLsmg_set_color(NEWT_COLORSET_LISTBOX); + + while (i < co->height) { + newtGotorc(co->top + i, co->left); + SLsmg_write_nstring(spaces, co->width); + i++; + } + } + + if(ct->sb) { + newtScrollbarSet(ct->sb, ct->currItem - ct->flatList, + ct->flatCount - 1); + ct->sb->ops->draw(ct->sb); + } + + newtGotorc(currRow, co->left + + (*ct->currItem ? (*ct->currItem)->depth : 0) * 3 + 4); +} + +static void destroyItems(struct items * item) { + struct items * nextitem; + + while (item != NULL) { + nextitem = item->next; + free(item->text); + if (item->branch) + destroyItems(item->branch); + free(item); + item = nextitem; + } +} + +static void ctDestroy(newtComponent co) { + struct CheckboxTree * ct = co->data; + + destroyItems(ct->itemlist); + free(ct->flatList); + if (ct->sb) + ct->sb->ops->destroy(ct->sb); + free(ct->seq); + free(ct); + free(co); +} + +static void ctEnsureLimits( struct CheckboxTree *ct ) { + struct items **listEnd = ct->flatList + ct->flatCount - 1; + if (ct->firstItem < ct->flatList) + ct->firstItem = ct->flatList; + if (ct->currItem < ct->flatList) + ct->currItem = ct->flatList; + if (ct->firstItem > listEnd) { + ct->firstItem = listEnd; + ct->currItem = listEnd; + } +} + +struct eventResult ctEvent(newtComponent co, struct event ev) { + struct CheckboxTree * ct = co->data; + struct eventResult er; + struct items ** listEnd, ** lastItem; + int key, selnum = 1; + + er.result = ER_IGNORED; + + if(ev.when == EV_EARLY || ev.when == EV_LATE) { + return er; + } + + switch(ev.event) { + case EV_KEYPRESS: + key = ev.u.key; + if (key == (char) key && key != ' ') { + for (selnum = 0; ct->seq[selnum]; selnum++) + if (key == ct->seq[selnum]) + break; + if (!ct->seq[selnum]) + switch (key) { + case '-': selnum = 0; break; + case '+': + case '*': selnum = 1; break; + } + if (ct->seq[selnum]) + key = '*'; + } + switch(key) { + case ' ': + case NEWT_KEY_ENTER: + ctSetItem(co, *ct->currItem, NEWT_FLAGS_TOGGLE); + er.result = ER_SWALLOWED; + if (!(*ct->currItem)->branch || (*ct->currItem)->selected) + key = NEWT_KEY_DOWN; + else + key = '*'; + break; + case '*': + if ((*ct->currItem)->branch) { + ctSetItems((*ct->currItem)->branch, selnum); + if (!(*ct->currItem)->selected) + key = NEWT_KEY_DOWN; + } else { + (*ct->currItem)->selected = selnum; + key = NEWT_KEY_DOWN; + } + er.result = ER_SWALLOWED; + break; + } + switch (key) { + case '*': + ctDraw(co); + if(co->callback) co->callback(co, co->callbackData); + return er; + case NEWT_KEY_HOME: + ct->currItem = ct->flatList; + ct->firstItem = ct->flatList; + ctDraw(co); + if(co->callback) co->callback(co, co->callbackData); + er.result = ER_SWALLOWED; + return er; + case NEWT_KEY_END: + ct->currItem = ct->flatList + ct->flatCount - 1; + if (ct->flatCount <= co->height) + ct->firstItem = ct->flatList; + else + ct->firstItem = ct->flatList + ct->flatCount - co->height; + ctDraw(co); + if(co->callback) co->callback(co, co->callbackData); + er.result = ER_SWALLOWED; + return er; + case NEWT_KEY_DOWN: + if (ev.u.key != NEWT_KEY_DOWN) { + if(co->callback) co->callback(co, co->callbackData); + if (strlen(ct->seq) != 2) { + ctDraw(co); + return er; + } + } + if ((ct->currItem - ct->flatList + 1) < ct->flatCount) { + ct->currItem++; + + if (ct->currItem - ct->firstItem >= co->height) + ct->firstItem++; + + ctDraw(co); + } else if (ev.u.key != NEWT_KEY_DOWN) + ctDraw(co); + if(co->callback) co->callback(co, co->callbackData); + er.result = ER_SWALLOWED; + return er; + case NEWT_KEY_UP: + if (ct->currItem != ct->flatList) { + ct->currItem--; + + if (ct->currItem < ct->firstItem) + ct->firstItem = ct->currItem; + + ctDraw(co); + } + er.result = ER_SWALLOWED; + if(co->callback) co->callback(co, co->callbackData); + return er; + case NEWT_KEY_PGUP: + if (ct->firstItem - co->height < ct->flatList) { + ct->firstItem = ct->currItem = ct->flatList; + } else { + ct->currItem -= co->height; + ct->firstItem -= co->height; + } + ctEnsureLimits( ct ); + + ctDraw(co); + if(co->callback) co->callback(co, co->callbackData); + er.result = ER_SWALLOWED; + return er; + case NEWT_KEY_PGDN: + listEnd = ct->flatList + ct->flatCount - 1; + lastItem = ct->firstItem + co->height - 1; + + if (lastItem + co->height > listEnd) { + ct->firstItem = listEnd - co->height + 1; + ct->currItem = listEnd; + } else { + ct->currItem += co->height; + ct->firstItem += co->height; + } + ctEnsureLimits( ct ); + + ctDraw(co); + if(co->callback) co->callback(co, co->callbackData); + er.result = ER_SWALLOWED; + return er; + } + break; + + case EV_FOCUS: + ct->isActive = 1; + ctDraw(co); + er.result = ER_SWALLOWED; + break; + + case EV_UNFOCUS: + ct->isActive = 0; + ctDraw(co); + er.result = ER_SWALLOWED; + break; + default: + break; + } + + return er; +} + +const void * newtCheckboxTreeGetCurrent(newtComponent co) { + struct CheckboxTree * ct = co->data; + + if (!ct->currItem) { + if (ct->itemlist) + return ct->itemlist->data; + else + return NULL; + } + + return (*ct->currItem)->data; +} + +void newtCheckboxTreeSetEntry(newtComponent co, const void * data, const char * text) +{ + struct CheckboxTree * ct; + struct items * item; + int i, width; + + if (!co) return; + ct = co->data; + item = findItem(ct->itemlist, data); + if (!item) return; + + free(item->text); + item->text = strdup(text); + + i = 4 + (3 * item->depth); + + width = wstrlen(text, -1); + if ((ct->userHasSetWidth == 0) && ((width + i + ct->sbAdjust) > co->width)) { + updateWidth(co, ct, width + i); + } + + ctDraw(co); +} + +char newtCheckboxTreeGetEntryValue(newtComponent co, const void * data) +{ + struct CheckboxTree * ct; + struct items * item; + + if (!co) return -1; + ct = co->data; + item = findItem(ct->itemlist, data); + if (!item) return -1; + if (item->branch) + return item->selected ? NEWT_CHECKBOXTREE_EXPANDED : NEWT_CHECKBOXTREE_COLLAPSED; + else + return ct->seq[item->selected]; +} + +void newtCheckboxTreeSetEntryValue(newtComponent co, const void * data, char value) +{ + struct CheckboxTree * ct; + struct items * item; + int i; + + if (!co) return; + ct = co->data; + item = findItem(ct->itemlist, data); + if (!item || item->branch) return; + + for(i = 0; ct->seq[i]; i++) + if (value == ct->seq[i]) + break; + + if (!ct->seq[i]) return; + item->selected = i; + + ctDraw(co); +} + + +void newtCheckboxTreeSetCurrent(newtComponent co, void * data) { + struct CheckboxTree * ct = co->data; + int * path; + int i, j; + struct items * treeTop, * item; + + path = newtCheckboxTreeFindItem(co, data); + if (!path) return; + + /* traverse the path and turn on all of the branches to this point */ + for (i = 0, treeTop = ct->itemlist; path[i + 1] != NEWT_ARG_LAST; i++) { + for (j = 0, item = treeTop; j < path[i]; j++) + item = item->next; + + item->selected = 1; + treeTop = item->branch; + } + + free(path); + buildFlatList(co); + + item = findItem(ct->itemlist, data); + + i = 0; + while (ct->flatList[i] != item) i++; + + /* choose the top item */ + j = i - (co->height / 2); + + if ((j + co->height) > ct->flatCount) + j = ct->flatCount - co->height; + + if (j < 0) + j = 0; + + ct->firstItem = ct->flatList + j; + ct->currItem = ct->flatList + i; + + ctDraw(co); +} diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..0725c98 --- /dev/null +++ b/config.h.in @@ -0,0 +1,96 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if NLS support is enabled */ +#undef ENABLE_NLS + +/* Define to 1 if you have the header file. */ +#undef HAVE_ALLOCA_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBINTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_POPT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Default NEWT_COLORS_FILE */ +#undef NEWT_COLORS_FILE + +/* Package Name */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* The size of `long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* The size of `long long', as computed by sizeof. */ +#undef SIZEOF_LONG_LONG + +/* The size of `void *', as computed by sizeof. */ +#undef SIZEOF_VOID_P + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if GPM support is enabled */ +#undef USE_GPM + +/* NEWT Version String */ +#undef VERSION + +/* Enable large inode numbers on Mac OS X 10.5. */ +#ifndef _DARWIN_USE_64_BIT_INODE +# define _DARWIN_USE_64_BIT_INODE 1 +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES diff --git a/configure b/configure new file mode 100755 index 0000000..8b7717f --- /dev/null +++ b/configure @@ -0,0 +1,5437 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= +PACKAGE_URL= + +ac_unique_file="newt_pr.h" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='LTLIBOBJS +LIBOBJS +WHIPTCLLIB +TCL_LIB_FLAG +PYTHONVERS +GNU_LD +EGREP +CPP +GREP +LN_S +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +SONAME +VERSION +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_largefile +with_python +with_tcl +with_gpm_support +enable_nls +with_colorsfile +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-largefile omit support for large files + --disable-nls compile without NLS support + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --without-python do not compile python support + --without-tcl do not compile whiptcl.so + --with-gpm-support compile with GPM support + --with-colorsfile=file set default location of colors file + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES +# -------------------------------------------- +# Tries to find the compile-time value of EXPR in a program that includes +# INCLUDES, setting VAR accordingly. Returns whether the value could be +# computed +ac_fn_c_compute_int () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=0 ac_mid=0 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid; break +else + as_fn_arith $ac_mid + 1 && ac_lo=$as_val + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) < 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=-1 ac_mid=-1 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=$ac_mid; break +else + as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + ac_lo= ac_hi= +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid +else + as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in #(( +?*) eval "$3=\$ac_lo"; ac_retval=0 ;; +'') ac_retval=1 ;; +esac + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +static long int longval () { return $2; } +static unsigned long int ulongval () { return $2; } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (($2) < 0) + { + long int i = longval (); + if (i != ($2)) + return 1; + fprintf (f, "%ld", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ($2)) + return 1; + fprintf (f, "%lu", i); + } + /* Do not output a trailing newline, as this causes \r\n confusion + on some platforms. */ + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + echo >>conftest.val; read $3 &5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +PACKAGE=newt +VERSION=0.52.20 +SONAME=0.52 + +ac_config_headers="$ac_config_headers config.h" + + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + + +# Check whether --enable-largefile was given. +if test "${enable_largefile+set}" = set; then : + enableval=$enable_largefile; +fi + +if test "$enable_largefile" != no; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 +$as_echo_n "checking for special C compiler options needed for large files... " >&6; } +if ${ac_cv_sys_largefile_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_sys_largefile_CC=no + if test "$GCC" != yes; then + ac_save_CC=$CC + while :; do + # IRIX 6.2 and later do not support large files by default, + # so use the C compiler's -n32 option if that helps. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF + if ac_fn_c_try_compile "$LINENO"; then : + break +fi +rm -f core conftest.err conftest.$ac_objext + CC="$CC -n32" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_largefile_CC=' -n32'; break +fi +rm -f core conftest.err conftest.$ac_objext + break + done + CC=$ac_save_CC + rm -f conftest.$ac_ext + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 +$as_echo "$ac_cv_sys_largefile_CC" >&6; } + if test "$ac_cv_sys_largefile_CC" != no; then + CC=$CC$ac_cv_sys_largefile_CC + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 +$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } +if ${ac_cv_sys_file_offset_bits+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _FILE_OFFSET_BITS 64 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=64; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_file_offset_bits=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 +$as_echo "$ac_cv_sys_file_offset_bits" >&6; } +case $ac_cv_sys_file_offset_bits in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits +_ACEOF +;; +esac +rm -rf conftest* + if test $ac_cv_sys_file_offset_bits = unknown; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 +$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } +if ${ac_cv_sys_large_files+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _LARGE_FILES 1 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=1; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_large_files=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 +$as_echo "$ac_cv_sys_large_files" >&6; } +case $ac_cv_sys_large_files in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _LARGE_FILES $ac_cv_sys_large_files +_ACEOF +;; +esac +rm -rf conftest* + fi + + +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 +$as_echo_n "checking size of long... " >&6; } +if ${ac_cv_sizeof_long+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 +$as_echo "$ac_cv_sizeof_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5 +$as_echo_n "checking size of long long... " >&6; } +if ${ac_cv_sizeof_long_long+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_long_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_long_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5 +$as_echo "$ac_cv_sizeof_long_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5 +$as_echo_n "checking size of void *... " >&6; } +if ${ac_cv_sizeof_void_p+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_void_p" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (void *) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_void_p=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5 +$as_echo "$ac_cv_sizeof_void_p" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_VOID_P $ac_cv_sizeof_void_p +_ACEOF + + + +# Are we using GNU ld? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +LD=`$CC -print-prog-name=ld 2>&5` + +if test `$LD -v 2>&1 | $ac_cv_path_GREP -c "GNU ld"` = 0; then + # Not + GNU_LD="" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +else + GNU_LD="$LD" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + +for ac_header in sys/select.h alloca.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +ac_fn_c_check_header_mongrel "$LINENO" "slang.h" "ac_cv_header_slang_h" "$ac_includes_default" +if test "x$ac_cv_header_slang_h" = xyes; then : + +else + + old_CPPFLAGS=${CPPFLAGS} + CPPFLAGS="${CPPFLAGS} -I/opt/local/include" + unset ac_cv_header_slang_h + ac_fn_c_check_header_mongrel "$LINENO" "slang.h" "ac_cv_header_slang_h" "$ac_includes_default" +if test "x$ac_cv_header_slang_h" = xyes; then : + +fi + + + if test x$ac_cv_header_slang_h = x; then + CPPFLAGS="${old_CPPFLAGS}" + else + LDFLAGS="${LDFLAGS} -L/opt/local/lib" + fi + +fi + + +if test x$ac_cv_header_slang_h = x; then + old_CPPFLAGS=${CPPFLAGS} + CPPFLAGS="${CPPFLAGS} -I/sw/include" + ac_fn_c_check_header_mongrel "$LINENO" "slang.h" "ac_cv_header_slang_h" "$ac_includes_default" +if test "x$ac_cv_header_slang_h" = xyes; then : + +fi + + + if test x$ac_cv_header_slang_h = x; then + CPPFLAGS=${old_CPPFLAGS} + else + LDFLAGS="${LDFLAGS} -L/sw/lib" + fi +fi +for ac_header in popt.h libintl.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for python versions" >&5 +$as_echo_n "checking for python versions... " >&6; } + +# Check whether --with-python was given. +if test "${with_python+set}" = set; then : + withval=$with_python; +fi + +if test "x$with_python" = "xno"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: skipped" >&5 +$as_echo "skipped" >&6; } + PYTHONVERS= +else + PYTHONVERS=$(ls /usr/include/python*/Python.h 2> /dev/null | sed 's|.*\(python[0-9]*\.[0-9]*\).*|\1|g' | tr '\n' ' ') + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHONVERS" >&5 +$as_echo "$PYTHONVERS" >&6; } +fi + + + +# Check whether --with-tcl was given. +if test "${with_tcl+set}" = set; then : + withval=$with_tcl; +fi + +if test "x$with_tcl" = "xno"; then + WHIPTCLLIB= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tcl configuration" >&5 +$as_echo_n "checking for tcl configuration... " >&6; } + + # check in a few common install locations + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in `ls -d ${libdir} 2>/dev/null` \ + `ls -d /usr/lib 2>/dev/null` \ + `ls -d /usr/lib64 2>/dev/null` \ + `ls -d /usr/local/lib 2>/dev/null` \ + `ls -d /usr/contrib/lib 2>/dev/null` \ + `ls -d /usr/pkg/lib 2>/dev/null` \ + `ls -d /usr/local/lib/tcl8.5 2>/dev/null` \ + `ls -d /usr/local/lib/tcl8.4 2>/dev/null` \ + `ls -d /usr/lib/tcl8.5 2>/dev/null` \ + `ls -d /usr/lib/tcl8.4 2>/dev/null` \ + `ls -d /opt/local/lib 2>/dev/null` \ + ; do + if test -f "$i/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd $i; pwd)` + break + fi + done + fi + + if test x"${ac_cv_c_tclconfig}" != x ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5 +$as_echo "found" >&6; } + . ${ac_cv_c_tclconfig}/tclConfig.sh + + WHIPTCLLIB=whiptcl + # needed with tcl8.6 + CPPFLAGS="$CPPFLAGS -DUSE_INTERP_RESULT" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: NOT found" >&5 +$as_echo "NOT found" >&6; } + fi +fi + + + +# Check whether --with-gpm-support was given. +if test "${with_gpm_support+set}" = set; then : + withval=$with_gpm_support; +fi + + +if test "x$with_gpm_support" = "xyes"; then + +$as_echo "#define USE_GPM 1" >>confdefs.h + +fi + +# Check whether --enable-nls was given. +if test "${enable_nls+set}" = set; then : + enableval=$enable_nls; +fi + + +if test "x$enable_nls" != "xno"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gettext in -lc" >&5 +$as_echo_n "checking for gettext in -lc... " >&6; } +if ${ac_cv_lib_c_gettext+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lc $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gettext (); +int +main () +{ +return gettext (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_c_gettext=yes +else + ac_cv_lib_c_gettext=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_gettext" >&5 +$as_echo "$ac_cv_lib_c_gettext" >&6; } +if test "x$ac_cv_lib_c_gettext" = xyes; then : + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gettext in -lintl" >&5 +$as_echo_n "checking for gettext in -lintl... " >&6; } +if ${ac_cv_lib_intl_gettext+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lintl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gettext (); +int +main () +{ +return gettext (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_intl_gettext=yes +else + ac_cv_lib_intl_gettext=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_gettext" >&5 +$as_echo "$ac_cv_lib_intl_gettext" >&6; } +if test "x$ac_cv_lib_intl_gettext" = xyes; then : + + LIBS="-lintl" + +else + + if test "x$enable_nls" != "xcheck"; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "--enable-nls was specified, but the configure check failed +See \`config.log' for more details" "$LINENO" 5; } + else + enable_nls=no + fi + +fi + + +fi + + if test "x$enable_nls" != "xno"; then + +$as_echo "#define ENABLE_NLS 1" >>confdefs.h + + fi +fi + + +# Check whether --with-colorsfile was given. +if test "${with_colorsfile+set}" = set; then : + withval=$with_colorsfile; +fi + + +if test "x$with_colorsfile" != "xno"; then + if test "x$with_colorsfile" != "xyes"; then + if test "x$with_colorsfile" != "x"; then + +cat >>confdefs.h <<_ACEOF +#define NEWT_COLORS_FILE "$with_colorsfile" +_ACEOF + + fi + fi +fi + +ac_config_files="$ac_config_files Makefile libnewt.pc" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "libnewt.pc") CONFIG_FILES="$CONFIG_FILES libnewt.pc" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi + ;; + + + esac + +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..d33489d --- /dev/null +++ b/configure.ac @@ -0,0 +1,149 @@ +AC_INIT([newt_pr.h]) + +PACKAGE=newt +VERSION=0.52.20 +SONAME=0.52 + +AC_CONFIG_HEADER([config.h]) + +AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Package Name]) +AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [NEWT Version String]) +AC_SUBST([VERSION]) +AC_SUBST([SONAME]) +AC_PROG_CC +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_GREP +AC_SYS_LARGEFILE + +AC_CHECK_SIZEOF([long]) +AC_CHECK_SIZEOF([long long]) +AC_CHECK_SIZEOF([void *]) + +# Are we using GNU ld? +AC_MSG_CHECKING([for GNU ld]) +LD=`$CC -print-prog-name=ld 2>&5` + +if test `$LD -v 2>&1 | $ac_cv_path_GREP -c "GNU ld"` = 0; then + # Not + GNU_LD="" + AC_MSG_RESULT([no]) +else + GNU_LD="$LD" + AC_MSG_RESULT([yes]) + AC_SUBST([GNU_LD]) +fi + +AC_CHECK_HEADERS([sys/select.h alloca.h]) +AC_CHECK_HEADER([slang.h], [], [ + old_CPPFLAGS=${CPPFLAGS} + CPPFLAGS="${CPPFLAGS} -I/opt/local/include" + unset ac_cv_header_slang_h + AC_CHECK_HEADER([slang.h]) + if test x$ac_cv_header_slang_h = x; then + CPPFLAGS="${old_CPPFLAGS}" + else + LDFLAGS="${LDFLAGS} -L/opt/local/lib" + fi +]) +if test x$ac_cv_header_slang_h = x; then + old_CPPFLAGS=${CPPFLAGS} + CPPFLAGS="${CPPFLAGS} -I/sw/include" + AC_CHECK_HEADER([slang.h]) + if test x$ac_cv_header_slang_h = x; then + CPPFLAGS=${old_CPPFLAGS} + else + LDFLAGS="${LDFLAGS} -L/sw/lib" + fi +fi +AC_CHECK_HEADERS([popt.h libintl.h]) + +AC_MSG_CHECKING([for python versions]) +AC_ARG_WITH([python], [ --without-python do not compile python support]) +if test "x$with_python" = "xno"; then + AC_MSG_RESULT([skipped]) + PYTHONVERS= +else + PYTHONVERS=$(ls /usr/include/python*/Python.h 2> /dev/null | sed 's|.*\(python[[0-9]]*\.[[0-9]]*\).*|\1|g' | tr '\n' ' ') + AC_MSG_RESULT([$PYTHONVERS]) +fi +AC_SUBST([PYTHONVERS]) + +AC_ARG_WITH([tcl], [ --without-tcl do not compile whiptcl.so]) +if test "x$with_tcl" = "xno"; then + WHIPTCLLIB= +else + AC_MSG_CHECKING([for tcl configuration]) + + # check in a few common install locations + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in `ls -d ${libdir} 2>/dev/null` \ + `ls -d /usr/lib 2>/dev/null` \ + `ls -d /usr/lib64 2>/dev/null` \ + `ls -d /usr/local/lib 2>/dev/null` \ + `ls -d /usr/contrib/lib 2>/dev/null` \ + `ls -d /usr/pkg/lib 2>/dev/null` \ + `ls -d /usr/local/lib/tcl8.5 2>/dev/null` \ + `ls -d /usr/local/lib/tcl8.4 2>/dev/null` \ + `ls -d /usr/lib/tcl8.5 2>/dev/null` \ + `ls -d /usr/lib/tcl8.4 2>/dev/null` \ + `ls -d /opt/local/lib 2>/dev/null` \ + ; do + if test -f "$i/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd $i; pwd)` + break + fi + done + fi + + if test x"${ac_cv_c_tclconfig}" != x ; then + AC_MSG_RESULT([found]) + . ${ac_cv_c_tclconfig}/tclConfig.sh + AC_SUBST([TCL_LIB_FLAG]) + WHIPTCLLIB=whiptcl + # needed with tcl8.6 + CPPFLAGS="$CPPFLAGS -DUSE_INTERP_RESULT" + else + AC_MSG_RESULT([NOT found]) + fi +fi +AC_SUBST([WHIPTCLLIB]) + +AC_ARG_WITH([gpm-support], [ --with-gpm-support compile with GPM support]) + +if test "x$with_gpm_support" = "xyes"; then + AC_DEFINE([USE_GPM], 1, [Define to 1 if GPM support is enabled]) +fi + +AC_ARG_ENABLE([nls], [ --disable-nls compile without NLS support]) + +if test "x$enable_nls" != "xno"; then + AC_CHECK_LIB([c], [gettext], [ ], [ + AC_CHECK_LIB([intl], [gettext], [ + LIBS="-lintl" + AC_SUBST([LIBS])], [ + if test "x$enable_nls" != "xcheck"; then + AC_MSG_FAILURE([--enable-nls was specified, but the configure check failed]) + else + enable_nls=no + fi + ]) + ]) + if test "x$enable_nls" != "xno"; then + AC_DEFINE([ENABLE_NLS], 1, [Define to 1 if NLS support is enabled]) + fi +fi + +AC_ARG_WITH(colorsfile, [ --with-colorsfile=file set default location of colors file]) + +if test "x$with_colorsfile" != "xno"; then + if test "x$with_colorsfile" != "xyes"; then + if test "x$with_colorsfile" != "x"; then + AC_DEFINE_UNQUOTED(NEWT_COLORS_FILE, "$with_colorsfile", [Default NEWT_COLORS_FILE ]) + fi + fi +fi + +AC_CONFIG_FILES([Makefile libnewt.pc]) +AC_OUTPUT + diff --git a/dialogboxes.c b/dialogboxes.c new file mode 100644 index 0000000..502b6ed --- /dev/null +++ b/dialogboxes.c @@ -0,0 +1,606 @@ +/* simple dialog boxes, used by both whiptail and tcl dialog bindings */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include + +#include "nls.h" +#include "dialogboxes.h" +#include "newt.h" +#include "newt_pr.h" +#include "popt.h" + +#define MAXBUF 200 +#define MAXFORMAT 20 +#define BUTTONS 4 + +/* globals -- ick */ +static int buttonHeight = 1; +static const char * buttonText[BUTTONS]; + +int max (int a, int b) +{ + return (a > b) ? a : b; +} + +int min (int a, int b) +{ + return ( a < b) ? a : b ; +} + +static newtComponent (*makeButton)(int left, int right, const char * text) = + newtCompactButton; + +static const char * getButtonText(int button) { + const char * text; + if (button < 0 || button >= BUTTONS) + return NULL; + + text = buttonText[button]; + if (text) + return text; + + switch (button) { + case 0: return dgettext(PACKAGE, "Ok"); + case 1: return dgettext(PACKAGE, "Cancel"); + case 2: return dgettext(PACKAGE, "Yes"); + case 3: return dgettext(PACKAGE, "No"); + default: + return NULL; + } +} + +static void addButtons(int height, int width, newtComponent form, + newtComponent * okay, newtComponent * cancel, + int flags) { + // FIXME: DO SOMETHING ABOUT THE HARD-CODED CONSTANTS + if (flags & FLAG_NOCANCEL) { + *okay = makeButton((width - 8) / 2, height - buttonHeight - 1, + getButtonText(BUTTON_OK)); + *cancel = NULL; + newtFormAddComponent(form, *okay); + } else { + *okay = makeButton((width - 18) / 3, height - buttonHeight - 1, + getButtonText(BUTTON_OK)); + *cancel = makeButton(((width - 18) / 3) * 2 + 9, + height - buttonHeight - 1, + getButtonText(BUTTON_CANCEL)); + newtFormAddComponents(form, *okay, *cancel, NULL); + } +} + +static void cleanNewlines(char *text) +{ + char *p, *q; + + for (p = q = text; *p; p++, q++) + if (*p == '\\' && p[1] == 'n') { + p++; + *q = '\n'; + } else + *q = *p; + *q = '\0'; +} + +static newtComponent textbox(int maxHeight, int width, const char * text, + int flags, int * height) { + newtComponent tb; + int sFlag = (flags & FLAG_SCROLL_TEXT) ? NEWT_FLAG_SCROLL : 0; + int i; + char *buf; + + buf = alloca(strlen(text) + 1); + strcpy(buf, text); + cleanNewlines(buf); + + tb = newtTextbox(1, 0, width, maxHeight, NEWT_FLAG_WRAP | sFlag); + newtTextboxSetText(tb, buf); + + i = newtTextboxGetNumLines(tb); + if (i < maxHeight) { + newtTextboxSetHeight(tb, i); + maxHeight = i; + } + + *height = maxHeight; + + return tb; +} + +int gauge(const char * text, int height, int width, poptContext optCon, int fd, + int flags) { + newtComponent form, scale, tb; + int top; + const char * arg; + char * end; + int val; + FILE * f = fdopen(fd, "r"); + char buf[3000]; + char buf3[50]; + int i; + + setlinebuf(f); + + if (!(arg = poptGetArg(optCon))) return DLG_ERROR; + val = strtoul(arg, &end, 10); + if (*end) return DLG_ERROR; + + tb = textbox(height - 3, width - 2, text, flags, &top); + + form = newtForm(NULL, NULL, 0); + + scale = newtScale(2, height - 2, width - 4, 100); + newtScaleSet(scale, val); + + newtFormAddComponents(form, tb, scale, NULL); + + newtDrawForm(form); + newtRefresh(); + + do { + if (!fgets(buf, sizeof(buf) - 1, f)) + continue; + buf[strlen(buf) - 1] = '\0'; + + if (!strcmp(buf, "XXX")) { + while (!fgets(buf3, sizeof(buf3) - 1, f) && !feof(f)) + ; + if (feof(f)) + break; + buf3[strlen(buf3) - 1] = '\0'; + + i = 0; + do { + if (!fgets(buf + i, sizeof(buf) - 1 - i, f)) + continue; + if (!strcmp(buf + i, "XXX\n")) { + *(buf + i) = '\0'; + break; + } + i = strlen(buf); + } while (!feof(f)); + + if (i > 0) + buf[strlen(buf) - 1] = '\0'; + else + buf[0] = '\0'; + + cleanNewlines(buf); + newtTextboxSetText(tb, buf); + + arg = buf3; + } else { + arg = buf; + } + + val = strtoul(arg, &end, 10); + if (!*end) { + newtScaleSet(scale, val); + newtDrawForm(form); + newtRefresh(); + } + } while (!feof(f)); + + newtFormDestroy(form); + + return DLG_OKAY; +} + +int inputBox(const char * text, int height, int width, poptContext optCon, + int flags, char ** result) { + newtComponent form, entry, okay, cancel, answer, tb; + const char * val; + int pFlag = (flags & FLAG_PASSWORD) ? NEWT_FLAG_PASSWORD : 0; + int rc = DLG_OKAY; + int top; + + val = poptGetArg(optCon); + tb = textbox(height - 3 - buttonHeight, width - 2, + text, flags, &top); + + form = newtForm(NULL, NULL, 0); + entry = newtEntry(1, top + 1, val, width - 2, &val, + NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT | pFlag); + + newtFormAddComponents(form, tb, entry, NULL); + + addButtons(height, width, form, &okay, &cancel, flags); + + answer = newtRunForm(form); + *result = NULL; + if (answer == cancel) + rc = DLG_CANCEL; + else if (answer == NULL) + rc = DLG_ESCAPE; + else + *result = strdup(val); + + newtFormDestroy(form); + + return rc; +} + +static int mystrncpyw(char *dest, const char *src, int n, int *maxwidth) +{ + int i = 0; + int w = 0, cw; + wchar_t c; + mbstate_t ps; + const char *p = src; + char *d = dest; + + memset(&ps, 0, sizeof(ps)); + + for (;;) { + int ret = mbrtowc(&c, p, MB_CUR_MAX, &ps); + if (ret <= 0) break; + if (ret + i >= n) break; + cw = wcwidth(c); + if (cw < 0) break; + if (cw + w > *maxwidth) break; + w += cw; + memcpy(d, p, ret); + d += ret; + p += ret; + i += ret; + } + dest[i] = '\0'; + *maxwidth = w; + return i; +} + +int listBox(const char * text, int height, int width, poptContext optCon, + int flags, const char *default_item, char ** result) { + newtComponent form, okay, tb, answer, listBox; + newtComponent cancel = NULL; + const char * arg; + char * end; + int listHeight; + int numItems = 0; + int allocedItems = 5; + int i, top; + int rc = DLG_OKAY; + char buf[MAXBUF]; + int maxTagWidth = 0; + int maxTextWidth = 0; + int defItem = -1; + int scrollFlag; + int lineWidth, textWidth, tagWidth; + struct { + const char * text; + const char * tag; + } * itemInfo = malloc(allocedItems * sizeof(*itemInfo)); + + if (itemInfo == NULL) return DLG_ERROR; + if (!(arg = poptGetArg(optCon))) return DLG_ERROR; + listHeight = strtoul(arg, &end, 10); + if (*end) return DLG_ERROR; + + while ((arg = poptGetArg(optCon))) { + if (allocedItems == numItems) { + allocedItems += 5; + itemInfo = realloc(itemInfo, sizeof(*itemInfo) * allocedItems); + if (itemInfo == NULL) return DLG_ERROR; + } + + itemInfo[numItems].tag = arg; + if (default_item && (strcmp(default_item, arg) == 0)) { + defItem = numItems; + } + if (!(arg = poptGetArg(optCon))) return DLG_ERROR; + + if (!(flags & FLAG_NOITEM)) { + itemInfo[numItems].text = arg; + } else + itemInfo[numItems].text = ""; + + if (wstrlen(itemInfo[numItems].text,-1) > (unsigned int)maxTextWidth) + maxTextWidth = wstrlen(itemInfo[numItems].text,-1); + if (wstrlen(itemInfo[numItems].tag,-1) > (unsigned int)maxTagWidth) + maxTagWidth = wstrlen(itemInfo[numItems].tag,-1); + + numItems++; + } + if (numItems == 0) + return DLG_ERROR; + + if (flags & FLAG_NOTAGS) { + maxTagWidth = 0; + } + + form = newtForm(NULL, NULL, 0); + + tb = textbox(height - 4 - buttonHeight - listHeight, width - 2, + text, flags, &top); + + if (listHeight >= numItems) { + scrollFlag = 0; + i = 0; + } else { + scrollFlag = NEWT_FLAG_SCROLL; + i = 2; + } + + lineWidth = min(maxTagWidth + maxTextWidth + i + 1, SLtt_Screen_Cols - 6); + listBox = newtListbox( (width - lineWidth) / 2 , top + 1, listHeight, + NEWT_FLAG_RETURNEXIT | scrollFlag); + + textWidth = maxTextWidth; + tagWidth = maxTagWidth; + if (maxTextWidth == 0) { + tagWidth = lineWidth; + } else { + tagWidth++; + textWidth++; + while (textWidth + tagWidth + i > lineWidth) { + if (textWidth >= tagWidth && textWidth > 0) + textWidth--; + else if (tagWidth > 0) + tagWidth--; + else + break; + } + } + + if (!(flags & FLAG_NOTAGS)) { + for (i = 0; i < numItems; i++) { + int w = tagWidth; + int len, j; + len = mystrncpyw(buf, itemInfo[i].tag, MAXBUF, &w); + for (j = 0; j < tagWidth - w; j++) { + if (len + 1 >= MAXBUF) + break; + buf[len++] = ' '; + } + buf[len] = '\0'; + w = textWidth; + mystrncpyw(buf + len, itemInfo[i].text, MAXBUF-len, &w); + newtListboxAddEntry(listBox, buf, (void *)(long) i); + } + } else { + for (i = 0; i < numItems; i++) { + snprintf(buf, MAXBUF, "%s", itemInfo[i].text); + newtListboxAddEntry(listBox, buf, (void *)(long) i); + } + } + + if (defItem != -1) + newtListboxSetCurrent (listBox, defItem); + + newtFormAddComponents(form, tb, listBox, NULL); + + addButtons(height, width, form, &okay, &cancel, flags); + + answer = newtRunForm(form); + *result = NULL; + if (answer == cancel) + rc = DLG_CANCEL; + else if (answer == NULL) + rc = DLG_ESCAPE; + else { + i = (long) newtListboxGetCurrent(listBox); + *result = strdup(itemInfo[i].tag); + } + + newtFormDestroy(form); + free(itemInfo); + + return rc; +} + +int checkList(const char * text, int height, int width, poptContext optCon, + int useRadio, int flags, char *** selections) { + newtComponent form, okay, tb, subform, answer; + newtComponent sb = NULL, cancel = NULL; + const char * arg; + char * end; + int listHeight; + int numBoxes = 0; + int allocedBoxes = 5; + int i; + int numSelected; + int rc = DLG_OKAY; + char buf[MAXBUF], format[MAXFORMAT]; + int maxWidth = 0; + int top; + struct { + const char * text; + const char * tag; + newtComponent comp; + } * cbInfo = malloc(allocedBoxes * sizeof(*cbInfo)); + char * cbStates = malloc(allocedBoxes * sizeof(*cbStates)); + + if ( (cbInfo == NULL) || (cbStates == NULL)) return DLG_ERROR; + if (!(arg = poptGetArg(optCon))) return DLG_ERROR; + listHeight = strtoul(arg, &end, 10); + if (*end) return DLG_ERROR; + + while ((arg = poptGetArg(optCon))) { + if (allocedBoxes == numBoxes) { + allocedBoxes += 5; + cbInfo = realloc(cbInfo, sizeof(*cbInfo) * allocedBoxes); + cbStates = realloc(cbStates, sizeof(*cbStates) * allocedBoxes); + if ((cbInfo == NULL) || (cbStates == NULL)) return DLG_ERROR; + } + + cbInfo[numBoxes].tag = arg; + if (!(arg = poptGetArg(optCon))) return DLG_ERROR; + + if (!(flags & FLAG_NOITEM)) { + cbInfo[numBoxes].text = arg; + if (!(arg = poptGetArg(optCon))) return DLG_ERROR; + } else + cbInfo[numBoxes].text = ""; + + if (!strcmp(arg, "1") || !strcasecmp(arg, "on") || + !strcasecmp(arg, "yes")) + cbStates[numBoxes] = '*'; + else + cbStates[numBoxes] = ' '; + + if (wstrlen(cbInfo[numBoxes].tag,-1) > (unsigned int)maxWidth) + maxWidth = wstrlen(cbInfo[numBoxes].tag,-1); + + numBoxes++; + } + + form = newtForm(NULL, NULL, 0); + + tb = textbox(height - 3 - buttonHeight - listHeight, width - 2, + text, flags, &top); + + if (listHeight < numBoxes) { + sb = newtVerticalScrollbar(width - 4, + top + 1, + listHeight, NEWT_COLORSET_CHECKBOX, + NEWT_COLORSET_ACTCHECKBOX); + newtFormAddComponent(form, sb); + } + subform = newtForm(sb, NULL, 0); + newtFormSetBackground(subform, NEWT_COLORSET_CHECKBOX); + + if (flags & FLAG_NOTAGS) + snprintf(format, MAXFORMAT, "%%.0s%%s"); + else + snprintf(format, MAXFORMAT, "%%-%ds %%s", maxWidth); + + for (i = 0; i < numBoxes; i++) { + snprintf(buf, MAXBUF, format, cbInfo[i].tag, cbInfo[i].text); + + if (useRadio) + cbInfo[i].comp = newtRadiobutton(4, top + 1 + i, buf, + cbStates[i] != ' ', + i ? cbInfo[i - 1].comp : NULL); + else + cbInfo[i].comp = newtCheckbox(4, top + 1 + i, buf, + cbStates[i], NULL, cbStates + i); + + newtCheckboxSetFlags(cbInfo[i].comp, NEWT_FLAG_RETURNEXIT, NEWT_FLAGS_SET); + newtFormAddComponent(subform, cbInfo[i].comp); + } + + newtFormSetHeight(subform, listHeight); + newtFormSetWidth(subform, width - 10); + + newtFormAddComponents(form, tb, subform, NULL); + + addButtons(height, width, form, &okay, &cancel, flags); + + answer = newtRunForm(form); + *selections = NULL; + if (answer == cancel) + rc = DLG_CANCEL; + else if (answer == NULL) + rc = DLG_ESCAPE; + else { + if (useRadio) { + answer = newtRadioGetCurrent(cbInfo[0].comp); + *selections = malloc(sizeof(char *) * 2); + if (*selections == NULL) + return DLG_ERROR; + (*selections)[0] = (*selections)[1] = NULL; + for (i = 0; i < numBoxes; i++) + if (cbInfo[i].comp == answer) { + (*selections)[0] = strdup(cbInfo[i].tag); + break; + } + } else { + numSelected = 0; + for (i = 0; i < numBoxes; i++) { + if (cbStates[i] != ' ') numSelected++; + } + + *selections = malloc(sizeof(char *) * (numSelected + 1)); + if (*selections == NULL) + return DLG_ERROR; + + numSelected = 0; + for (i = 0; i < numBoxes; i++) { + if (cbStates[i] != ' ') + (*selections)[numSelected++] = strdup(cbInfo[i].tag); + } + + (*selections)[numSelected] = NULL; + } + } + + free(cbInfo); + free(cbStates); + newtFormDestroy(form); + + return rc; +} + +int messageBox(const char * text, int height, int width, int type, int flags) { + newtComponent form, yes, tb, answer; + newtComponent no = NULL; + int rc = DLG_OKAY; + int tFlag = (flags & FLAG_SCROLL_TEXT) ? NEWT_FLAG_SCROLL : 0; + + form = newtForm(NULL, NULL, 0); + + tb = newtTextbox(1, 1, width - 2, height - 3 - buttonHeight, + NEWT_FLAG_WRAP | tFlag); + newtTextboxSetText(tb, text); + + newtFormAddComponent(form, tb); + + switch ( type ) { + case MSGBOX_INFO: + break; + case MSGBOX_MSG: + // FIXME Do something about the hard-coded constants + yes = makeButton((width - 8) / 2, height - 1 - buttonHeight, + getButtonText(BUTTON_OK)); + newtFormAddComponent(form, yes); + break; + default: + yes = makeButton((width - 16) / 3, height - 1 - buttonHeight, + getButtonText(BUTTON_YES)); + no = makeButton(((width - 16) / 3) * 2 + 9, height - 1 - buttonHeight, + getButtonText(BUTTON_NO)); + newtFormAddComponents(form, yes, no, NULL); + + if (flags & FLAG_DEFAULT_NO) + newtFormSetCurrent(form, no); + } + + if ( type != MSGBOX_INFO ) { + if (newtRunForm(form) == NULL) + rc = DLG_ESCAPE; + + answer = newtFormGetCurrent(form); + + if (answer == no) + rc = DLG_CANCEL; + } + else { + newtDrawForm(form); + newtRefresh(); + } + + newtFormDestroy(form); + + return rc; +} + +void useFullButtons(int state) { + if (state) { + buttonHeight = 3; + makeButton = newtButton; + } else { + buttonHeight = 1; + makeButton = newtCompactButton; + } +} + +void setButtonText(const char * text, int button) { + if (button < 0 || button >= BUTTONS) + return; + buttonText[button] = text; +} diff --git a/dialogboxes.h b/dialogboxes.h new file mode 100644 index 0000000..ca51090 --- /dev/null +++ b/dialogboxes.h @@ -0,0 +1,42 @@ +#ifndef H_DIALOGBOXES +#define H_DIALOGBOXES + +#include "popt.h" + +#define MSGBOX_MSG 0 +#define MSGBOX_YESNO 1 +#define MSGBOX_INFO 2 + +#define FLAG_NOITEM (1 << 0) +#define FLAG_NOCANCEL (1 << 1) +#define FLAG_SCROLL_TEXT (1 << 2) +#define FLAG_DEFAULT_NO (1 << 3) +#define FLAG_PASSWORD (1 << 4) +#define FLAG_NOTAGS (1 << 5) + +#define DLG_ERROR -1 +#define DLG_OKAY 0 +#define DLG_CANCEL 1 +#define DLG_ESCAPE 2 + +#define BUTTON_OK 0 +#define BUTTON_CANCEL 1 +#define BUTTON_YES 2 +#define BUTTON_NO 3 + +int min(int a, int b); +int max(int a, int b); + +int messageBox(const char * text, int height, int width, int type, int flags); +int checkList(const char * text, int height, int width, poptContext optCon, + int useRadio, int flags, char *** selections); +int listBox(const char * text, int height, int width, poptContext optCon, + int flags, const char *default_item, char ** result); +int inputBox(const char * text, int height, int width, poptContext optCon, + int flags, char ** result); +int gauge(const char * text, int height, int width, poptContext optCon, int fd, + int flags); +void useFullButtons(int state); +void setButtonText(const char * text, int button); + +#endif diff --git a/eawidth.c b/eawidth.c new file mode 100644 index 0000000..7001e96 --- /dev/null +++ b/eawidth.c @@ -0,0 +1,463 @@ +/* #define TEST_GET_EAST_ASIA_STR_WIDTH 1 */ + +#include +#include +#include +#include +#include + +#include "eawidth.h" + +/* + * If the amount of columns the cursor advances on a TAB character depends + * on the current position, set this to a negative number (i.e. -8 for tab + * stops every eight columns. If static, set to a positive number. Zero if + * tabs are ignored. + */ +static const int tab_width = -8; + +typedef struct { + unsigned short start, end; + east_asia_type type; +} eaw_db_type; + +static const eaw_db_type eaw_db[] = { + { 0x0020,0x007E,narrow }, + { 0x00A1,0x00A1,ambiguous }, /*INVERTED EXCLAMATION MARK*/ + { 0x00A2,0x00A3,narrow }, + { 0x00A4,0x00A4,ambiguous }, /*CURRENCY SIGN*/ + { 0x00A5,0x00A6,narrow }, + { 0x00A7,0x00A8,ambiguous }, + { 0x00AA,0x00AA,ambiguous }, /*FEMININE ORDINAL INDICATOR*/ + { 0x00AC,0x00AC,narrow }, /*NOT SIGN*/ + { 0x00AD,0x00AD,ambiguous }, /*SOFT HYPHEN*/ + { 0x00AF,0x00AF,narrow }, /*MACRON*/ + { 0x00B0,0x00B4,ambiguous }, + { 0x00B6,0x00BA,ambiguous }, + { 0x00BC,0x00BF,ambiguous }, + { 0x00C6,0x00C6,ambiguous }, /*LATIN CAPITAL LETTER AE*/ + { 0x00D0,0x00D0,ambiguous }, /*LATIN CAPITAL LETTER ETH*/ + { 0x00D7,0x00D8,ambiguous }, + { 0x00DE,0x00E1,ambiguous }, + { 0x00E6,0x00E6,ambiguous }, /*LATIN SMALL LETTER AE*/ + { 0x00E8,0x00EA,ambiguous }, + { 0x00EC,0x00ED,ambiguous }, + { 0x00F0,0x00F0,ambiguous }, /*LATIN SMALL LETTER ETH*/ + { 0x00F2,0x00F3,ambiguous }, + { 0x00F7,0x00FA,ambiguous }, + { 0x00FC,0x00FC,ambiguous }, /*LATIN SMALL LETTER U WITH DIAERESIS*/ + { 0x00FE,0x00FE,ambiguous }, /*LATIN SMALL LETTER THORN*/ + { 0x0101,0x0101,ambiguous }, /*LATIN SMALL LETTER A WITH MACRON*/ + { 0x0111,0x0111,ambiguous }, /*LATIN SMALL LETTER D WITH STROKE*/ + { 0x0113,0x0113,ambiguous }, /*LATIN SMALL LETTER E WITH MACRON*/ + { 0x011B,0x011B,ambiguous }, /*LATIN SMALL LETTER E WITH CARON*/ + { 0x0126,0x0127,ambiguous }, + { 0x012B,0x012B,ambiguous }, /*LATIN SMALL LETTER I WITH MACRON*/ + { 0x0131,0x0133,ambiguous }, + { 0x0138,0x0138,ambiguous }, /*LATIN SMALL LETTER KRA*/ + { 0x013F,0x0142,ambiguous }, + { 0x0144,0x0144,ambiguous }, /*LATIN SMALL LETTER N WITH ACUTE*/ + { 0x0148,0x014A,ambiguous }, + { 0x014D,0x014D,ambiguous }, /*LATIN SMALL LETTER O WITH MACRON*/ + { 0x0152,0x0153,ambiguous }, + { 0x0166,0x0167,ambiguous }, + { 0x016B,0x016B,ambiguous }, /*LATIN SMALL LETTER U WITH MACRON*/ + { 0x01CE,0x01CE,ambiguous }, /*LATIN SMALL LETTER A WITH CARON*/ + { 0x01D0,0x01D0,ambiguous }, /*LATIN SMALL LETTER I WITH CARON*/ + { 0x01D2,0x01D2,ambiguous }, /*LATIN SMALL LETTER O WITH CARON*/ + { 0x01D4,0x01D4,ambiguous }, /*LATIN SMALL LETTER U WITH CARON*/ + { 0x01D6,0x01D6,ambiguous }, /*LATIN SMALL LETTER U W/DIAERESIS+MACRON*/ + { 0x01D8,0x01D8,ambiguous }, /*LATIN SMALL LETTER U W/DIAERESIS+ACUTE*/ + { 0x01DA,0x01DA,ambiguous }, /*LATIN SMALL LETTER U W/DIAERESIS+CARON*/ + { 0x01DC,0x01DC,ambiguous }, /*LATIN SMALL LETTER U W/DIAERESIS+GRAVE*/ + { 0x0251,0x0251,ambiguous }, /*LATIN SMALL LETTER ALPHA*/ + { 0x0261,0x0261,ambiguous }, /*LATIN SMALL LETTER SCRIPT G*/ + { 0x02C7,0x02C7,ambiguous }, /*CARON*/ + { 0x02C9,0x02CB,ambiguous }, + { 0x02CD,0x02CD,ambiguous }, /*MODIFIER LETTER LOW MACRON*/ + { 0x02D0,0x02D0,ambiguous }, /*MODIFIER LETTER TRIANGULAR COLON*/ + { 0x02D8,0x02DB,ambiguous }, + { 0x02DD,0x02DD,ambiguous }, /*DOUBLE ACUTE ACCENT*/ + { 0x0300,0x0362,ambiguous }, + { 0x0391,0x03A9,ambiguous }, + { 0x03B1,0x03C1,ambiguous }, + { 0x03C3,0x03C9,ambiguous }, + { 0x0401,0x0401,ambiguous }, /*CYRILLIC CAPITAL LETTER IO*/ + { 0x0410,0x044F,ambiguous }, + { 0x0451,0x0451,ambiguous }, /*CYRILLIC SMALL LETTER IO*/ + { 0x1100,0x115F,wide }, + { 0x2010,0x2010,ambiguous }, /*HYPHEN*/ + { 0x2013,0x2016,ambiguous }, + { 0x2018,0x2019,ambiguous }, + { 0x201C,0x201D,ambiguous }, + { 0x2020,0x2021,ambiguous }, + { 0x2025,0x2027,ambiguous }, + { 0x2030,0x2030,ambiguous }, /*PER MILLE SIGN*/ + { 0x2032,0x2033,ambiguous }, + { 0x2035,0x2035,ambiguous }, /*REVERSED PRIME*/ + { 0x203B,0x203B,ambiguous }, /*REFERENCE MARK*/ + { 0x2074,0x2074,ambiguous }, /*SUPERSCRIPT FOUR*/ + { 0x207F,0x207F,ambiguous }, /*SUPERSCRIPT LATIN SMALL LETTER N*/ + { 0x2081,0x2084,ambiguous }, + { 0x20A9,0x20A9,half_width }, /*WON SIGN*/ + { 0x20AC,0x20AC,ambiguous }, /*EURO SIGN*/ + { 0x2103,0x2103,ambiguous }, /*DEGREE CELSIUS*/ + { 0x2105,0x2105,ambiguous }, /*CARE OF*/ + { 0x2109,0x2109,ambiguous }, /*DEGREE FAHRENHEIT*/ + { 0x2113,0x2113,ambiguous }, /*SCRIPT SMALL L*/ + { 0x2121,0x2122,ambiguous }, + { 0x2126,0x2126,ambiguous }, /*OHM SIGN*/ + { 0x212B,0x212B,ambiguous }, /*ANGSTROM SIGN*/ + { 0x2154,0x2155,ambiguous }, + { 0x215B,0x215B,ambiguous }, /*VULGAR FRACTION ONE EIGHTH*/ + { 0x215E,0x215E,ambiguous }, /*VULGAR FRACTION SEVEN EIGHTHS*/ + { 0x2160,0x216B,ambiguous }, + { 0x2170,0x2179,ambiguous }, + { 0x2190,0x2199,ambiguous }, + { 0x21D2,0x21D2,ambiguous }, /*RIGHTWARDS DOUBLE ARROW*/ + { 0x21D4,0x21D4,ambiguous }, /*LEFT RIGHT DOUBLE ARROW*/ + { 0x2200,0x2200,ambiguous }, /*FOR ALL*/ + { 0x2202,0x2203,ambiguous }, + { 0x2207,0x2208,ambiguous }, + { 0x220B,0x220B,ambiguous }, /*CONTAINS AS MEMBER*/ + { 0x220F,0x220F,ambiguous }, /*N-ARY PRODUCT*/ + { 0x2211,0x2211,ambiguous }, /*N-ARY SUMMATION*/ + { 0x2215,0x2215,ambiguous }, /*DIVISION SLASH*/ + { 0x221A,0x221A,ambiguous }, /*SQUARE ROOT*/ + { 0x221D,0x2220,ambiguous }, + { 0x2223,0x2223,ambiguous }, /*DIVIDES*/ + { 0x2225,0x2225,ambiguous }, /*PARALLEL TO*/ + { 0x2227,0x222C,ambiguous }, + { 0x222E,0x222E,ambiguous }, /*CONTOUR INTEGRAL*/ + { 0x2234,0x2237,ambiguous }, + { 0x223C,0x223D,ambiguous }, + { 0x2248,0x2248,ambiguous }, /*ALMOST EQUAL TO*/ + { 0x224C,0x224C,ambiguous }, /*ALL EQUAL TO*/ + { 0x2252,0x2252,ambiguous }, /*APPROXIMATELY EQUAL TO OR THE IMAGE OF*/ + { 0x2260,0x2261,ambiguous }, + { 0x2264,0x2267,ambiguous }, + { 0x226A,0x226B,ambiguous }, + { 0x226E,0x226F,ambiguous }, + { 0x2282,0x2283,ambiguous }, + { 0x2286,0x2287,ambiguous }, + { 0x2295,0x2295,ambiguous }, /*CIRCLED PLUS*/ + { 0x2299,0x2299,ambiguous }, /*CIRCLED DOT OPERATOR*/ + { 0x22A5,0x22A5,ambiguous }, /*UP TACK*/ + { 0x22BF,0x22BF,ambiguous }, /*RIGHT TRIANGLE*/ + { 0x2312,0x2312,ambiguous }, /*ARC*/ + { 0x2460,0x24BF,ambiguous }, + { 0x24D0,0x24E9,ambiguous }, + { 0x2500,0x254B,ambiguous }, + { 0x2550,0x2574,ambiguous }, + { 0x2580,0x258F,ambiguous }, + { 0x2592,0x25A1,ambiguous }, + { 0x25A3,0x25A9,ambiguous }, + { 0x25B2,0x25B3,ambiguous }, + { 0x25B6,0x25B7,ambiguous }, + { 0x25BC,0x25BD,ambiguous }, + { 0x25C0,0x25C1,ambiguous }, + { 0x25C6,0x25C8,ambiguous }, + { 0x25CB,0x25CB,ambiguous }, /*WHITE CIRCLE*/ + { 0x25CE,0x25D1,ambiguous }, + { 0x25E2,0x25E5,ambiguous }, + { 0x25EF,0x25EF,ambiguous }, /*LARGE CIRCLE*/ + { 0x2605,0x2606,ambiguous }, + { 0x2609,0x2609,ambiguous }, /*SUN*/ + { 0x260E,0x260F,ambiguous }, + { 0x261C,0x261C,ambiguous }, /*WHITE LEFT POINTING INDEX*/ + { 0x261E,0x261E,ambiguous }, /*WHITE RIGHT POINTING INDEX*/ + { 0x2640,0x2640,ambiguous }, /*FEMALE SIGN*/ + { 0x2642,0x2642,ambiguous }, /*MALE SIGN*/ + { 0x2660,0x2661,ambiguous }, + { 0x2663,0x2665,ambiguous }, + { 0x2667,0x266A,ambiguous }, + { 0x266C,0x266D,ambiguous }, + { 0x266F,0x266F,ambiguous }, /*MUSIC SHARP SIGN*/ + { 0x2E80,0x3009,wide }, + { 0x300A,0x300B,ambiguous }, + { 0x300C,0x3019,wide }, + { 0x301A,0x301B,ambiguous }, + { 0x301C,0x303E,wide }, + { 0x3041,0xD7A3,wide }, + { 0xE000,0xF8FF,ambiguous }, + { 0xF900,0xFA2D,wide }, + { 0xFE30,0xFE6B,wide }, + { 0xFF01,0xFF5E,full_width }, + { 0xFF61,0xFFDC,half_width }, + { 0xFFE0,0xFFE6,full_width }, + { 0xFFE8,0xFFEE,half_width }, +}; + +static int +eaw_db_cmp (const void *ck, const void *ce) { + const eaw_db_type *key = ck, *element = ce; + + assert(key != NULL); + assert(element != NULL); + if (key->start < element->start) return -1; + else if (key->end > element->end) return 1; + return 0; +} + +static int +is_cjk_locale (const char *locale_name) { + static const char c[] = "zh"; /* Chinese */ + static const char j[] = "ja"; /* Japanese */ + static const char k[] = "ko"; /* Korean */ + + if (NULL == locale_name) return 0; + if (strncmp(locale_name, c, sizeof(c)) == 0) return 1; + if (strncmp(locale_name, j, sizeof(j)) == 0) return 1; + if (strncmp(locale_name, k, sizeof(k)) == 0) return 1; + return 0; +} + +east_asia_type +get_east_asia_type (wchar_t unicode) { + assert(0xFFFF != unicode && 0xFFFE != unicode); + + if (unicode > 0xFFFF) { + + /* + * Plane 2 is intended for CJK ideographs + */ + if (unicode >= 0x20000 && unicode <= 0x2FFFD) return wide; + return ambiguous; + } + else { + eaw_db_type *pos, key; + size_t n; + + n = sizeof(eaw_db) / sizeof(eaw_db_type); + key.start = key.end = (unsigned short) unicode; + pos = bsearch(&key, eaw_db, n, sizeof(eaw_db_type), eaw_db_cmp); + if (NULL != pos) return pos->type; + } + return neutral; +} + +int +east_asia_mblen (const char *locale_name, const char *s, size_t n, int x) +{ + wchar_t *wcs, *p; + int width = 0; + + if (NULL == s) s = ""; + + /* + * Getting the locale name via setlocale() is expensive, so we prefer + * to have it passed to us. + */ + if (NULL == locale_name) { + locale_name = setlocale(LC_CTYPE, NULL); + if (NULL == locale_name) return INT_MAX; + } + + wcs = (wchar_t *) calloc(n, sizeof(wchar_t)); + if (NULL == wcs) return INT_MAX; + +#if defined __GLIBC__ && !__GLIBC_PREREQ(2,2) +#warning wide character support is broken. Glibc 2.2 or better needed. +#endif + + if ((size_t) -1 == mbstowcs(wcs, s, n)) return INT_MAX; + + switch (get_east_asia_type(*wcs)) { + case neutral: + + /* + * Put characters that print nothing here. + * + * XXX: Yes, I know there are a lot more than this in ISO-10646, but + * this function is intended to calculate the width of strings for + * fixed width terminals displaying legacy CJK character sets. + * State-of-the-art Unicode handling terminals probably won't need + * this function anyway. + */ + if (0x0000 == *wcs) break; /* NULL */ + if (0x0007 == *wcs) break; /* BELL */ + + /* FIXME: there will probably be ASCII chars after the escape + * code, which will be counted as part of the width even though they + * aren't displayed. + */ + if (0x001B == *wcs) break; /* ESC */ + if (0xFEFF == *wcs) break; /* ZWNBSP aka BOM (magic, signature) */ + + /* + * Special characters go here + */ + if (0x0008 == *wcs) { /* BACKSPACE */ + width = -1; + break; + } + if (0x0009 == *wcs) { /* TAB */ + if (tab_width < 0) width = x % abs(tab_width); + else width = tab_width; + break; + } + + /*FALLTHRU*/ + case narrow: + case half_width: + width = 1; + break; + case wide: + case full_width: + width = 2; + break; + case ambiguous: + width = is_cjk_locale(locale_name) ? 2 : 1; + break; + default: + width = INT_MAX; + } + free(wcs); + return width; +} + +int +get_east_asia_str_n_width (const char *locale_name, const char *s, size_t n, int x) +{ + int total_width = 0; + wchar_t *wcs, *p; + + if (NULL == s) s = ""; + + /* + * Getting the locale name via setlocale() is expensive, so we prefer + * to have it passed to us. + */ + if (NULL == locale_name) { + locale_name = setlocale(LC_CTYPE, NULL); + if (NULL == locale_name) return INT_MAX; + } + + wcs = (wchar_t *) calloc(n, sizeof(wchar_t)); + if (NULL == wcs) return INT_MAX; + +#if defined __GLIBC__ && !__GLIBC_PREREQ(2,2) +#warning wide character support is broken. Glibc 2.2 or better needed. +#endif + + if ((size_t) -1 == mbstowcs(wcs, s, n)) return INT_MAX; + + for (p = wcs; L'\0' != *p; p++) { + int width = 0; + + switch (get_east_asia_type(*p)) { + case neutral: + + /* + * Put characters that print nothing here. + * + * XXX: Yes, I know there are a lot more than this in ISO-10646, but + * this function is intended to calculate the width of strings for + * fixed width terminals displaying legacy CJK character sets. + * State-of-the-art Unicode handling terminals probably won't need + * this function anyway. + */ + if (0x0000 == *p) break; /* NULL */ + if (0x0007 == *p) break; /* BELL */ + + /* FIXME: there will probably be ASCII chars after the escape + * code, which will be counted as part of the width even though they + * aren't displayed. + */ + if (0x001B == *p) break; /* ESC */ + if (0xFEFF == *p) break; /* ZWNBSP aka BOM (magic, signature) */ + + /* + * Special characters go here + */ + if (0x0008 == *p) { /* BACKSPACE */ + width = -1; + break; + } + if (0x0009 == *p) { /* TAB */ + if (tab_width < 0) width = x % abs(tab_width); + else width = tab_width; + break; + } + + /*FALLTHRU*/ + case narrow: + case half_width: + width = 1; + break; + case wide: + case full_width: + width = 2; + break; + case ambiguous: + width = is_cjk_locale(locale_name) ? 2 : 1; + break; + default: abort(); /* Doh! */ + } + x += width; + total_width += width; + } + free(wcs); + return total_width; +} + +int +get_east_asia_str_width (const char *locale_name, const char *s, int x) { + size_t n; + int rc; + + n = strlen(s) + 1; + rc = get_east_asia_str_n_width (locale_name, s, n, x); + if (rc == INT_MAX) + return strlen (s); + return rc; +} + +#if TEST_GET_EAST_ASIA_STR_WIDTH + +#include + +int +main (int argc, char *argv[]) { + int i; + char *lc; + const char *fmt = "word #%d ('%s') length is %zu, width is %u\n"; + + lc = setlocale(LC_CTYPE, ""); + if (NULL == lc) { + fputs("couldn't set the default locale for LC_CTYPE\n", stderr); + exit(EXIT_FAILURE); + } + if (printf("character type locale is '%s'\n", lc) < 0) { + perror(NULL); + exit(EXIT_FAILURE); + } + for (i = 1; argc < 2 || i < argc; i++) { + char *s; + size_t length; + unsigned width; + + if (argc < 2) { + if (scanf("%as", &s) < 1 && ferror(stdin)) { + perror(NULL); + exit(EXIT_FAILURE); + } + else if (feof(stdin)) break; + } + else s = strdup(argv[(size_t) i]); + if (NULL == s) { + perror(NULL); + exit(EXIT_FAILURE); + } + length = strlen(s); + width = get_east_asia_str_width(lc, s, 0); + if (printf(fmt, i, s, length, width) < 0) { + perror(NULL); + exit(EXIT_FAILURE); + } + free(s); + } + return 0; +} + +#endif diff --git a/entry.c b/entry.c new file mode 100644 index 0000000..8dad8c8 --- /dev/null +++ b/entry.c @@ -0,0 +1,518 @@ +#include "config.h" + +#ifdef HAVE_ALLOCA_H +#include +#endif + +#include +#include +#include +#include +#include + +#include "newt.h" +#include "newt_pr.h" + +struct entry { + int flags; + char * buf; + const char ** resultPtr; + int bufAlloced; + int bufUsed; /* amount of the buffer that's been used */ + int cursorPosition; /* cursor *in the string* on on screen */ + int firstChar; /* first character position being shown */ + newtEntryFilter filter; + void * filterData; + int cs; + int csDisabled; +}; + +static int previous_char(const char *buf, int pos); +static int next_char(const char *buf, int pos); +static void entryDraw(newtComponent co); +static void entryDestroy(newtComponent co); +static struct eventResult entryEvent(newtComponent co, + struct event ev); + +static struct eventResult entryHandleKey(newtComponent co, int key); + +static struct componentOps entryOps = { + entryDraw, + entryEvent, + entryDestroy, + newtDefaultPlaceHandler, + newtDefaultMappedHandler, +} ; + +void newtEntrySet(newtComponent co, const char * value, int cursorAtEnd) { + struct entry * en = co->data; + + if ((strlen(value) + 1) > (unsigned int)en->bufAlloced) { + free(en->buf); + en->bufAlloced = strlen(value) + 1; + en->buf = malloc(en->bufAlloced); + if (en->resultPtr) *en->resultPtr = en->buf; + } + memset(en->buf, 0, en->bufAlloced); /* clear the buffer */ + strcpy(en->buf, value); + en->bufUsed = strlen(value); + en->firstChar = 0; + if (cursorAtEnd) + en->cursorPosition = en->bufUsed; + else + en->cursorPosition = 0; + + entryDraw(co); +} ; + +newtComponent newtEntry(int left, int top, const char * initialValue, int width, + const char ** resultPtr, int flags) { + newtComponent co; + struct entry * en; + + co = malloc(sizeof(*co)); + en = malloc(sizeof(struct entry)); + co->data = en; + + co->top = top; + co->left = left; + co->height = 1; + co->width = width; + co->isMapped = 0; + co->callback = NULL; + co->destroyCallback = NULL; + + co->ops = &entryOps; + + en->flags = flags; + en->cursorPosition = 0; + en->firstChar = 0; + en->bufUsed = 0; + en->bufAlloced = width + 1; + en->filter = NULL; + + if (!(en->flags & NEWT_FLAG_DISABLED)) + co->takesFocus = 1; + else + co->takesFocus = 0; + + if (initialValue && strlen(initialValue) > (unsigned int)width) { + en->bufAlloced = strlen(initialValue) + 1; + } + en->buf = malloc(en->bufAlloced); + en->resultPtr = resultPtr; + if (en->resultPtr) *en->resultPtr = en->buf; + + memset(en->buf, 0, en->bufAlloced); + if (initialValue) { + strcpy(en->buf, initialValue); + en->bufUsed = strlen(initialValue); + en->cursorPosition = en->bufUsed; + + /* move cursor back if entry is full */ + if (en->cursorPosition && !(en->flags & NEWT_FLAG_SCROLL || + wstrlen(en->buf, -1) < co->width)) + en->cursorPosition = previous_char(en->buf, en->cursorPosition); + } else { + *en->buf = '\0'; + en->bufUsed = 0; + en->cursorPosition = 0; + } + + en->cs = NEWT_COLORSET_ENTRY; + en->csDisabled = NEWT_COLORSET_DISENTRY; + + return co; +} + +static void scroll(struct entry *en, int width) +{ + int r, lv, rv, cntx, cw, cn, nc, pc, ncw, pcw; + + if (width <= 1) { + en->firstChar = en->cursorPosition; + return; + } + + cntx = width / 4; + if (cntx > 5) + cntx = 5; + + if (en->cursorPosition < en->firstChar) + en->firstChar = en->cursorPosition; + + cn = next_char(en->buf, en->cursorPosition); + cw = en->cursorPosition >= en->bufUsed ? 1 : + wstrlen(en->buf + en->cursorPosition, cn - en->cursorPosition); + + r = wstrlen(en->buf + cn, -1); + + lv = wstrlen(en->buf + en->firstChar, en->cursorPosition - en->firstChar); + rv = width - lv - cw; + +#define RC (ncw > 0 && (r > rv && lv - ncw >= cntx && rv < cntx)) +#define LC (pcw > 0 && (r + pcw <= rv || (lv < cntx && rv - pcw >= cntx))) + + nc = next_char(en->buf, en->firstChar); + ncw = wstrlen(en->buf + en->firstChar, nc - en->firstChar); + if (RC) { + do { + lv -= ncw; + rv += ncw; + en->firstChar = nc; + nc = next_char(en->buf, en->firstChar); + ncw = wstrlen(en->buf + en->firstChar, nc - en->firstChar); + } while (RC); + return; + } + + pc = previous_char(en->buf, en->firstChar); + pcw = wstrlen(en->buf + pc, en->firstChar - pc); + if (LC) { + do { + lv += pcw; + rv -= pcw; + en->firstChar = pc; + pc = previous_char(en->buf, en->firstChar); + pcw = wstrlen(en->buf + pc, en->firstChar - pc); + } while (LC); + } +} + +static void entryDraw(newtComponent co) { + struct entry * en = co->data; + int i; + char * chptr; + int len; + char *tmpptr = NULL; + + if (!co->isMapped) return; + + if (en->flags & NEWT_FLAG_DISABLED) + SLsmg_set_color(en->csDisabled); + else + SLsmg_set_color(en->cs); + + if (en->flags & NEWT_FLAG_HIDDEN) { + newtGotorc(co->top, co->left); + for (i = 0; i < co->width; i++) + SLsmg_write_char('_'); + newtGotorc(co->top, co->left); + + return; + } + + newtTrashScreen(); + + /* scroll if necessary */ + scroll(en, co->width); + + chptr = en->buf + en->firstChar; + + if (en->flags & NEWT_FLAG_PASSWORD) { + len = wstrlen(chptr, -1); + tmpptr = alloca(len + 1); + for (i = 0; i < len; i++) + memset(tmpptr, '*', len); + tmpptr[len] = '\0'; + chptr = tmpptr; + } + + len = wstrlen(chptr, -1); + + /* workaround for double width characters */ + if (co->width > 1) { + i = len < co->width ? len : co->width; + i = i > 2 ? i - 2 : 0; + newtGotorc(co->top, co->left + i); + SLsmg_write_char('_'); + SLsmg_write_char('_'); + } + + newtGotorc(co->top, co->left); + + if (len <= co->width) { + i = len; + SLsmg_write_string(chptr); + while (i < co->width) { + SLsmg_write_char('_'); + i++; + } + } else + SLsmg_write_nstring(chptr, co->width); + + newtGotorc(co->top, co->left + wstrlen(en->buf+en->firstChar, en->cursorPosition - en->firstChar)); +} + +void newtEntrySetFlags(newtComponent co, int flags, enum newtFlagsSense sense) { + struct entry * en = co->data; + int row, col; + + en->flags = newtSetFlags(en->flags, flags, sense); + + if (!(en->flags & NEWT_FLAG_DISABLED)) + co->takesFocus = 1; + else + co->takesFocus = 0; + + newtGetrc(&row, &col); + entryDraw(co); + newtGotorc(row, col); +} + +void newtEntrySetColors(newtComponent co, int normal, int disabled) { + struct entry * en = co->data; + + en->cs = normal; + en->csDisabled = disabled; + entryDraw(co); +} + +static void entryDestroy(newtComponent co) { + struct entry * en = co->data; + + free(en->buf); + free(en); + free(co); +} + +static struct eventResult entryEvent(newtComponent co, + struct event ev) { + struct entry * en = co->data; + struct eventResult er; + int ch; + + er.result = ER_IGNORED; + + if (ev.when == EV_NORMAL) { + switch (ev.event) { + case EV_FOCUS: + newtCursorOn(); + if (en->flags & NEWT_FLAG_HIDDEN) + newtGotorc(co->top, co->left); + else + newtGotorc(co->top, co->left + + wstrlen(en->buf + en->firstChar, en->cursorPosition - en->firstChar)); + er.result = ER_SWALLOWED; + break; + + case EV_UNFOCUS: + newtCursorOff(); + newtGotorc(0, 0); + er.result = ER_SWALLOWED; + if (co->callback) + co->callback(co, co->callbackData); + break; + + case EV_KEYPRESS: + ch = ev.u.key; + if (en->filter) + ch = en->filter(co, en->filterData, ch, en->cursorPosition); + if (ch) er = entryHandleKey(co, ch); + break; + + case EV_MOUSE: + if ((ev.u.mouse.type == MOUSE_BUTTON_DOWN) && + (en->flags ^ NEWT_FLAG_HIDDEN)) { + if (strlen(en->buf) >= ev.u.mouse.x - co->left) { + en->cursorPosition = ev.u.mouse.x - co->left; + newtGotorc(co->top, + co->left +(en->cursorPosition - en->firstChar)); + } else { + en->cursorPosition = strlen(en->buf); + newtGotorc(co->top, + co->left +(en->cursorPosition - en->firstChar)); + } + } + break; + } + } + + return er; +} + +static int previous_char(const char *buf, int pos) +{ + int len = 0; + int off = 0; + + while (off < pos) { + len = mblen(buf+off, MB_CUR_MAX); + if (len <= 0) + return pos; + off+=len; + } + return off-len; +} + +static int next_char(const char *buf, int pos) +{ + int len = mblen(buf + pos, MB_CUR_MAX); + if (len <= 0) + return pos; + return pos+len; +} + +static struct eventResult entryHandleKey(newtComponent co, int key) { + struct entry * en = co->data; + struct eventResult er; + char * chptr; + + er.result = ER_SWALLOWED; + switch (key) { + case '\r': /* Return */ + if (en->flags & NEWT_FLAG_RETURNEXIT) { + newtCursorOff(); + er.result = ER_EXITFORM; + } else { + er.result = ER_NEXTCOMP; + } + break; + + case '\001': /* ^A */ + case NEWT_KEY_HOME: + en->cursorPosition = 0; + break; + + case '\005': /* ^E */ + case NEWT_KEY_END: + en->cursorPosition = en->bufUsed; + break; + + case '\013': /* ^K */ + en->bufUsed = en->cursorPosition; + memset(en->buf + en->bufUsed, 0, en->bufAlloced - en->bufUsed); + break; + + case '\025': /* ^U */ + en->bufUsed -= en->cursorPosition; + memmove(en->buf, en->buf + en->cursorPosition, en->bufUsed); + en->cursorPosition = 0; + memset(en->buf + en->bufUsed, 0, en->bufAlloced - en->bufUsed); + break; + + case '\002': /* ^B */ + case NEWT_KEY_LEFT: + if (en->cursorPosition) + en->cursorPosition = previous_char(en->buf, en->cursorPosition); + break; + + case '\004': + case NEWT_KEY_DELETE: + chptr = en->buf + en->cursorPosition; + if (*chptr) { + int delta = next_char(en->buf, en->cursorPosition)-en->cursorPosition; + if (delta) { + chptr+=delta; + while (*chptr) { + *(chptr - delta) = *chptr; + chptr++; + } + memset(chptr - delta, 0, delta); + en->bufUsed-=delta; + } + } + break; + + case NEWT_KEY_BKSPC: { + int prev = previous_char(en->buf, en->cursorPosition); + if (en->cursorPosition != prev) { + /* if this isn't true, there's nothing to erase */ + int delta = en->cursorPosition - prev; + chptr = en->buf + en->cursorPosition; + en->bufUsed-=delta; + en->cursorPosition-=delta; + while (*chptr) { + *(chptr - delta) = *chptr; + chptr++; + } + memset(chptr - delta, 0, delta); + } + } + break; + + case '\006': /* ^B */ + case NEWT_KEY_RIGHT: + if (en->cursorPosition < en->bufUsed) + en->cursorPosition = next_char(en->buf, en->cursorPosition); + break; + + default: + if ((key >= 0x20 && key <= 0x7e) || (key >= 0x80 && key <= 0xff)) { + char s[MB_CUR_MAX]; + mbstate_t ps; + int i, l; + + for (i = 1, s[0] = key; ; i++) { + memset(&ps, 0, sizeof (ps)); + l = mbrtowc(NULL, s, i, &ps); + if (l == -1) /* invalid sequence */ + i = 0; + if (l != -2) /* not incomplete sequence */ + break; + + /* read next byte */ + if (i == MB_CUR_MAX || !SLang_input_pending(1)) { + i = 0; + break; + } + s[i] = SLang_getkey(); + } + + if (!i || (!(en->flags & NEWT_FLAG_SCROLL) && wstrlen(en->buf, -1) + wstrlen(s, i) > co->width)) { + /* FIXME this is broken */ + SLtt_beep(); + break; + } + + if ((en->bufUsed + i) >= en->bufAlloced) { + en->bufAlloced += 20; + en->buf = realloc(en->buf, en->bufAlloced); + if (en->resultPtr) *en->resultPtr = en->buf; + memset(en->buf + en->bufAlloced - 20, 0, 20); + } + + if (en->cursorPosition != en->bufUsed) { + /* insert the new character */ + memmove(en->buf + en->cursorPosition + i, en->buf + en->cursorPosition, en->bufUsed - en->cursorPosition); + } + en->bufUsed += i; + for (l = 0; l < i; l++) + en->buf[en->cursorPosition++] = s[l]; + } else { + er.result = ER_IGNORED; + } + } + + if (en->cursorPosition == en->bufUsed && en->cursorPosition && + !(en->flags & NEWT_FLAG_SCROLL || wstrlen(en->buf, -1) < co->width)) + en->cursorPosition = previous_char(en->buf, en->cursorPosition); + + entryDraw(co); + + return er; +} + +char * newtEntryGetValue(newtComponent co) { + struct entry * en = co->data; + + return en->buf; +} + +void newtEntrySetFilter(newtComponent co, newtEntryFilter filter, void * data) { + struct entry * en = co->data; + en->filter = filter; + en->filterData = data; +} + +int newtEntryGetCursorPosition (newtComponent co) { + struct entry * en = co->data; + + return en->cursorPosition; +} + +void newtEntrySetCursorPosition (newtComponent co, int position) { + struct entry * en = co->data; + + en->cursorPosition = position; +} diff --git a/form.c b/form.c new file mode 100644 index 0000000..24c601d --- /dev/null +++ b/form.c @@ -0,0 +1,1231 @@ +#include "config.h" + +#include + +#include +#include +#include +#ifdef HAVE_SYS_SELECT_H +#include +#endif +#include + +#ifdef USE_GPM +#include +#include /* timeval */ +#include /* socket() */ +#include /* struct sockaddr_un */ +#include /* O_RDONLY */ +#include /* stat() */ +#include /* winsize */ +#include +#include /* KDGETMODE */ +#include +#include +#endif + +#include "newt.h" +#include "newt_pr.h" + +#ifdef USE_GPM +/*....................................... The connection data structure */ + +typedef struct Gpm_Connect { + unsigned short eventMask, defaultMask; + unsigned short minMod, maxMod; + int pid; + int vc; +} Gpm_Connect; + +/*....................................... Stack struct */ +typedef struct Gpm_Stst { + Gpm_Connect info; + struct Gpm_Stst *next; +} Gpm_Stst; + +enum Gpm_Etype { + GPM_MOVE=1, + GPM_DRAG=2, /* exactly one of the bare ones is active at a time */ + GPM_DOWN=4, + GPM_UP= 8, + +#define GPM_BARE_EVENTS(type) ((type)&(0x0f|GPM_ENTER|GPM_LEAVE)) + + GPM_SINGLE=16, /* at most one in three is set */ + GPM_DOUBLE=32, + GPM_TRIPLE=64, /* WARNING: I depend on the values */ + + GPM_MFLAG=128, /* motion during click? */ + GPM_HARD=256, /* if set in the defaultMask, force an already + used event to pass over to another handler */ + + GPM_ENTER=512, /* enter event, user in Roi's */ + GPM_LEAVE=1024 /* leave event, used in Roi's */ +}; + +/*....................................... The reported event */ + +enum Gpm_Margin {GPM_TOP=1, GPM_BOT=2, GPM_LFT=4, GPM_RGT=8}; + +typedef struct Gpm_Event { + unsigned char buttons, modifiers; /* try to be a multiple of 4 */ + unsigned short vc; + short dx, dy, x, y; + enum Gpm_Etype type; + int clicks; + enum Gpm_Margin margin; +} Gpm_Event; + +static int Gpm_Open(Gpm_Connect *conn, int flag); +static int Gpm_Close(void); + +static int gpm_fd=-1; +static int gpm_flag=0; +static int gpm_tried=0; +Gpm_Stst *gpm_stack=NULL; +static char *gpm_sock_name=NULL; +static struct sigaction gpm_saved_suspend_hook; +static struct sigaction gpm_saved_winch_hook; + +#define GPM_XTERM_ON +#define GPM_XTERM_OFF +#define GPM_NODE_DEV "/dev/gpmctl" +#define GPM_NODE_CTL GPM_NODE_DEV + +static inline int putdata(int where, Gpm_Connect *what) +{ + if (write(where,what,sizeof(Gpm_Connect))!=sizeof(Gpm_Connect)) + { + return -1; + } + return 0; +} + +static void gpm_winch_hook (int signum) +{ + if (SIG_IGN != gpm_saved_winch_hook.sa_handler && + SIG_DFL != gpm_saved_winch_hook.sa_handler) { + gpm_saved_winch_hook.sa_handler(signum); + } /*if*/ +} + +static void gpm_suspend_hook (int signum) +{ + Gpm_Connect gpm_connect; + sigset_t old_sigset; + sigset_t new_sigset; + struct sigaction sa; + int success; + + sigemptyset (&new_sigset); + sigaddset (&new_sigset, SIGTSTP); + sigprocmask (SIG_BLOCK, &new_sigset, &old_sigset); + + /* Open a completely transparent gpm connection */ + gpm_connect.eventMask = 0; + gpm_connect.defaultMask = ~0; + gpm_connect.minMod = ~0; + gpm_connect.maxMod = 0; + /* cannot do this under xterm, tough */ + success = (Gpm_Open (&gpm_connect, 0) >= 0); + + /* take the default action, whatever it is (probably a stop :) */ + sigprocmask (SIG_SETMASK, &old_sigset, 0); + sigaction (SIGTSTP, &gpm_saved_suspend_hook, 0); + kill (getpid (), SIGTSTP); + + /* in bardo here */ + + /* Reincarnation. Prepare for another death early. */ + sigemptyset(&sa.sa_mask); + sa.sa_handler = gpm_suspend_hook; + sa.sa_flags = SA_NOMASK; + sigaction (SIGTSTP, &sa, 0); + + /* Pop the gpm stack by closing the useless connection */ + /* but do it only when we know we opened one.. */ + if (success) { + Gpm_Close (); + } /*if*/ +} + +static int Gpm_Open(Gpm_Connect *conn, int flag) +{ + char tty[32]; + char *term; + int i; + struct sockaddr_un addr; + Gpm_Stst *new; + + /*....................................... First of all, check xterm */ + + if ((term=(char *)getenv("TERM")) && !strncmp(term,"xterm",5)) + { + if (gpm_tried) return gpm_fd; /* no stack */ + gpm_fd=-2; + GPM_XTERM_ON; + gpm_flag=1; + return gpm_fd; + } + /*....................................... No xterm, go on */ + + + /* + * So I chose to use the current tty, instead of /dev/console, which + * has permission problems. (I am fool, and my console is + * readable/writeable by everybody. + * + * However, making this piece of code work has been a real hassle. + */ + + if (!gpm_flag && gpm_tried) return -1; + gpm_tried=1; /* do or die */ + + new=malloc(sizeof(Gpm_Stst)); + if (!new) return -1; + + new->next=gpm_stack; + gpm_stack=new; + + conn->pid=getpid(); /* fill obvious values */ + + if (new->next) + conn->vc=new->next->info.vc; /* inherit */ + else + { + conn->vc=0; /* default handler */ + if (flag>0) + { /* forced vc number */ + conn->vc=flag; + sprintf(tty,"/dev/tty%i",flag); + } + else if (flag==0) /* use your current vc */ + { + char *t = ttyname(0); /* stdin */ + if (!t) t = ttyname(1); /* stdout */ + if (!t) goto err; + strcpy(tty,t); + if (strncmp(tty,"/dev/tty",8) || !isdigit(tty[8])) + goto err; + conn->vc=atoi(tty+8); + } + else /* a default handler -- use console */ + sprintf(tty,"/dev/tty0"); + + } + + new->info=*conn; + + /*....................................... Connect to the control socket */ + + if (!(gpm_flag++)) + { + + if ( (gpm_fd=socket(AF_UNIX,SOCK_STREAM,0))<0 ) + { + goto err; + } + + bzero((char *)&addr,sizeof(addr)); + addr.sun_family=AF_UNIX; + if (!(gpm_sock_name = tempnam (0, "gpm"))) { + goto err; + } /*if*/ + strncpy (addr.sun_path, gpm_sock_name, sizeof (addr.sun_path)); + if (bind (gpm_fd, (struct sockaddr*)&addr, + sizeof (addr.sun_family) + strlen (addr.sun_path))==-1) { + goto err; + } /*if*/ + + bzero((char *)&addr,sizeof(addr)); + addr.sun_family=AF_UNIX; + strcpy(addr.sun_path, GPM_NODE_CTL); + i=sizeof(addr.sun_family)+strlen(GPM_NODE_CTL); + + if ( connect(gpm_fd,(struct sockaddr *)(&addr),i)<0 ) + { + struct stat stbuf; + + /* + * Well, try to open a chr device called /dev/gpmctl. This should + * be forward-compatible with a kernel server + */ + close(gpm_fd); /* the socket */ + if ((gpm_fd=open(GPM_NODE_DEV,O_RDWR))==-1) { + goto err; + } /*if*/ + if (fstat(gpm_fd,&stbuf)==-1 || (stbuf.st_mode&S_IFMT)!=S_IFCHR) + goto err; + } + } + /*....................................... Put your data */ + + if (putdata(gpm_fd,conn)!=-1) + { + /* itz Wed Dec 16 23:22:16 PST 1998 use sigaction, the old + code caused a signal loop under XEmacs */ + struct sigaction sa; + sigemptyset(&sa.sa_mask); + +#if (defined(SIGWINCH)) + /* And the winch hook .. */ + sa.sa_handler = gpm_winch_hook; + sa.sa_flags = 0; + sigaction(SIGWINCH, &sa, &gpm_saved_winch_hook); +#endif + +#if (defined(SIGTSTP)) + if (gpm_flag == 1) { + /* Install suspend hook */ + sa.sa_handler = SIG_IGN; + sigaction(SIGTSTP, &sa, &gpm_saved_suspend_hook); + + /* if signal was originally ignored, job control is not supported */ + if (gpm_saved_suspend_hook.sa_handler != SIG_IGN) { + sa.sa_flags = SA_NOMASK; + sa.sa_handler = gpm_suspend_hook; + sigaction(SIGTSTP, &sa, 0); + } /*if*/ + } /*if*/ +#endif + + } /*if*/ + return gpm_fd; + + /*....................................... Error: free all memory */ + err: + do + { + new=gpm_stack->next; + free(gpm_stack); + gpm_stack=new; + } + while(gpm_stack); + if (gpm_fd>=0) close(gpm_fd); + if (gpm_sock_name) { + unlink(gpm_sock_name); + free(gpm_sock_name); + gpm_sock_name = NULL; + } /*if*/ + gpm_flag=0; + gpm_fd=-1; + return -1; +} + +/*-------------------------------------------------------------------*/ +static int Gpm_Close(void) +{ + Gpm_Stst *next; + + gpm_tried=0; /* reset the error flag for next time */ + if (gpm_fd==-2) /* xterm */ + GPM_XTERM_OFF; + else /* linux */ + { + if (!gpm_flag) return 0; + next=gpm_stack->next; + free(gpm_stack); + gpm_stack=next; + if (next) + putdata(gpm_fd,&(next->info)); + + if (--gpm_flag) return -1; + } + + if (gpm_fd>=0) close(gpm_fd); + gpm_fd=-1; + if (gpm_sock_name) { + unlink(gpm_sock_name); + free(gpm_sock_name); + gpm_sock_name = NULL; + } +#ifdef SIGTSTP + sigaction(SIGTSTP, &gpm_saved_suspend_hook, 0); +#endif +#ifdef SIGWINCH + sigaction(SIGWINCH, &gpm_saved_winch_hook, 0); +#endif + return 0; +} + +/*-------------------------------------------------------------------*/ +static int Gpm_GetEvent(Gpm_Event *event) +{ + int count; + + if (!gpm_flag) return 0; + + if ((count=read(gpm_fd,event,sizeof(Gpm_Event)))!=sizeof(Gpm_Event)) + { + if (count==0) + { + Gpm_Close(); + return 0; + } + return -1; + } + return 1; +} +#endif + +/**************************************************************************** + These forms handle vertical scrolling of components with a height of 1 + + Horizontal scrolling won't work, and scrolling large widgets will fail + miserably. It shouldn't be too hard to fix either of those if anyone + cares to. I only use scrolling for listboxes and text boxes though so + I didn't bother. +*****************************************************************************/ + +struct element { + newtComponent co; +}; + +struct fdInfo { + int fd; + int flags; +}; + +struct form { + int numCompsAlloced; + struct element * elements; + int numComps; + int currComp; + int fixedHeight; + int flags; + int vertOffset; + newtComponent vertBar, exitComp; + const char * help; + int numRows; + int * hotKeys; + int numHotKeys; + int background; + int numFds; + struct fdInfo * fds; + int maxFd; + int timer; /* in milliseconds */ + struct timeval lastTimeout; + void * helpTag; + newtCallback helpCb; +}; + +static void gotoComponent(newtComponent co, int newComp); +static struct eventResult formEvent(newtComponent co, struct event ev); +static struct eventResult sendEvent(newtComponent comp, struct event ev); +static void formPlace(newtComponent co, int left, int top); + +/* Global, ick */ +static newtCallback helpCallback; + +/* this isn't static as grid.c tests against it to find forms */ +struct componentOps formOps = { + newtDrawForm, + formEvent, + newtFormDestroy, + formPlace, + newtDefaultMappedHandler, +} ; + +int needResize = 0; + +static inline int componentFits(newtComponent co, int compNum) { + struct form * form = co->data; + struct element * el = form->elements + compNum; + + if (co->top > el->co->top) + return 0; + if (co->top + co->height < el->co->top + el->co->height) + return 0; + + return 1; +} + +newtComponent newtForm(newtComponent vertBar, void * help, int flags) { + newtComponent co; + struct form * form; + + co = malloc(sizeof(*co)); + form = malloc(sizeof(*form)); + co->data = form; + co->width = 0; + co->height = 0; + co->top = -1; + co->left = -1; + co->isMapped = 0; + + co->takesFocus = 0; /* we may have 0 components */ + co->ops = &formOps; + co->callback = NULL; + co->destroyCallback = NULL; + + form->help = help; + form->flags = flags; + form->numCompsAlloced = 5; + form->numComps = 0; + form->currComp = -1; + form->vertOffset = 0; + form->fixedHeight = 0; + form->numRows = 0; + form->numFds = 0; + form->maxFd = 0; + form->fds = NULL; + form->elements = malloc(sizeof(*(form->elements)) * form->numCompsAlloced); + + form->background = COLORSET_WINDOW; + form->hotKeys = malloc(sizeof(int)); + form->numHotKeys = 0; + form->timer = 0; + form->lastTimeout.tv_sec = form->lastTimeout.tv_usec = 0; + if (!(form->flags & NEWT_FLAG_NOF12)) { + newtFormAddHotKey(co, NEWT_KEY_F12); + } + + if (vertBar) + form->vertBar = vertBar; + else + form->vertBar = NULL; + + form->helpTag = help; + form->helpCb = helpCallback; + + return co; +} + +newtComponent newtFormGetCurrent(newtComponent co) { + struct form * form = co->data; + + if (form->currComp == -1) return 0; + return form->elements[form->currComp].co; +} + +static void formScroll(newtComponent co, int delta) { + struct form * form = co->data; + struct element * el; + int i, newVertOffset = form->vertOffset + delta; + + if (newVertOffset < 0) + newVertOffset = 0; + if (newVertOffset > form->numRows - co->height) + newVertOffset = form->numRows - co->height; + + delta = newVertOffset - form->vertOffset; + form->vertOffset = newVertOffset; + + for (i = 0, el = form->elements; i < form->numComps; i++, el++) { + if (el->co == form->vertBar) + continue; + el->co->ops->place(el->co, el->co->left, el->co->top - delta); + } +} + +int newtFormGetScrollPosition(newtComponent co) { + struct form * form = co->data; + + return form->vertOffset; +} + +void newtFormSetScrollPosition(newtComponent co, int position) { + struct form * form = co->data; + + if (form->numRows == 0) + newtFormSetSize(co); + formScroll(co, position - form->vertOffset); +} + +void newtFormSetCurrent(newtComponent co, newtComponent subco) { + struct form * form = co->data; + int i, new; + + for (i = 0; i < form->numComps; i++) { + if (form->elements[i].co == subco) break; + } + + if (form->elements[i].co != subco) return; + new = i; + + if (co->isMapped && !componentFits(co, new)) { + gotoComponent(co, -1); + formScroll(co, form->elements[new].co->top - co->top - 1); + } + + gotoComponent(co, new); +} + +void newtFormSetTimer(newtComponent co, int millisecs) { + struct form * form = co->data; + + form->timer = millisecs; + form->lastTimeout.tv_usec = 0; + form->lastTimeout.tv_sec = 0; +} + +void newtFormSetHeight(newtComponent co, int height) { + struct form * form = co->data; + + form->fixedHeight = 1; + co->height = height; +} + +void newtFormSetWidth(newtComponent co, int width) { + co->width = width; +} + +void newtFormAddComponent(newtComponent co, newtComponent newco) { + struct form * form = co->data; + + co->takesFocus = 1; + + if (form->numCompsAlloced == form->numComps) { + form->numCompsAlloced += 5; + form->elements = realloc(form->elements, + sizeof(*(form->elements)) * form->numCompsAlloced); + } + + form->elements[form->numComps].co = newco; + + if (newco->takesFocus && form->currComp == -1) + form->currComp = form->numComps; + + form->numComps++; +} + +void newtFormAddComponents(newtComponent co, ...) { + va_list ap; + newtComponent subco; + + va_start(ap, co); + + while ((subco = va_arg(ap, newtComponent))) + newtFormAddComponent(co, subco); + + va_end(ap); +} + +static void formPlace(newtComponent co, int left, int top) { + struct form * form = co->data; + int vertDelta, horizDelta; + struct element * el; + int i; + + vertDelta = top - co->top; + horizDelta = left - co->left; + co->top = top; + co->left = left; + + for (i = 0, el = form->elements; i < form->numComps; i++, el++) { + el->co->ops->place(el->co, el->co->left + horizDelta, + el->co->top + vertDelta); + } +} + +void newtDrawForm(newtComponent co) { + struct form * form = co->data; + struct element * el; + int i; + + newtFormSetSize(co); + + SLsmg_set_color(form->background); + newtClearBox(co->left, co->top, co->width, co->height); + + for (i = 0, el = form->elements; i < form->numComps; i++, el++) { + /* only draw it if it'll fit on the screen vertically + (the scrollbar *always* fits somewhere) */ + if (el->co == form->vertBar || componentFits(co, i)) { + el->co->ops->mapped(el->co, 1); + el->co->ops->draw(el->co); + } else { + el->co->ops->mapped(el->co, 0); + } + } + + if (form->vertBar) + newtScrollbarSet(form->vertBar, form->vertOffset, + form->numRows - co->height); +} + +static struct eventResult formEvent(newtComponent co, struct event ev) { + struct form * form = co->data; + newtComponent subco = form->elements[form->currComp].co; + int new, wrap = 0; + struct eventResult er; + int dir = 0, page = 0; + int i, num, found; + struct element * el; + + er.result = ER_IGNORED; + if (!form->numComps) return er; + + if (form->currComp == -1) return er; + + switch (ev.when) { + case EV_EARLY: + if (ev.event == EV_KEYPRESS) { + if (ev.u.key == NEWT_KEY_TAB) { + er.result = ER_SWALLOWED; + dir = 1; + wrap = 1; + } else if (ev.u.key == NEWT_KEY_UNTAB) { + er.result = ER_SWALLOWED; + dir = -1; + wrap = 1; + } + } + + if (form->numComps) { + i = form->currComp; + num = 0; + while (er.result == ER_IGNORED && num != form->numComps ) { + er = form->elements[i].co->ops->event(form->elements[i].co, ev); + + num++; + i++; + if (i == form->numComps) i = 0; + } + } + + break; + + case EV_NORMAL: + if (ev.event == EV_MOUSE) { + found = 0; + for (i = 0, el = form->elements; i < form->numComps; i++, el++) { + if ((el->co->top <= ev.u.mouse.y) && + (el->co->top + el->co->height > ev.u.mouse.y) && + (el->co->left <= ev.u.mouse.x) && + (el->co->left + el->co->width > ev.u.mouse.x)) { + found = 1; + if (el->co->takesFocus) { + gotoComponent(co, i); + subco = form->elements[form->currComp].co; + } + } + /* If we did not find a co to send this event to, we + should just swallow the event here. */ + } + if (!found) { + er.result = ER_SWALLOWED; + + return er; + } + } + er = subco->ops->event(subco, ev); + switch (er.result) { + case ER_NEXTCOMP: + er.result = ER_SWALLOWED; + dir = 1; + break; + + case ER_EXITFORM: + form->exitComp = subco; + break; + + default: + break; + } + break; + + case EV_LATE: + er = subco->ops->event(subco, ev); + + if (er.result == ER_IGNORED) { + switch (ev.u.key) { + case NEWT_KEY_UP: + case NEWT_KEY_LEFT: + case NEWT_KEY_BKSPC: + er.result = ER_SWALLOWED; + dir = -1; + break; + + case NEWT_KEY_DOWN: + case NEWT_KEY_RIGHT: + er.result = ER_SWALLOWED; + dir = 1; + break; + + case NEWT_KEY_PGUP: + er.result = ER_SWALLOWED; + dir = -1; + page = 1; + break; + + case NEWT_KEY_PGDN: + er.result = ER_SWALLOWED; + dir = 1; + page = 1; + break; + } + } + } + + if (dir) { + new = form->currComp; + + if (page) { + new += dir * co->height; + if (new < 0) + new = 0; + else if (new >= form->numComps) + new = (form->numComps - 1); + + while (!form->elements[new].co->takesFocus && + new - dir >= 0 && new - dir < form->numComps) + new -= dir; + } else { + do { + new += dir; + + if (wrap) { + if (new < 0) + new = form->numComps - 1; + else if (new >= form->numComps) + new = 0; + if (new == form->currComp) + /* back where we started */ + return er; + } else if (new < 0 || new >= form->numComps) + return er; + } while (!form->elements[new].co->takesFocus); + } + + /* make sure this component is visible */ + if (!componentFits(co, new)) { + int vertDelta; + + gotoComponent(co, -1); + + if (dir < 0) { + /* make the new component the first one */ + vertDelta = form->elements[new].co->top - co->top; + } else { + /* make the new component the last one */ + vertDelta = (form->elements[new].co->top + + form->elements[new].co->height) - + (co->top + co->height); + } + + formScroll(co, vertDelta); + newtDrawForm(co); + } + + gotoComponent(co, new); + er.result = ER_SWALLOWED; + } + + return er; +} + +/* Destroy a component. Components which have been added to a form + * are destroyed when the form is destroyed; this is just for the + * (rare) case of components which for whatever reason weren't added + * to a form. + */ +void newtComponentDestroy(newtComponent co) { + /* If the user registered a destroy callback for this component, + * now is a good time to call it. + */ + if (co->destroyCallback) + co->destroyCallback(co, co->destroyCallbackData); + + if (co->ops->destroy) { + co->ops->destroy(co); + } else { + if (co->data) free(co->data); + free(co); + } +} + +/* this also destroys all of the components on the form */ +void newtFormDestroy(newtComponent co) { + newtComponent subco; + struct form * form = co->data; + int i; + + /* first, destroy all of the components */ + for (i = 0; i < form->numComps; i++) { + subco = form->elements[i].co; + newtComponentDestroy(subco); + } + + if (form->hotKeys) free(form->hotKeys); + + free(form->elements); + free(form); + free(co); +} + +newtComponent newtRunForm(newtComponent co) { + struct newtExitStruct es; + + newtFormRun(co, &es); + if (es.reason == NEWT_EXIT_HOTKEY) { + if (es.u.key == NEWT_KEY_F12) { + es.reason = NEWT_EXIT_COMPONENT; + es.u.co = co; + } else { + return NULL; + } + } else if (es.reason == NEWT_EXIT_ERROR) + return NULL; + + return es.u.co; +} + +void newtFormAddHotKey(newtComponent co, int key) { + struct form * form = co->data; + + form->numHotKeys++; + form->hotKeys = realloc(form->hotKeys, sizeof(int) * form->numHotKeys); + form->hotKeys[form->numHotKeys - 1] = key; +} + +void newtFormSetSize(newtComponent co) { + struct form * form = co->data; + int delta, i, first; + struct element * el; + + form->numRows = 0; + + co->width = 0; + if (!form->fixedHeight) co->height = 0; + + co->top = -1; + co->left = -1; + first = 1; + + for (i = 0, el = form->elements; i < form->numComps; i++, el++) { + if (el->co->ops == &formOps) + newtFormSetSize(el->co); + else if (el->co == form->vertBar) + continue; + + if (first) { + co->top = el->co->top; + co->left = el->co->left; + first = 0; + } + + if (co->left > el->co->left) { + delta = co->left - el->co->left; + co->left -= delta; + co->width += delta; + } + + if (co->top > el->co->top) { + delta = co->top - el->co->top; + co->top -= delta; + form->numRows += delta; + if (!form->fixedHeight) + co->height += delta; + } + + if ((co->left + co->width) < (el->co->left + el->co->width)) + co->width = (el->co->left + el->co->width) - co->left; + + if (!form->fixedHeight) { + if ((co->top + co->height) < (el->co->top + el->co->height)) + co->height = (el->co->top + el->co->height) - co->top; + } + + if ((el->co->top + el->co->height - co->top) > form->numRows) { + form->numRows = el->co->top + el->co->height - co->top; + } + } + + co->top += form->vertOffset; +} + +void newtFormRun(newtComponent co, struct newtExitStruct * es) { + struct form * form = co->data; + struct event ev; + struct eventResult er; + int key, i, max; + int done = 0; + fd_set readSet, writeSet, exceptSet; + struct timeval nextTimeout, now, timeout; +#ifdef USE_GPM + int x, y; + Gpm_Connect conn; + Gpm_Event event; + + /* Set up GPM interface */ + conn.eventMask = ~GPM_MOVE; + conn.defaultMask = GPM_MOVE; + conn.minMod = 0; + conn.maxMod = 0; + + Gpm_Open(&conn, 0); +#endif + + /* draw all of the components */ + newtDrawForm(co); + + if (form->currComp == -1) { + if (form->numComps) + gotoComponent(co, 0); + } else + gotoComponent(co, form->currComp); + + while (!done) { + newtRefresh(); + + FD_ZERO(&readSet); + FD_ZERO(&writeSet); + FD_ZERO(&exceptSet); + FD_SET(0, &readSet); +#ifdef USE_GPM + if (gpm_fd > 0) { + FD_SET(gpm_fd, &readSet); + } + max = form->maxFd > gpm_fd ? form->maxFd : gpm_fd; +#else + max = form->maxFd; +#endif + + for (i = 0; i < form->numFds; i++) { + if (form->fds[i].flags & NEWT_FD_READ) + FD_SET(form->fds[i].fd, &readSet); + if (form->fds[i].flags & NEWT_FD_WRITE) + FD_SET(form->fds[i].fd, &writeSet); + if (form->fds[i].flags & NEWT_FD_EXCEPT) + FD_SET(form->fds[i].fd, &exceptSet); + } + + if (form->timer) { + /* Calculate when we next need to return with a timeout. Do + this inside the loop in case a callback resets the timer. */ + gettimeofday(&now, 0); + + if ((!form->lastTimeout.tv_sec && !form->lastTimeout.tv_usec) || + now.tv_sec < form->lastTimeout.tv_sec || + (now.tv_sec == form->lastTimeout.tv_sec && + now.tv_usec < form->lastTimeout.tv_usec)) + form->lastTimeout = now; + + nextTimeout.tv_sec = form->lastTimeout.tv_sec + + (form->timer / 1000); + nextTimeout.tv_usec = form->lastTimeout.tv_usec + + (form->timer % 1000) * 1000; + + if (now.tv_sec > nextTimeout.tv_sec) { + timeout.tv_sec = timeout.tv_usec = 0; + } else if (now.tv_sec == nextTimeout.tv_sec) { + timeout.tv_sec = 0; + if (now.tv_usec > nextTimeout.tv_usec) + timeout.tv_usec = 0; + else + timeout.tv_usec = nextTimeout.tv_usec - now.tv_usec; + } else if (now.tv_sec < nextTimeout.tv_sec) { + timeout.tv_sec = nextTimeout.tv_sec - now.tv_sec; + if (now.tv_usec > nextTimeout.tv_usec) + timeout.tv_sec--, + timeout.tv_usec = nextTimeout.tv_usec + 1000000 - + now.tv_usec; + else + timeout.tv_usec = nextTimeout.tv_usec - now.tv_usec; + } + } else { + timeout.tv_sec = timeout.tv_usec = 0; + } + + if (needResize) { + needResize = 0; + newtResizeScreen(1); + + /* The application may want to handle the resize */ + for (i = 0; i < form->numHotKeys; i++) { + if (form->hotKeys[i] == NEWT_KEY_RESIZE) { + es->reason = NEWT_EXIT_HOTKEY; + es->u.key = NEWT_KEY_RESIZE; + done = 1; + break; + } + } + if (done) + break; + } + + i = select(max + 1, &readSet, &writeSet, &exceptSet, + form->timer ? &timeout : NULL); + if (i < 0) continue; /* ?? What should we do here? */ + + if (i == 0) { + done = 1; + es->reason = NEWT_EXIT_TIMER; + gettimeofday(&form->lastTimeout, NULL); + } else +#ifdef USE_GPM + if (gpm_fd > 0 && FD_ISSET(gpm_fd, &readSet)) { + Gpm_GetEvent(&event); + + if (event.type & GPM_DOWN) { + /* Transform coordinates to current window */ + newtGetWindowPos(&x, &y); + + ev.event = EV_MOUSE; + ev.u.mouse.type = MOUSE_BUTTON_DOWN; + ev.u.mouse.x = event.x - x - 1; + ev.u.mouse.y = event.y - y - 1; + + /* Send the form the event */ + er = sendEvent(co, ev); + + if (er.result == ER_EXITFORM) { + done = 1; + es->reason = NEWT_EXIT_COMPONENT; + es->u.co = form->exitComp; + } + + } + } else +#endif + { + if (FD_ISSET(0, &readSet)) { + + key = newtGetKey(); + + for (i = 0; i < form->numHotKeys; i++) { + if (form->hotKeys[i] == key) { + es->reason = NEWT_EXIT_HOTKEY; + es->u.key = key; + done = 1; + break; + } + } + + if (key == NEWT_KEY_F1 && form->helpTag && form->helpCb) { + if (form->currComp != -1) { + ev.event = EV_UNFOCUS; + sendEvent(form->elements[form->currComp].co, ev); + } + form->helpCb(co, form->helpTag); + if (form->currComp != -1) { + ev.event = EV_FOCUS; + sendEvent(form->elements[form->currComp].co, ev); + } + } + + if (key == NEWT_KEY_ERROR) { + es->u.watch = -1; + es->reason = NEWT_EXIT_ERROR; + done = 1; + } + + if (!done) { + ev.event = EV_KEYPRESS; + ev.u.key = key; + + er = sendEvent(co, ev); + + if (er.result == ER_EXITFORM) { + done = 1; + es->reason = NEWT_EXIT_COMPONENT; + es->u.co = form->exitComp; + } + } + } else { + for (i = 0; i < form->numFds; i++) { + if (((form->fds[i].flags & NEWT_FD_READ) + && FD_ISSET(form->fds[i].fd, &readSet)) + || ((form->fds[i].flags & NEWT_FD_WRITE) + && FD_ISSET(form->fds[i].fd, &writeSet)) + || ((form->fds[i].flags & NEWT_FD_EXCEPT) + && FD_ISSET(form->fds[i].fd, &exceptSet))) break; + } + if(i < form->numFds) + es->u.watch = form->fds[i].fd; + else + es->u.watch = -1; + + es->reason = NEWT_EXIT_FDREADY; + done = 1; + } + } + } + newtRefresh(); +#ifdef USE_GPM + Gpm_Close(); +#endif +} + +static struct eventResult sendEvent(newtComponent co, struct event ev) { + struct eventResult er; + + ev.when = EV_EARLY; + er = co->ops->event(co, ev); + + if (er.result == ER_IGNORED) { + ev.when = EV_NORMAL; + er = co->ops->event(co, ev); + } + + if (er.result == ER_IGNORED) { + ev.when = EV_LATE; + er = co->ops->event(co, ev); + } + + return er; +} + +static void gotoComponent(newtComponent co, int newComp) { + struct form * form = co->data; + struct event ev; + + if (form->currComp != -1) { + ev.event = EV_UNFOCUS; + sendEvent(form->elements[form->currComp].co, ev); + } + + form->currComp = newComp; + + if (form->currComp != -1) { + ev.event = EV_FOCUS; + ev.when = EV_NORMAL; + sendEvent(form->elements[form->currComp].co, ev); + } + + if (co->callback) + co->callback(co, co->callbackData); +} + +void newtComponentAddCallback(newtComponent co, newtCallback f, void * data) { + co->callback = f; + co->callbackData = data; +} + +/* Add a callback which is called when the component is destroyed. */ +void newtComponentAddDestroyCallback(newtComponent co, + newtCallback f, void * data) { + co->destroyCallback = f; + co->destroyCallbackData = data; +} + +void newtComponentTakesFocus(newtComponent co, int val) { + co->takesFocus = val; +} + +void newtFormSetBackground(newtComponent co, int color) { + struct form * form = co->data; + + form->background = color; +} + +void newtFormWatchFd(newtComponent co, int fd, int fdFlags) { + struct form * form = co->data; + int i; + + for (i = 0; i < form->numFds; i++) + if (form->fds[i].fd == fd) + break; + + if(i >= form->numFds) + form->fds = realloc(form->fds, (++form->numFds) * sizeof(*form->fds)); + + form->fds[i].fd = fd; + form->fds[i].flags = fdFlags; + if (form->maxFd < fd) form->maxFd = fd; +} + +void newtSetHelpCallback(newtCallback cb) { + helpCallback = cb; +} diff --git a/grid.c b/grid.c new file mode 100644 index 0000000..5b4b120 --- /dev/null +++ b/grid.c @@ -0,0 +1,394 @@ +#include "config.h" + +#ifdef HAVE_ALLOCA_H +#include +#endif +#include +#include + +#include "newt.h" +#include "newt_pr.h" + +struct gridField { + enum newtGridElement type; + union { + newtGrid grid; + newtComponent co; + } u; + int padLeft, padTop, padRight, padBottom; + int anchor; + int flags; +}; + +struct grid_s { + int rows, cols; + int width, height; /* totals, -1 means unknown */ + struct gridField ** fields; +}; + +/* this is a bit of a hack */ +extern struct componentOps formOps[]; + +newtGrid newtCreateGrid(int cols, int rows) { + newtGrid grid; + + grid = malloc(sizeof(*grid)); + grid->rows = rows; + grid->cols = cols; + + grid->fields = malloc(sizeof(*grid->fields) * cols); + while (cols--) { + grid->fields[cols] = malloc(sizeof(**(grid->fields)) * rows); + memset(grid->fields[cols], 0, sizeof(**(grid->fields)) * rows); + } + + grid->width = grid->height = -1; + + return grid; +} + +void newtGridSetField(newtGrid grid, int col, int row, + enum newtGridElement type, void * val, int padLeft, + int padTop, int padRight, int padBottom, int anchor, + int flags) { + struct gridField * field = &grid->fields[col][row]; + + if (field->type == NEWT_GRID_SUBGRID) + newtGridFree(field->u.grid, 1); + + field->type = type; + field->u.co = (void *) val; + + field->padLeft = padLeft; + field->padRight = padRight; + field->padTop = padTop; + field->padBottom = padBottom; + field->anchor = anchor; + field->flags = flags; + + grid->width = grid->height = -1; +} + +static void distSpace(int extra, int items, int * list) { + int all, some, i; + + all = extra / items; + some = extra % items; + for (i = 0; i < items; i++) { + list[i] += all; + if (some) { + list[i]++; + some--; + } + } +} + +static void shuffleGrid(newtGrid grid, int left, int top, int set) { + struct gridField * field; + int row, col; + int i, j; + int minWidth, minHeight; + int * widths, * heights; + int thisLeft, thisTop; + int x, y, remx, remy; + + widths = alloca(sizeof(*widths) * grid->cols); + memset(widths, 0, sizeof(*widths) * grid->cols); + heights = alloca(sizeof(*heights) * grid->rows); + memset(heights, 0, sizeof(*heights) * grid->rows); + + minWidth = 0; + for (row = 0; row < grid->rows; row++) { + i = 0; + for (col = 0; col < grid->cols; col++) { + field = &grid->fields[col][row]; + if (field->type == NEWT_GRID_SUBGRID) { + /* we'll have to redo this later */ + if (field->u.grid->width == -1) + shuffleGrid(field->u.grid, left, top, 0); + j = field->u.grid->width; + } else if (field->type == NEWT_GRID_COMPONENT) { + if (field->u.co->ops == formOps) + newtFormSetSize(field->u.co); + j = field->u.co->width; + } else + j = 0; + + j += field->padLeft + field->padRight; + + if (j > widths[col]) widths[col] = j; + i += widths[col]; + } + + if (i > minWidth) minWidth = i; + } + + minHeight = 0; + for (col = 0; col < grid->cols; col++) { + i = 0; + for (row = 0; row < grid->rows; row++) { + field = &grid->fields[col][row]; + if (field->type == NEWT_GRID_SUBGRID) { + /* we'll have to redo this later */ + if (field->u.grid->height == -1) + shuffleGrid(field->u.grid, 0, 0, 0); + j = field->u.grid->height; + } else if (field->type == NEWT_GRID_COMPONENT){ + j = field->u.co->height; + } else + j = 0; + + j += field->padTop + field->padBottom; + + if (j > heights[row]) heights[row] = j; + i += heights[row]; + } + + if (i > minHeight) minHeight = i; + } + + /* this catches the -1 case */ + if (grid->width < minWidth) grid->width = minWidth; /* ack! */ + if (grid->height < minHeight) grid->height = minHeight; /* ditto! */ + + if (!set) return; + + distSpace(grid->width - minWidth, grid->cols, widths); + distSpace(grid->height - minHeight, grid->rows, heights); + + thisTop = top; + for (row = 0; row < grid->rows; row++) { + i = 0; + thisLeft = left; + for (col = 0; col < grid->cols; col++) { + field = &grid->fields[col][row]; + + if (field->type == NEWT_GRID_EMPTY) continue; + + x = thisLeft + field->padLeft; + remx = widths[col] - field->padLeft - field->padRight; + y = thisTop + field->padTop; + remy = heights[row] - field->padTop - field->padBottom; + + if (field->type == NEWT_GRID_SUBGRID) { + remx -= field->u.grid->width; + remy -= field->u.grid->height; + } else if (field->type == NEWT_GRID_COMPONENT) { + remx -= field->u.co->width; + remy -= field->u.co->height; + } + + if (!(field->flags & NEWT_GRID_FLAG_GROWX)) { + if (field->anchor & NEWT_ANCHOR_RIGHT) + x += remx; + else if (!(field->anchor & NEWT_ANCHOR_LEFT)) + x += (remx / 2); + } + + if (!(field->flags & NEWT_GRID_FLAG_GROWY)) { + if (field->anchor & NEWT_ANCHOR_BOTTOM) + y += remx; + else if (!(field->anchor & NEWT_ANCHOR_TOP)) + y += (remy / 2); + } + + if (field->type == NEWT_GRID_SUBGRID) { + if (field->flags & NEWT_GRID_FLAG_GROWX) + field->u.grid->width = widths[col] - field->padLeft + - field->padRight; + if (field->flags & NEWT_GRID_FLAG_GROWY) + field->u.grid->height = heights[col] - field->padTop + - field->padBottom; + + shuffleGrid(field->u.grid, x, y, 1); + } else if (field->type == NEWT_GRID_COMPONENT) { + field->u.co->ops->place(field->u.co, x, y); + } + + thisLeft += widths[col]; + } + + thisTop += heights[row]; + } +} + +void newtGridPlace(newtGrid grid, int left, int top) { + shuffleGrid(grid, left, top, 1); +} + +void newtGridFree(newtGrid grid, int recurse) { + int row, col; + + for (col = 0; col < grid->cols; col++) { + if (recurse) { + for (row = 0; row < grid->rows; row++) { + if (grid->fields[col][row].type == NEWT_GRID_SUBGRID) + newtGridFree(grid->fields[col][row].u.grid, 1); + } + } + + free(grid->fields[col]); + } + + free(grid->fields); + free(grid); +} + +void newtGridGetSize(newtGrid grid, int * width, int * height) { + if (grid->width == -1 || grid->height == -1) { + grid->width = grid->height = -1; + shuffleGrid(grid, 0, 0, 1); + } + + *width = grid->width; + *height = grid->height; +} + +void newtGridWrappedWindow(newtGrid grid, char * title) { + int w, width, height, offset = 0; + + newtGridGetSize(grid, &width, &height); + w = wstrlen(title,-1); + if (width < w + 2) { + offset = ((w + 2) - width) / 2; + width = w + 2; + } + newtCenteredWindow(width + 2, height + 2, title); + newtGridPlace(grid, 1 + offset, 1); +} + +void newtGridWrappedWindowAt(newtGrid grid, char * title, int left, int top) { + int width, height; + + newtGridGetSize(grid, &width, &height); + newtOpenWindow(left, top, width + 2, height + 2, title); + newtGridPlace(grid, 1, 1); +} + +void newtGridAddComponentsToForm(newtGrid grid, newtComponent form, + int recurse) { + int row, col; + + for (col = 0; col < grid->cols; col++) { + for (row = 0; row < grid->rows; row++) { + if (grid->fields[col][row].type == NEWT_GRID_SUBGRID && recurse) + newtGridAddComponentsToForm(grid->fields[col][row].u.grid, + form, 1); + else if (grid->fields[col][row].type == NEWT_GRID_COMPONENT) + newtFormAddComponent(form, grid->fields[col][row].u.co); + } + } +} + +/* this handles up to 50 items */ +static newtGrid stackem(int isVert, enum newtGridElement type1, void * what1, + va_list args, int close) { + struct item { + enum newtGridElement type; + void * what; + } items[50]; + int i, num; + newtGrid grid; + + items[0].type = type1, items[0].what = what1, num = 1; + while (1) { + items[num].type = va_arg(args, enum newtGridElement); + if (items[num].type == NEWT_GRID_EMPTY) break; + + items[num].what = va_arg(args, void *); + num++; + } + + grid = newtCreateGrid(isVert ? 1 : num, isVert ? num : 1); + + for (i = 0; i < num; i++) { + newtGridSetField(grid, isVert ? 0 : i, isVert ? i : 0, + items[i].type, items[i].what, + close ? 0 : (i ? (isVert ? 0 : 1) : 0), + close ? 0 : (i ? (isVert ? 1 : 0) : 0), 0, 0, 0, 0); + } + + return grid; +} + +newtGrid newtGridHCloseStacked(enum newtGridElement type1, void * what1, ...) { + va_list args; + newtGrid grid; + + va_start(args, what1); + + grid = stackem(0, type1, what1, args, 1); + + va_end(args); + + return grid; +} + +newtGrid newtGridVCloseStacked(enum newtGridElement type1, void * what1, ...) { + va_list args; + newtGrid grid; + + va_start(args, what1); + + grid = stackem(1, type1, what1, args, 1); + + va_end(args); + + return grid; +} + +newtGrid newtGridVStacked(enum newtGridElement type1, void * what1, ...) { + va_list args; + newtGrid grid; + + va_start(args, what1); + + grid = stackem(1, type1, what1, args, 0); + + va_end(args); + + return grid; +} + +newtGrid newtGridHStacked(enum newtGridElement type1, void * what1, ...) { + va_list args; + newtGrid grid; + + va_start(args, what1); + + grid = stackem(0, type1, what1, args, 0); + + va_end(args); + + return grid; +} + +newtGrid newtGridBasicWindow(newtComponent text, newtGrid middle, + newtGrid buttons) { + newtGrid grid; + + grid = newtCreateGrid(1, 3); + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text, + 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); + newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, middle, + 0, 1, 0, 0, 0, 0); + newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons, + 0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX); + + return grid; +} + +newtGrid newtGridSimpleWindow(newtComponent text, newtComponent middle, + newtGrid buttons) { + newtGrid grid; + + grid = newtCreateGrid(1, 3); + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text, + 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); + newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, middle, + 0, 1, 0, 0, 0, 0); + newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons, + 0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX); + + return grid; +} diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..0b0fdcb --- /dev/null +++ b/install-sh @@ -0,0 +1,501 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2013-12-25.23; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +tab=' ' +nl=' +' +IFS=" $tab$nl" + +# Set DOITPROG to "echo" to test this script. + +doit=${DOITPROG-} +doit_exec=${doit:-exec} + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +is_target_a_directory=possibly + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) is_target_a_directory=never;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + dstdir=`dirname "$dst"` + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + oIFS=$IFS + IFS=/ + set -f + set fnord $dstdir + shift + set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + set +f && + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/label.c b/label.c new file mode 100644 index 0000000..85fa518 --- /dev/null +++ b/label.c @@ -0,0 +1,92 @@ +#include +#include +#include + +#include "newt.h" +#include "newt_pr.h" + +struct label { + char * text; + int length; + int cs; +}; + +static void labelDraw(newtComponent co); +static void labelDestroy(newtComponent co); + +static struct componentOps labelOps = { + labelDraw, + newtDefaultEventHandler, + labelDestroy, + newtDefaultPlaceHandler, + newtDefaultMappedHandler, +} ; + +newtComponent newtLabel(int left, int top, const char * text) { + newtComponent co; + struct label * la; + + co = malloc(sizeof(*co)); + la = malloc(sizeof(struct label)); + co->data = la; + co->destroyCallback = NULL; + + co->ops = &labelOps; + + co->height = 1; + co->width = wstrlen(text, -1); + co->top = top; + co->left = left; + co->takesFocus = 0; + co->isMapped = 0; + + la->length = strlen(text); + la->text = strdup(text); + la->cs = COLORSET_LABEL; + + return co; +} + +void newtLabelSetText(newtComponent co, const char * text) { + int newLength; + struct label * la = co->data; + + co->width = wstrlen(text,-1); + newLength = strlen(text); + if (newLength <= la->length) { + memset(la->text, ' ', la->length); + memcpy(la->text, text, newLength); + } else { + free(la->text); + la->text = strdup(text); + la->length = newLength; + } + + labelDraw(co); +} + +void newtLabelSetColors(newtComponent co, int colorset) { + struct label * la = co->data; + + la->cs = colorset; + labelDraw(co); +} + +static void labelDraw(newtComponent co) { + struct label * la = co->data; + + if (!co->isMapped) return; + + SLsmg_set_color(la->cs); + + newtGotorc(co->top, co->left); + SLsmg_write_string(la->text); +} + +static void labelDestroy(newtComponent co) { + struct label * la = co->data; + + free(la->text); + free(la); + free(co); +} diff --git a/libnewt.pc.in b/libnewt.pc.in new file mode 100644 index 0000000..89dc934 --- /dev/null +++ b/libnewt.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libnewt +Description: A development library for text mode user interfaces +Version: @VERSION@ +Libs: -L${libdir} -lnewt +Cflags: -I${includedir} diff --git a/listbox.c b/listbox.c new file mode 100644 index 0000000..6177c07 --- /dev/null +++ b/listbox.c @@ -0,0 +1,774 @@ +/* This goofed-up box whacked into shape by Elliot Lee + (from the original listbox by Erik Troan ) + and contributed to newt for use under the LGPL license. + Copyright (C) 1996, 1997 Elliot Lee */ + +#include +#include +#include +#include +#include + +#include "newt.h" +#include "newt_pr.h" + + +/* Linked list of items in the listbox */ +struct items { + char * text; + const void *data; + unsigned char isSelected; + struct items *next; +}; + +/* Holds all the relevant information for this listbox */ +struct listbox { + newtComponent sb; /* Scrollbar on right side of listbox */ + int curWidth; /* size of text w/o scrollbar or border*/ + int curHeight; /* size of text w/o border */ + int sbAdjust; + int bdxAdjust, bdyAdjust; + int numItems, numSelected; + int userHasSetWidth; + int currItem, startShowItem; /* startShowItem is the first item displayed + on the screen */ + int isActive; /* If we handle key events all the time, it seems + to do things even when they are supposed to be for + another button/whatever */ + struct items *boxItems; + int grow; + int flags; /* flags for this listbox, right now just + NEWT_FLAG_RETURNEXIT */ +}; + +static void listboxDraw(newtComponent co); +static void listboxDestroy(newtComponent co); +static struct eventResult listboxEvent(newtComponent co, struct event ev); +static void newtListboxRealSetCurrent(newtComponent co); +static void listboxPlace(newtComponent co, int newLeft, int newTop); +static inline void updateWidth(newtComponent co, struct listbox * li, + int maxField); +static void listboxMapped(newtComponent co, int isMapped); + +static struct componentOps listboxOps = { + listboxDraw, + listboxEvent, + listboxDestroy, + listboxPlace, + listboxMapped, +}; + +static void listboxMapped(newtComponent co, int isMapped) { + struct listbox * li = co->data; + + co->isMapped = isMapped; + if (li->sb) + li->sb->ops->mapped(li->sb, isMapped); +} + +static void listboxPlace(newtComponent co, int newLeft, int newTop) { + struct listbox * li = co->data; + + co->top = newTop; + co->left = newLeft; + + if (li->sb) + li->sb->ops->place(li->sb, co->left + co->width - li->bdxAdjust - 1, + co->top + li->bdyAdjust); +} + +newtComponent newtListbox(int left, int top, int height, int flags) { + newtComponent co, sb; + struct listbox * li; + + if (!(co = malloc(sizeof(*co)))) + return NULL; + + if (!(li = malloc(sizeof(struct listbox)))) { + free(co); + return NULL; + } + + li->boxItems = NULL; + li->numItems = 0; + li->currItem = 0; + li->numSelected = 0; + li->isActive = 0; + li->userHasSetWidth = 0; + li->startShowItem = 0; + li->sbAdjust = 0; + li->bdxAdjust = 0; + li->bdyAdjust = 0; + li->flags = flags & (NEWT_FLAG_RETURNEXIT | NEWT_FLAG_BORDER | + NEWT_FLAG_MULTIPLE | NEWT_FLAG_SHOWCURSOR); + + if (li->flags & NEWT_FLAG_BORDER) { + li->bdxAdjust = 2; + li->bdyAdjust = 1; + } + + co->height = height; + li->curHeight = co->height - (2 * li->bdyAdjust); + + if (height) { + li->grow = 0; + if (flags & NEWT_FLAG_SCROLL) { + sb = newtVerticalScrollbar(left, top + li->bdyAdjust, + li->curHeight, + COLORSET_LISTBOX, COLORSET_ACTLISTBOX); + li->sbAdjust = 3; + } else { + sb = NULL; + } + } else { + li->grow = 1; + sb = NULL; + } + + li->sb = sb; + co->data = li; + co->isMapped = 0; + co->left = left; + co->top = top; + co->ops = &listboxOps; + co->takesFocus = 1; + co->callback = NULL; + co->destroyCallback = NULL; + + updateWidth(co, li, 5); + + return co; +} + +static inline void updateWidth(newtComponent co, struct listbox * li, + int maxField) { + li->curWidth = maxField; + co->width = li->curWidth + li->sbAdjust + 2 * li->bdxAdjust; + + if (li->sb) + li->sb->left = co->left + co->width - li->bdxAdjust - 1; +} + +void newtListboxSetCurrentByKey(newtComponent co, void * key) { + struct listbox * li = co->data; + struct items * item; + int i; + + item = li->boxItems, i = 0; + while (item && item->data != key) + item = item->next, i++; + + if (item) + newtListboxSetCurrent(co, i); +} + +void newtListboxSetCurrent(newtComponent co, int num) +{ + struct listbox * li = co->data; + + if (num >= li->numItems) + li->currItem = li->numItems - 1; + else if (num < 0) + li->currItem = 0; + else + li->currItem = num; + + if (li->currItem < li->startShowItem) + li->startShowItem = li->currItem; + else if (li->currItem - li->startShowItem > li->curHeight - 1) + li->startShowItem = li->currItem - li->curHeight + 1; + if (li->startShowItem + li->curHeight > li->numItems) + li->startShowItem = li->numItems - li->curHeight; + if(li->startShowItem < 0) + li->startShowItem = 0; + + newtListboxRealSetCurrent(co); +} + +static void newtListboxRealSetCurrent(newtComponent co) +{ + struct listbox * li = co->data; + + if(li->sb) + newtScrollbarSet(li->sb, li->currItem + 1, li->numItems); + listboxDraw(co); + if(co->callback) co->callback(co, co->callbackData); +} + +void newtListboxSetWidth(newtComponent co, int width) { + struct listbox * li = co->data; + + co->width = width; + li->curWidth = co->width - li->sbAdjust - 2 * li->bdxAdjust; + li->userHasSetWidth = 1; + if (li->sb) + li->sb->left = co->left + co->width - li->bdxAdjust - 1; + listboxDraw(co); +} + +void * newtListboxGetCurrent(newtComponent co) { + struct listbox * li = co->data; + int i; + struct items *item; + + for(i = 0, item = li->boxItems; item != NULL && i < li->currItem; + i++, item = item->next); + + if (item) + return (void *)item->data; + else + return NULL; +} + +void newtListboxSelectItem(newtComponent co, const void * key, + enum newtFlagsSense sense) +{ + struct listbox * li = co->data; + int i; + struct items * item; + + item = li->boxItems, i = 0; + while (item && item->data != key) + item = item->next, i++; + + if (!item) return; + + if (item->isSelected) + li->numSelected--; + + switch(sense) { + case NEWT_FLAGS_RESET: + item->isSelected = 0; break; + case NEWT_FLAGS_SET: + item->isSelected = 1; break; + case NEWT_FLAGS_TOGGLE: + item->isSelected = !item->isSelected; + } + + if (item->isSelected) + li->numSelected++; + + listboxDraw(co); +} + +void newtListboxClearSelection(newtComponent co) +{ + struct items *item; + struct listbox * li = co->data; + + for(item = li->boxItems; item != NULL; + item = item->next) + item->isSelected = 0; + li->numSelected = 0; + listboxDraw(co); +} + +/* Free the returned array after use, but NOT the values in the array */ +void ** newtListboxGetSelection(newtComponent co, int *numitems) +{ + struct listbox * li; + int i; + void **retval; + struct items *item; + + if(!co || !numitems) return NULL; + + li = co->data; + if(!li || !li->numSelected) return NULL; + + retval = malloc(li->numSelected * sizeof(void *)); + for(i = 0, item = li->boxItems; item != NULL; + item = item->next) + if(item->isSelected) + retval[i++] = (void *)item->data; + *numitems = li->numSelected; + return retval; +} + +void newtListboxSetEntry(newtComponent co, int num, const char * text) { + struct listbox * li = co->data; + int i; + struct items *item; + + for(i = 0, item = li->boxItems; item != NULL && i < num; + i++, item = item->next); + + if(!item) + return; + else { + free(item->text); + item->text = strdup(text); + } + if (li->userHasSetWidth == 0 && wstrlen(text,-1) > li->curWidth) { + updateWidth(co, li, wstrlen(text,-1)); + } + + if (num >= li->startShowItem && num <= li->startShowItem + co->height) + listboxDraw(co); +} + +void newtListboxSetData(newtComponent co, int num, void * data) { + struct listbox * li = co->data; + int i; + struct items *item; + + for(i = 0, item = li->boxItems; item != NULL && i < num; + i++, item = item->next); + + if (item) + item->data = data; +} + +int newtListboxAppendEntry(newtComponent co, const char * text, + const void * data) { + struct listbox * li = co->data; + struct items *item; + + if(li->boxItems) { + for (item = li->boxItems; item->next != NULL; item = item->next); + + item = item->next = malloc(sizeof(struct items)); + } else { + item = li->boxItems = malloc(sizeof(struct items)); + } + + if (!li->userHasSetWidth && text && (wstrlen(text,-1) > li->curWidth)) + updateWidth(co, li, wstrlen(text,-1)); + + item->text = strdup(text); item->data = data; item->next = NULL; + item->isSelected = 0; + + if (li->grow) + co->height++, li->curHeight++; + li->numItems++; + + return 0; +} + +int newtListboxInsertEntry(newtComponent co, const char * text, + const void * data, void * key) { + struct listbox * li = co->data; + struct items *item, *t; + + if (li->boxItems) { + if (key) { + item = li->boxItems; + while (item && item->data != key) item = item->next; + + if (!item) return 1; + + t = item->next; + item = item->next = malloc(sizeof(struct items)); + item->next = t; + } else { + t = li->boxItems; + item = li->boxItems = malloc(sizeof(struct items)); + item->next = t; + } + } else if (key) { + return 1; + } else { + item = li->boxItems = malloc(sizeof(struct items)); + item->next = NULL; + } + + if (!li->userHasSetWidth && text && (wstrlen(text,-1) > li->curWidth)) + updateWidth(co, li, wstrlen(text,-1)); + + item->text = strdup(text?text:"(null)"); item->data = data; + item->isSelected = 0; + + if (li->sb) + li->sb->left = co->left + co->width - li->bdxAdjust - 1; + li->numItems++; + + listboxDraw(co); + + return 0; +} + +int newtListboxDeleteEntry(newtComponent co, void * key) { + struct listbox * li = co->data; + int widest = 0, t; + struct items *item, *item2 = NULL; + int num; + + if (li->boxItems == NULL || li->numItems <= 0) + return 0; + + num = 0; + + item2 = NULL, item = li->boxItems; + while (item && item->data != key) { + item2 = item; + item = item->next; + num++; + } + + if (!item) + return -1; + + if (item2) + item2->next = item->next; + else + li->boxItems = item->next; + + free(item->text); + free(item); + li->numItems--; + + if (!li->userHasSetWidth) { + widest = 0; + for (item = li->boxItems; item != NULL; item = item->next) + if ((t = wstrlen(item->text,-1)) > widest) widest = t; + } + + if (li->currItem >= num) + li->currItem--; + + if (!li->userHasSetWidth) { + updateWidth(co, li, widest); + } + + listboxDraw(co); + + return 0; +} + +void newtListboxClear(newtComponent co) +{ + struct listbox * li; + struct items *anitem, *nextitem; + if(co == NULL || (li = co->data) == NULL) + return; + for(anitem = li->boxItems; anitem != NULL; anitem = nextitem) { + nextitem = anitem->next; + free(anitem->text); + free(anitem); + } + li->numItems = li->numSelected = li->currItem = li->startShowItem = 0; + li->boxItems = NULL; + if (!li->userHasSetWidth) + updateWidth(co, li, 5); +} + +int newtListboxItemCount(newtComponent co) +{ + struct listbox *li = co->data; + return li->numItems; +} + +/* If you don't want to get back the text, pass in NULL for the ptr-ptr. Same + goes for the data. */ +void newtListboxGetEntry(newtComponent co, int num, char **text, void **data) { + struct listbox * li = co->data; + int i; + struct items *item; + + if (!li->boxItems || num >= li->numItems) { + if(text) + *text = NULL; + if(data) + *data = NULL; + return; + } + + i = 0; + item = li->boxItems; + while (item && i < num) { + i++, item = item->next; + } + + if (item) { + if (text) + *text = item->text; + if (data) + *data = (void *)item->data; + } +} + +static void listboxDraw(newtComponent co) +{ + struct listbox * li = co->data; + struct items *item; + int i, j; + + if (!co->isMapped) return ; + + newtTrashScreen(); + + if(li->flags & NEWT_FLAG_BORDER) { + if(li->isActive) + SLsmg_set_color(NEWT_COLORSET_ACTLISTBOX); + else + SLsmg_set_color(NEWT_COLORSET_LISTBOX); + + newtDrawBox(co->left, co->top, co->width, co->height, 0); + } + + if(li->sb) + li->sb->ops->draw(li->sb); + + SLsmg_set_color(NEWT_COLORSET_LISTBOX); + + for(i = 0, item = li->boxItems; item != NULL && i < li->startShowItem; + i++, item = item->next); + + j = i; + + for (i = 0; item != NULL && i < li->curHeight; i++, item = item->next) { + if (!item->text) continue; + + newtGotorc(co->top + i + li->bdyAdjust, co->left + li->bdxAdjust); + if(j + i == li->currItem) { + if(li->isActive) + SLsmg_set_color(NEWT_COLORSET_ACTSELLISTBOX); + else + SLsmg_set_color(NEWT_COLORSET_ACTLISTBOX); + } else if(item->isSelected) + SLsmg_set_color(NEWT_COLORSET_SELLISTBOX); + else + SLsmg_set_color(NEWT_COLORSET_LISTBOX); + + SLsmg_write_nstring(item->text, li->curWidth); + + if (li->flags & NEWT_FLAG_MULTIPLE) { + newtGotorc(co->top + i + li->bdyAdjust, co->left + li->bdxAdjust); + SLsmg_set_color(item->isSelected ? + NEWT_COLORSET_SELLISTBOX : NEWT_COLORSET_LISTBOX); + SLsmg_write_nstring(item->text, 1); + } + } + newtGotorc(co->top + (li->currItem - li->startShowItem) + li->bdyAdjust, + co->left + li->bdxAdjust); +} + +static struct eventResult listboxEvent(newtComponent co, struct event ev) { + struct eventResult er; + struct listbox * li = co->data; + struct items *item; + int i; + + er.result = ER_IGNORED; + + if(ev.when == EV_EARLY || ev.when == EV_LATE) { + return er; + } + + switch(ev.event) { + case EV_KEYPRESS: + if (!li->isActive) break; + + switch(ev.u.key) { + case ' ': + if(!(li->flags & NEWT_FLAG_MULTIPLE)) break; + newtListboxSelectItem(co, newtListboxGetCurrent(co), + NEWT_FLAGS_TOGGLE); + er.result = ER_SWALLOWED; + /* We don't break here, because it is cool to be able to + hold space to select a bunch of items in a list at once */ + + case NEWT_KEY_DOWN: + if(li->numItems <= 0) break; + if(li->currItem < li->numItems - 1) { + li->currItem++; + if(li->currItem > (li->startShowItem + li->curHeight - 1)) { + li->startShowItem = li->currItem - li->curHeight + 1; + if(li->startShowItem + li->curHeight > li->numItems) + li->startShowItem = li->numItems - li->curHeight; + } + if(li->sb) + newtScrollbarSet(li->sb, li->currItem + 1, li->numItems); + listboxDraw(co); + } + if(co->callback) co->callback(co, co->callbackData); + er.result = ER_SWALLOWED; + break; + + case NEWT_KEY_ENTER: + if(li->numItems <= 0) break; + if(li->flags & NEWT_FLAG_RETURNEXIT) + er.result = ER_EXITFORM; + break; + + case NEWT_KEY_UP: + if(li->numItems <= 0) break; + if(li->currItem > 0) { + li->currItem--; + if(li->currItem < li->startShowItem) + li->startShowItem = li->currItem; + if(li->sb) + newtScrollbarSet(li->sb, li->currItem + 1, li->numItems); + listboxDraw(co); + } + if(co->callback) co->callback(co, co->callbackData); + er.result = ER_SWALLOWED; + break; + + case NEWT_KEY_PGUP: + if(li->numItems <= 0) break; + li->startShowItem -= li->curHeight - 1; + if(li->startShowItem < 0) + li->startShowItem = 0; + li->currItem -= li->curHeight - 1; + if(li->currItem < 0) + li->currItem = 0; + newtListboxRealSetCurrent(co); + er.result = ER_SWALLOWED; + break; + + case NEWT_KEY_PGDN: + if(li->numItems <= 0) break; + li->startShowItem += li->curHeight; + if(li->startShowItem > (li->numItems - li->curHeight)) { + li->startShowItem = li->numItems - li->curHeight; + } + li->currItem += li->curHeight; + if(li->currItem >= li->numItems) { + li->currItem = li->numItems - 1; + } + newtListboxRealSetCurrent(co); + er.result = ER_SWALLOWED; + break; + + case NEWT_KEY_HOME: + if(li->numItems <= 0) break; + newtListboxSetCurrent(co, 0); + er.result = ER_SWALLOWED; + break; + + case NEWT_KEY_END: + if(li->numItems <= 0) break; + li->startShowItem = li->numItems - li->curHeight; + if(li->startShowItem < 0) + li->startShowItem = 0; + li->currItem = li->numItems - 1; + newtListboxRealSetCurrent(co); + er.result = ER_SWALLOWED; + break; + default: + if (li->numItems <= 0) break; + if (ev.u.key < NEWT_KEY_EXTRA_BASE && isalpha(ev.u.key)) { + for(i = 0, item = li->boxItems; item != NULL && + i < li->currItem; i++, item = item->next); + + if (item && item->text && (toupper(*item->text) == toupper(ev.u.key))) { + item = item->next; + i++; + } else { + item = li->boxItems; + i = 0; + } + while (item && item->text && + toupper(*item->text) != toupper(ev.u.key)) { + item = item->next; + i++; + } + if (item) { + li->currItem = i; + if(li->currItem < li->startShowItem || + li->currItem > li->startShowItem) + li->startShowItem = + li->currItem > li->numItems - li->curHeight ? + li->numItems - li->curHeight : + li->currItem; + if(li->sb) + newtScrollbarSet(li->sb, li->currItem + 1, li->numItems); + newtListboxRealSetCurrent(co); + er.result = ER_SWALLOWED; + } + } + } + break; + + case EV_FOCUS: + li->isActive = 1; + listboxDraw(co); + if(li->flags & NEWT_FLAG_SHOWCURSOR) + newtCursorOn(); + er.result = ER_SWALLOWED; + break; + + case EV_UNFOCUS: + li->isActive = 0; + listboxDraw(co); + if(li->flags & NEWT_FLAG_SHOWCURSOR) + newtCursorOff(); + er.result = ER_SWALLOWED; + break; + + case EV_MOUSE: + /* if this mouse click was within the listbox, make the current + item the item clicked on. */ + /* Up scroll arrow */ + if (li->sb && + ev.u.mouse.x == co->left + co->width - li->bdxAdjust - 1 && + ev.u.mouse.y == co->top + li->bdyAdjust) { + if(li->numItems <= 0) break; + if(li->currItem > 0) { + li->currItem--; + if(li->currItem < li->startShowItem) + li->startShowItem = li->currItem; + if(li->sb) + newtScrollbarSet(li->sb, li->currItem + 1, li->numItems); + listboxDraw(co); + } + if(co->callback) co->callback(co, co->callbackData); + er.result = ER_SWALLOWED; + break; + } + /* Down scroll arrow */ + if (li->sb && + ev.u.mouse.x == co->left + co->width - li->bdxAdjust - 1 && + ev.u.mouse.y == co->top + co->height - li->bdyAdjust - 1) { + if(li->numItems <= 0) break; + if(li->currItem < li->numItems - 1) { + li->currItem++; + if(li->currItem > (li->startShowItem + li->curHeight - 1)) { + li->startShowItem = li->currItem - li->curHeight + 1; + if(li->startShowItem + li->curHeight > li->numItems) + li->startShowItem = li->numItems - li->curHeight; + } + if(li->sb) + newtScrollbarSet(li->sb, li->currItem + 1, li->numItems); + listboxDraw(co); + } + if(co->callback) co->callback(co, co->callbackData); + er.result = ER_SWALLOWED; + break; + } + if ((ev.u.mouse.y >= co->top + li->bdyAdjust) && + (ev.u.mouse.y <= co->top + co->height - (li->bdyAdjust * 2)) && + (ev.u.mouse.x >= co->left + li->bdxAdjust) && + (ev.u.mouse.x <= co->left + co->width + (li->bdxAdjust * 2))) { + li->currItem = li->startShowItem + + (ev.u.mouse.y - li->bdyAdjust - co->top); + newtListboxRealSetCurrent(co); + listboxDraw(co); + if(co->callback) co->callback(co, co->callbackData); + er.result = ER_SWALLOWED; + break; + } + } + + return er; +} + +static void listboxDestroy(newtComponent co) { + struct listbox * li = co->data; + struct items * item, * nextitem; + + nextitem = item = li->boxItems; + + while (item != NULL) { + nextitem = item->next; + free(item->text); + free(item); + item = nextitem; + } + + if (li->sb) li->sb->ops->destroy(li->sb); + + free(li); + free(co); +} diff --git a/newt.0.52.ver b/newt.0.52.ver new file mode 100644 index 0000000..5bbb22e --- /dev/null +++ b/newt.0.52.ver @@ -0,0 +1,177 @@ +NEWT_0.52 { + /* remove private functions with next soname change */ + global: + newtBell; + newtButton; + newtButtonBar; + newtButtonBarv; + newtCenteredWindow; + newtCheckbox; + newtCheckboxGetValue; + newtCheckboxSetFlags; + newtCheckboxSetValue; + newtCheckboxTree; + newtCheckboxTreeAddArray; + newtCheckboxTreeAddItem; + newtCheckboxTreeFindItem; + newtCheckboxTreeGetCurrent; + newtCheckboxTreeGetEntryValue; + newtCheckboxTreeGetMultiSelection; + newtCheckboxTreeGetSelection; + newtCheckboxTreeMulti; + newtCheckboxTreeSetCurrent; + newtCheckboxTreeSetEntry; + newtCheckboxTreeSetEntryValue; + newtCheckboxTreeSetWidth; + newtClearBox; + newtClearKeyBuffer; + newtCls; + newtCompactButton; + newtComponentAddCallback; + newtComponentTakesFocus; + newtCreateGrid; + newtCursorOff; + newtCursorOn; + newtDefaultColorPalette; + newtDefaultEventHandler; + newtDefaultMappedHandler; + newtDefaultPlaceHandler; + newtDelay; + newtDrawBox; + newtDrawForm; + newtDrawRootText; + newtEntry; + newtEntryGetValue; + newtEntrySet; + newtEntrySetFilter; + newtEntrySetFlags; + newtFinished; + newtFlushInput; + newtForm; + newtFormAddComponent; + newtFormAddComponents; + newtFormAddHotKey; + newtFormDestroy; + newtFormGetCurrent; + newtFormRun; + newtFormSetBackground; + newtFormSetCurrent; + newtFormSetHeight; + newtFormSetSize; + newtFormSetTimer; + newtFormSetWidth; + newtFormWatchFd; + newtGetKey; + newtGetScreenSize; + newtGetWindowPos; + newtGetrc; + newtGotorc; + newtGridAddComponentsToForm; + newtGridBasicWindow; + newtGridFree; + newtGridGetSize; + newtGridHCloseStacked; + newtGridHStacked; + newtGridPlace; + newtGridSetField; + newtGridSimpleWindow; + newtGridVCloseStacked; + newtGridVStacked; + newtGridWrappedWindow; + newtGridWrappedWindowAt; + newtInit; + newtLabel; + newtLabelSetText; + newtListbox; + newtListboxAppendEntry; + newtListboxClear; + newtListboxClearSelection; + newtListboxDeleteEntry; + newtListboxGetCurrent; + newtListboxGetEntry; + newtListboxGetSelection; + newtListboxInsertEntry; + newtListboxItemCount; + newtListboxSelectItem; + newtListboxSetCurrent; + newtListboxSetCurrentByKey; + newtListboxSetData; + newtListboxSetEntry; + newtListboxSetWidth; + newtOpenWindow; + newtPopHelpLine; + newtPopWindow; + newtPushHelpLine; + newtRadioGetCurrent; + newtRadiobutton; + newtRedrawHelpLine; + newtReflowText; + newtRefresh; + newtResizeScreen; + newtResume; + newtRunForm; + newtScale; + newtScaleSet; + newtScrollbarSet; + newtSetColors; + newtSetFlags; + newtSetHelpCallback; + newtSetSuspendCallback; + newtSuspend; + newtTextbox; + newtTextboxGetNumLines; + newtTextboxReflowed; + newtTextboxSetHeight; + newtTextboxSetText; + newtTrashScreen; + newtVerticalScrollbar; + newtWaitForKey; + newtWinChoice; + newtWinEntries; + newtWinMenu; + newtWinMessage; + newtWinMessagev; + newtWinTernary; + _newt_wstrlen; + local: *; +}; + +NEWT_0.52.6 { + global: + newtSetColor; + newtPopWindowNoRefresh; +} NEWT_0.52; + +NEWT_0.52.9 { + global: + newtComponentAddDestroyCallback; + newtComponentDestroy; +} NEWT_0.52.6; + +NEWT_0.52.11 { + global: + newtRadioSetCurrent; +} NEWT_0.52.9; + +NEWT_0.52.13 { + global: + newtEntrySetColors; + newtLabelSetColors; + newtScaleSetColors; + newtScrollbarSetColors; + newtTextboxSetColors; +} NEWT_0.52.11; + +NEWT_0.52.16 { + global: + newtComponentGetPosition; + newtComponentGetSize; +} NEWT_0.52.13; + +NEWT_0.52.17 { + global: + newtFormGetScrollPosition; + newtFormSetScrollPosition; + newtEntryGetCursorPosition; + newtEntrySetCursorPosition; +} NEWT_0.52.16; diff --git a/newt.c b/newt.c new file mode 100644 index 0000000..1a913a0 --- /dev/null +++ b/newt.c @@ -0,0 +1,1172 @@ +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_ALLOCA_H +#include +#endif + +#include "newt.h" +#include "newt_pr.h" + +struct Window { + int height, width, top, left; + SLsmg_Char_Type * buffer; + char * title; +}; + +struct keymap { + char * str; + int code; + char * tc; +}; + +static struct Window windowStack[20]; +static struct Window * currentWindow = NULL; + +static char * helplineStack[20]; +static char ** currentHelpline = NULL; + +static int cursorRow, cursorCol; +static int cursorOn = 1; +static int trashScreen = 0; +extern int needResize; + +static const char * const defaultHelpLine = +" / between elements | selects | next screen" +; + +const struct newtColors newtDefaultColorPalette = { + "white", "blue", /* root fg, bg */ + "black", "lightgray", /* border fg, bg */ + "black", "lightgray", /* window fg, bg */ + "white", "black", /* shadow fg, bg */ + "red", "lightgray", /* title fg, bg */ + "lightgray", "red", /* button fg, bg */ + "red", "lightgray", /* active button fg, bg */ + "lightgray", "blue", /* checkbox fg, bg */ + "lightgray", "red", /* active checkbox fg, bg */ + "lightgray", "blue", /* entry box fg, bg */ + "blue", "lightgray", /* label fg, bg */ + "black", "lightgray", /* listbox fg, bg */ + "lightgray", "blue", /* active listbox fg, bg */ + "black", "lightgray", /* textbox fg, bg */ + "lightgray", "red", /* active textbox fg, bg */ + "white", "blue", /* help line */ + "lightgray", "blue", /* root text */ + "blue", /* scale full */ + "red", /* scale empty */ + "blue", "lightgray", /* disabled entry fg, bg */ + "black", "lightgray", /* compact button fg, bg */ + "lightgray", "red", /* active & sel listbox */ + "black", "brown" /* selected listbox */ +}; + +static const struct keymap keymap[] = { + { "\033OA", NEWT_KEY_UP, "ku" }, + { "\020", NEWT_KEY_UP, NULL }, /* emacs ^P */ + { "\033OB", NEWT_KEY_DOWN, "kd" }, + { "\016", NEWT_KEY_DOWN, NULL }, /* emacs ^N */ + { "\033OC", NEWT_KEY_RIGHT, "kr" }, + { "\006", NEWT_KEY_RIGHT, NULL }, /* emacs ^F */ + { "\033OD", NEWT_KEY_LEFT, "kl" }, + { "\002", NEWT_KEY_LEFT, NULL }, /* emacs ^B */ + { "\033OH", NEWT_KEY_HOME, "kh" }, + { "\033[1~", NEWT_KEY_HOME, NULL }, + { "\001", NEWT_KEY_HOME, NULL }, /* emacs ^A */ + { "\033Ow", NEWT_KEY_END, "kH" }, + { "\033[4~", NEWT_KEY_END, "@7" }, + { "\005", NEWT_KEY_END, NULL }, /* emacs ^E */ + + { "\033[3~", NEWT_KEY_DELETE, "kD" }, + { "\004", NEWT_KEY_DELETE, NULL }, /* emacs ^D */ + { "\033[2~", NEWT_KEY_INSERT, "kI" }, + + { "\033\t", NEWT_KEY_UNTAB, "kB" }, + { "\033[Z", NEWT_KEY_UNTAB, NULL }, + + { "\033[5~", NEWT_KEY_PGUP, "kP" }, + { "\033[6~", NEWT_KEY_PGDN, "kN" }, + { "\033V", NEWT_KEY_PGUP, NULL }, + { "\033v", NEWT_KEY_PGUP, NULL }, + { "\026", NEWT_KEY_PGDN, NULL }, + + { "\033[[A", NEWT_KEY_F1, NULL }, + { "\033[[B", NEWT_KEY_F2, NULL }, + { "\033[[C", NEWT_KEY_F3, NULL }, + { "\033[[D", NEWT_KEY_F4, NULL }, + { "\033[[E", NEWT_KEY_F5, NULL }, + + { "\033OP", NEWT_KEY_F1, NULL }, + { "\033OQ", NEWT_KEY_F2, NULL }, + { "\033OR", NEWT_KEY_F3, NULL }, + { "\033OS", NEWT_KEY_F4, NULL }, + + { "\033[11~", NEWT_KEY_F1, "k1" }, + { "\033[12~", NEWT_KEY_F2, "k2" }, + { "\033[13~", NEWT_KEY_F3, "k3" }, + { "\033[14~", NEWT_KEY_F4, "k4" }, + { "\033[15~", NEWT_KEY_F5, "k5" }, + { "\033[17~", NEWT_KEY_F6, "k6" }, + { "\033[18~", NEWT_KEY_F7, "k7" }, + { "\033[19~", NEWT_KEY_F8, "k8" }, + { "\033[20~", NEWT_KEY_F9, "k9" }, + { "\033[21~", NEWT_KEY_F10, "k;" }, + { "\033[23~", NEWT_KEY_F11, "F1" }, + { "\033[24~", NEWT_KEY_F12, "F2" }, + { "\033", NEWT_KEY_ESCAPE, "@2" }, + { "\033", NEWT_KEY_ESCAPE, "@9" }, + + { "\177", NEWT_KEY_BKSPC, NULL }, + { "\010", NEWT_KEY_BKSPC, NULL }, + + { 0 }, /* LEAVE this one */ +}; +static void initKeymap(); +static void freeKeymap(); + +static const char ident[] = // ident friendly + "$Version: Newt windowing library v" VERSION " $" + "$Copyright: (C) 1996-2003 Red Hat, Inc. Written by Erik Troan $" + "$License: Lesser GNU Public License. $"; + +static newtSuspendCallback suspendCallback = NULL; +static void * suspendCallbackData = NULL; + +void newtSetSuspendCallback(newtSuspendCallback cb, void * data) { + suspendCallback = cb; + suspendCallbackData = data; +} + +static void handleSigwinch(int signum) { + needResize = 1; +} + +static int getkeyInterruptHook(void) { + return -1; +} + +int _newt_wstrlen(const char *str, int len) { + mbstate_t ps; + wchar_t tmp; + int nchars = 0; + + if (!str) return 0; + if (!len) return 0; + if (len < 0) len = strlen(str); + memset(&ps,0,sizeof(mbstate_t)); + while (len > 0) { + int x,y; + + x = mbrtowc(&tmp,str,len,&ps); + if (x >0) { + str += x; + len -= x; + y = wcwidth(tmp); + if (y>0) + nchars+=y; + } else break; + } + return nchars; +} + +/** Trim a string to fit + * @param title - string. NULL will be inserted if necessary + * @param chrs - available space. (character cells) + */ +void trim_string(char *title, int chrs) +{ + char *p = title; + int ln; + int x = 0,y = 0; + wchar_t tmp; + mbstate_t ps; + + memset(&ps, 0, sizeof(ps)); + ln = strlen(title); + + while (*p) { + x = mbrtowc(&tmp, p, ln, &ps); + if (x < 0) { // error + *p = '\0'; + return; + } + y = wcwidth(tmp); + if (y > chrs) { + *p = '\0'; + return; + } else { + p += x; + ln -= x; + chrs -= y; + } + } +} + +static int getkey() { + int c; + + while ((c = SLang_getkey()) == '\xC') { /* if Ctrl-L redraw whole screen */ + SLsmg_touch_lines(0, SLtt_Screen_Rows); + SLsmg_refresh(); + } + return c; + +} + +static void updateColorset(char *fg, char *bg, char **fg_p, char **bg_p) +{ + if (*fg && fg_p) + *fg_p = fg; + if (*bg && bg_p) + *bg_p = bg; +} + +/* parse color specifications (e.g. root=,black:border=red,blue) + * and update the palette + */ +static void parseColors(char *s, struct newtColors *palette) +{ + char *name, *str, *fg, *bg; + + for (str = s; (s = strtok(str, ";:\n\r\t ")); str = NULL) { + name = s; + if (!(s = strchr(s, '=')) || !*s) + continue; + *s = '\0'; + fg = ++s; + if (!(s = strchr(s, ',')) || !*s) + continue; + *s = '\0'; + bg = ++s; + + if (!strcmp(name, "root")) + updateColorset(fg, bg, &palette->rootFg, &palette->rootBg); + else if (!strcmp(name, "border")) + updateColorset(fg, bg, &palette->borderFg, &palette->borderBg); + else if (!strcmp(name, "window")) + updateColorset(fg, bg, &palette->windowFg, &palette->windowBg); + else if (!strcmp(name, "shadow")) + updateColorset(fg, bg, &palette->shadowFg, &palette->shadowBg); + else if (!strcmp(name, "title")) + updateColorset(fg, bg, &palette->titleFg, &palette->titleBg); + else if (!strcmp(name, "button")) + updateColorset(fg, bg, &palette->buttonFg, &palette->buttonBg); + else if (!strcmp(name, "actbutton")) + updateColorset(fg, bg, &palette->actButtonFg, &palette->actButtonBg); + else if (!strcmp(name, "checkbox")) + updateColorset(fg, bg, &palette->checkboxFg, &palette->checkboxBg); + else if (!strcmp(name, "actcheckbox")) + updateColorset(fg, bg, &palette->actCheckboxFg, &palette->actCheckboxBg); + else if (!strcmp(name, "entry")) + updateColorset(fg, bg, &palette->entryFg, &palette->entryBg); + else if (!strcmp(name, "label")) + updateColorset(fg, bg, &palette->labelFg, &palette->labelBg); + else if (!strcmp(name, "listbox")) + updateColorset(fg, bg, &palette->listboxFg, &palette->listboxBg); + else if (!strcmp(name, "actlistbox")) + updateColorset(fg, bg, &palette->actListboxFg, &palette->actListboxBg); + else if (!strcmp(name, "textbox")) + updateColorset(fg, bg, &palette->textboxFg, &palette->textboxBg); + else if (!strcmp(name, "acttextbox")) + updateColorset(fg, bg, &palette->actTextboxFg, &palette->actTextboxBg); + else if (!strcmp(name, "helpline")) + updateColorset(fg, bg, &palette->helpLineFg, &palette->helpLineBg); + else if (!strcmp(name, "roottext")) + updateColorset(fg, bg, &palette->rootTextFg, &palette->rootTextBg); + else if (!strcmp(name, "emptyscale")) + updateColorset(fg, bg, NULL, &palette->emptyScale); + else if (!strcmp(name, "fullscale")) + updateColorset(fg, bg, NULL, &palette->fullScale); + else if (!strcmp(name, "disentry")) + updateColorset(fg, bg, &palette->disabledEntryFg, &palette->disabledEntryBg); + else if (!strcmp(name, "compactbutton")) + updateColorset(fg, bg, &palette->compactButtonFg, &palette->compactButtonBg); + else if (!strcmp(name, "actsellistbox")) + updateColorset(fg, bg, &palette->actSelListboxFg, &palette->actSelListboxBg); + else if (!strcmp(name, "sellistbox")) + updateColorset(fg, bg, &palette->selListboxFg, &palette->selListboxBg); + } +} + +static void initColors(void) +{ + char *colors, *colors_file, buf[16384]; + FILE *f; + struct newtColors palette; + + palette = newtDefaultColorPalette; + + colors_file = getenv("NEWT_COLORS_FILE"); +#ifdef NEWT_COLORS_FILE + if (colors_file == NULL) + colors_file = NEWT_COLORS_FILE; +#endif + + if ((colors = getenv("NEWT_COLORS"))) { + strncpy(buf, colors, sizeof (buf)); + buf[sizeof (buf) - 1] = '\0'; + parseColors(buf, &palette); + } else if (colors_file && *colors_file && (f = fopen(colors_file, "r"))) { + size_t r; + if ((r = fread(buf, 1, sizeof (buf) - 1, f)) > 0) { + buf[r] = '\0'; + parseColors(buf, &palette); + } + fclose(f); + } + + newtSetColors(palette); +} + +void newtFlushInput(void) { + while (SLang_input_pending(0)) { + getkey(); + } +} + +/** + * @brief Refresh the screen + */ +void newtRefresh(void) { + SLsmg_refresh(); +} + +void newtSuspend(void) { + SLtt_set_cursor_visibility (1); + SLsmg_suspend_smg(); + SLang_reset_tty(); + SLtt_set_cursor_visibility (cursorOn); +} + +/** + * @brief Return after suspension. + * @return 0 on success. + */ +int newtResume(void) { + SLsmg_resume_smg (); + SLsmg_refresh(); + return SLang_init_tty(0, 0, 0); +} + +void newtCls(void) { + SLsmg_set_color(NEWT_COLORSET_ROOT); + SLsmg_gotorc(0, 0); + SLsmg_erase_eos(); + + newtRefresh(); +} + +/** + * @brief Resize the screen + * @param redraw - boolean - should we redraw the screen? + */ +void newtResizeScreen(int redraw) { + /* we can't redraw from scratch, just redisplay SLang screen */ + SLtt_get_screen_size(); + /* SLsmg_reinit_smg(); */ + if (redraw) { + SLsmg_touch_lines(0, SLtt_Screen_Rows); + newtRefresh(); + } +} + +/** + * @brief Initialize the newt library + * @return int - 0 for success, else < 0 + */ +int newtInit(void) { + char * MonoValue, * MonoEnv = "NEWT_MONO"; + const char *lang; + int ret; + + if ((lang = getenv("LC_ALL")) == NULL) + if ((lang = getenv("LC_CTYPE")) == NULL) + if ((lang = getenv("LANG")) == NULL) + lang = ""; + /* slang doesn't support multibyte encodings except UTF-8, + avoid character corruption by redrawing the screen */ + if (strstr (lang, ".euc") != NULL) + trashScreen = 1; + + (void) strlen(ident); + + SLutf8_enable(-1); + SLtt_get_terminfo(); + SLtt_get_screen_size(); + + MonoValue = getenv(MonoEnv); + if ( MonoValue != NULL ) + SLtt_Use_Ansi_Colors = 0; + + if ((ret = SLsmg_init_smg()) < 0) + return ret; + if ((ret = SLang_init_tty(0, 0, 0)) < 0) + return ret; + + initColors(); + newtCursorOff(); + initKeymap(); + + SLsignal_intr(SIGWINCH, handleSigwinch); + SLang_getkey_intr_hook = getkeyInterruptHook; + + return 0; +} + +/** + * @brief Closedown the newt library, tidying screen. + * @returns int , 0. (no errors reported) + */ +int newtFinished(void) { + if (currentWindow) { + for (; currentWindow >= windowStack; currentWindow--) { + free(currentWindow->buffer); + free(currentWindow->title); + } + currentWindow = NULL; + } + + if (currentHelpline) { + for (; currentHelpline >= helplineStack; currentHelpline--) + free(*currentHelpline); + currentHelpline = NULL; + } + + freeKeymap(); + + SLsmg_gotorc(SLtt_Screen_Rows - 1, 0); + newtCursorOn(); + SLsmg_refresh(); + SLsmg_reset_smg(); + SLang_reset_tty(); + + return 0; +} + +/** + * @brief Set the colors used. + * @param colors - newtColor struct used. + */ +void newtSetColors(struct newtColors colors) { + if (!SLtt_Use_Ansi_Colors) { + int i; + + for (i = 2; i < 25; i++) + SLtt_set_mono(i, NULL, 0); + + SLtt_set_mono(NEWT_COLORSET_SELLISTBOX, NULL, SLTT_BOLD_MASK); + + SLtt_set_mono(NEWT_COLORSET_ACTBUTTON, NULL, SLTT_REV_MASK); + SLtt_set_mono(NEWT_COLORSET_ACTCHECKBOX, NULL, SLTT_REV_MASK); + SLtt_set_mono(NEWT_COLORSET_ACTLISTBOX, NULL, SLTT_REV_MASK); + SLtt_set_mono(NEWT_COLORSET_ACTTEXTBOX, NULL, SLTT_REV_MASK); + + SLtt_set_mono(NEWT_COLORSET_ACTSELLISTBOX, NULL, SLTT_REV_MASK | SLTT_BOLD_MASK); + + SLtt_set_mono(NEWT_COLORSET_DISENTRY, NULL, 0); // FIXME + SLtt_set_mono(NEWT_COLORSET_FULLSCALE, NULL, SLTT_ULINE_MASK | SLTT_REV_MASK); + SLtt_set_mono(NEWT_COLORSET_EMPTYSCALE, NULL, SLTT_ULINE_MASK); + return; + } + SLtt_set_color(NEWT_COLORSET_ROOT, "", colors.rootFg, colors.rootBg); + SLtt_set_color(NEWT_COLORSET_BORDER, "", colors.borderFg, colors.borderBg); + SLtt_set_color(NEWT_COLORSET_WINDOW, "", colors.windowFg, colors.windowBg); + SLtt_set_color(NEWT_COLORSET_SHADOW, "", colors.shadowFg, colors.shadowBg); + SLtt_set_color(NEWT_COLORSET_TITLE, "", colors.titleFg, colors.titleBg); + SLtt_set_color(NEWT_COLORSET_BUTTON, "", colors.buttonFg, colors.buttonBg); + SLtt_set_color(NEWT_COLORSET_ACTBUTTON, "", colors.actButtonFg, + colors.actButtonBg); + SLtt_set_color(NEWT_COLORSET_CHECKBOX, "", colors.checkboxFg, + colors.checkboxBg); + SLtt_set_color(NEWT_COLORSET_ACTCHECKBOX, "", colors.actCheckboxFg, + colors.actCheckboxBg); + SLtt_set_color(NEWT_COLORSET_ENTRY, "", colors.entryFg, colors.entryBg); + SLtt_set_color(NEWT_COLORSET_LABEL, "", colors.labelFg, colors.labelBg); + SLtt_set_color(NEWT_COLORSET_LISTBOX, "", colors.listboxFg, + colors.listboxBg); + SLtt_set_color(NEWT_COLORSET_ACTLISTBOX, "", colors.actListboxFg, + colors.actListboxBg); + SLtt_set_color(NEWT_COLORSET_TEXTBOX, "", colors.textboxFg, + colors.textboxBg); + SLtt_set_color(NEWT_COLORSET_ACTTEXTBOX, "", colors.actTextboxFg, + colors.actTextboxBg); + SLtt_set_color(NEWT_COLORSET_HELPLINE, "", colors.helpLineFg, + colors.helpLineBg); + SLtt_set_color(NEWT_COLORSET_ROOTTEXT, "", colors.rootTextFg, + colors.rootTextBg); + + SLtt_set_color(NEWT_COLORSET_EMPTYSCALE, "", "white", + colors.emptyScale); + SLtt_set_color(NEWT_COLORSET_FULLSCALE, "", "white", + colors.fullScale); + SLtt_set_color(NEWT_COLORSET_DISENTRY, "", colors.disabledEntryFg, + colors.disabledEntryBg); + + SLtt_set_color(NEWT_COLORSET_COMPACTBUTTON, "", colors.compactButtonFg, + colors.compactButtonBg); + + SLtt_set_color(NEWT_COLORSET_ACTSELLISTBOX, "", colors.actSelListboxFg, + colors.actSelListboxBg); + SLtt_set_color(NEWT_COLORSET_SELLISTBOX, "", colors.selListboxFg, + colors.selListboxBg); +} + +void newtSetColor(int colorset, char *fg, char *bg) { + if (colorset < NEWT_COLORSET_ROOT || + (colorset > NEWT_COLORSET_SELLISTBOX && colorset < NEWT_COLORSET_CUSTOM(0)) || + !SLtt_Use_Ansi_Colors) + return; + + SLtt_set_color(colorset, "", fg, bg); +} + +/* Keymap handling - rewritten by Henning Makholm , + * November 2003. + */ + +struct kmap_trie_entry { + char alloced; /* alloced/not first element in array */ + char c ; /* character got from terminal */ + int code; /* newt key, or 0 if c does not make a complete sequence */ + struct kmap_trie_entry *contseq; /* sub-trie for character following c */ + struct kmap_trie_entry *next; /* try this if char received != c */ +}; + +static struct kmap_trie_entry *kmap_trie_root = NULL; +static int keyreader_buf_len = 10 ; +static unsigned char default_keyreader_buf[10]; +static unsigned char *keyreader_buf = default_keyreader_buf; + +#if 0 /* for testing of the keymap manipulation code */ +static void dumpkeys_recursive(struct kmap_trie_entry *curr, int i, FILE *f) { + int j, ps ; + char seen[256]={0}; + if( curr && i >= keyreader_buf_len ) { + fprintf(f,"ARGH! Too long sequence!\n") ; + return ; + } + for(;curr;curr=curr->next) { + keyreader_buf[i] = curr->c ; + ps = seen[(unsigned char)curr->c]++ ; + if( ps || curr->code || (!curr->code && !curr->contseq) ) { + for(j=0;j<=i;j++) { + if( keyreader_buf[j] > 32 && keyreader_buf[j]<127 && + keyreader_buf[j] != '^' && keyreader_buf[j] != '\\' ) + fprintf(f,"%c",keyreader_buf[j]); + else if( keyreader_buf[j] > 0 && keyreader_buf[j]<=32 ) + fprintf(f,"^%c",keyreader_buf[j] + 0x40); + else + fprintf(f,"\\%03o", + (unsigned)(unsigned char)keyreader_buf[j]); + } + if( curr->code ) + fprintf(f,": 0x%X\n",curr->code); + else + fprintf(f,": (just keymap)\n"); + } + dumpkeys_recursive(curr->contseq,i+1,f); + } +} +static void dump_keymap(void) { + FILE *f = fopen("newt.keydump","wt"); + if (f) { + dumpkeys_recursive(kmap_trie_root, 0, f); + fclose(f); + } +} +#endif + +/* newtBindKey may overwrite a binding that is there already */ +static void newtBindKey(char *keyseq, int meaning) { + struct kmap_trie_entry *root = kmap_trie_root ; + struct kmap_trie_entry **curptr = &root ; + + /* Try to make sure the common matching buffer is long enough. */ + if( strlen(keyseq) > keyreader_buf_len ) { + int i = strlen(keyseq)+10; + unsigned char *newbuf = malloc(i); + if (newbuf) { + if (keyreader_buf != default_keyreader_buf) + free(keyreader_buf); + keyreader_buf = newbuf; + keyreader_buf_len = i; + } + } + + if (*keyseq == 0) return; /* binding the empty sequence is meaningless */ + + while(1) { + while ((*curptr) && (*curptr)->c != *keyseq) + curptr = &(*curptr)->next; + if ((*curptr)==0) { + struct kmap_trie_entry* fresh + = calloc(strlen(keyseq),sizeof(struct kmap_trie_entry)); + if (fresh == 0) return; /* despair! */ + fresh->alloced = 1; + *curptr = fresh; + while (keyseq[1]) { + fresh->contseq = fresh+1; + (fresh++)->c = *(keyseq++); + } + fresh->c = *keyseq; + fresh->code = meaning; + return; + } + if (keyseq[1]==0) { + (*curptr)->code = meaning; + return; + } else { + curptr = &(*curptr)->contseq; + keyseq++; + } + } +} + +/* This function recursively inserts all entries in the "to" trie into + corresponding positions in the "from" trie, except positions that + are already defined in the "from" trie. */ +static void kmap_trie_fallback(struct kmap_trie_entry *to, + struct kmap_trie_entry **from) { + if (*from == NULL) + *from = to ; + if (*from == to) + return ; + for (;to!=NULL;to=to->next) { + struct kmap_trie_entry **fromcopy = from ; + while ((*fromcopy) && (*fromcopy)->c != to->c) + fromcopy = &(*fromcopy)->next ; + if (*fromcopy) { + if ((*fromcopy)->code == 0) + (*fromcopy)->code = to->code; + kmap_trie_fallback(to->contseq, &(*fromcopy)->contseq); + } else { + *fromcopy = malloc(sizeof(struct kmap_trie_entry)); + if (*fromcopy) { + **fromcopy = *to ; + (*fromcopy)->alloced = 1; + (*fromcopy)->next = 0 ; + } + } + } +} + +int newtGetKey(void) { + int key, lastcode, errors = 0; + unsigned char *chptr = keyreader_buf, *lastmatch; + struct kmap_trie_entry *curr = kmap_trie_root; + + do { + key = getkey(); + if (key == SLANG_GETKEY_ERROR) { + if (needResize) { + needResize = 0; + return NEWT_KEY_RESIZE; + } + + /* Ignore other signals, but assume that stdin disappeared (the + * parent terminal was proably closed) if the error persists. + */ + if (errors++ > 10) + return NEWT_KEY_ERROR; + + continue; + } + + if (key == NEWT_KEY_SUSPEND && suspendCallback) + suspendCallback(suspendCallbackData); + } while (key == NEWT_KEY_SUSPEND || key == SLANG_GETKEY_ERROR); + + /* Read more characters, matching against the trie as we go */ + lastcode = *chptr = key; + lastmatch = chptr ; + while(1) { + while (curr->c != key) { + curr = curr->next ; + if (curr==NULL) goto break2levels; + } + if (curr->code) { + lastcode = curr->code; + lastmatch = chptr; + } + curr = curr->contseq; + if (curr==NULL) break; + + if (SLang_input_pending(5) <= 0) + break; + + if (chptr==keyreader_buf+keyreader_buf_len-1) break; + *++chptr = key = getkey(); + } + break2levels: + + /* The last time the trie matched was at position lastmatch. Back + * up if we have read too many characters. */ + while (chptr > lastmatch) + SLang_ungetkey(*chptr--); + + return lastcode; +} + +/** + * @brief Wait for a keystroke + */ +void newtWaitForKey(void) { + newtRefresh(); + + getkey(); + newtClearKeyBuffer(); +} + +/** + * @brief Clear the keybuffer + */ +void newtClearKeyBuffer(void) { + while (SLang_input_pending(1)) { + getkey(); + } +} + +/** + * Open a new window. + * @param left. int Size; _not_ including border + * @param top: int size, _not_ including border + * @param width unsigned int + * @param height unsigned int + * @param title - title string + * @return zero on success + */ +int newtOpenWindow(int left, int top, + unsigned int width, unsigned int height, + const char * title) { + int j, row, col; + int n; + int i; + + newtFlushInput(); + + if (currentWindow && currentWindow - windowStack + 1 + >= sizeof (windowStack) / sizeof (struct Window)) + return 1; + + if (!currentWindow) { + currentWindow = windowStack; + } else { + currentWindow++; + } + + currentWindow->left = left; + currentWindow->top = top; + currentWindow->width = width; + currentWindow->height = height; + currentWindow->title = title ? strdup(title) : NULL; + + currentWindow->buffer = malloc(sizeof(SLsmg_Char_Type) * (width + 5) * (height + 3)); + + row = top - 1; + col = left - 2; + /* clip to the current screen bounds - msw */ + if (row < 0) + row = 0; + if (col < 0) + col = 0; + if (left + width > SLtt_Screen_Cols) + width = SLtt_Screen_Cols - left; + if (top + height > SLtt_Screen_Rows) + height = SLtt_Screen_Rows - top; + n = 0; + for (j = 0; j < height + 3; j++, row++) { + SLsmg_gotorc(row, col); + SLsmg_read_raw(currentWindow->buffer + n, + currentWindow->width + 5); + n += currentWindow->width + 5; + } + + newtTrashScreen(); + + SLsmg_set_color(NEWT_COLORSET_BORDER); + SLsmg_set_char_set(1); + SLsmg_draw_box(top - 1, left - 1, height + 2, width + 2); + SLsmg_set_char_set(0); + + if (currentWindow->title) { + trim_string (currentWindow->title, width-4); + i = wstrlen(currentWindow->title,-1) + 4; + i = ((width - i) / 2) + left; + SLsmg_gotorc(top - 1, i); + SLsmg_set_char_set(1); + SLsmg_write_char(SLSMG_RTEE_CHAR); + SLsmg_set_char_set(0); + SLsmg_write_char(' '); + SLsmg_set_color(NEWT_COLORSET_TITLE); + SLsmg_write_string((char *)currentWindow->title); + SLsmg_set_color(NEWT_COLORSET_BORDER); + SLsmg_write_char(' '); + SLsmg_set_char_set(1); + SLsmg_write_char(SLSMG_LTEE_CHAR); + SLsmg_set_char_set(0); + } + + SLsmg_set_color(NEWT_COLORSET_WINDOW); + SLsmg_fill_region(top, left, height, width, ' '); + + SLsmg_set_color(NEWT_COLORSET_SHADOW); + SLsmg_fill_region(top + height + 1, left, 1, width + 2, ' '); + SLsmg_fill_region(top, left + width + 1, height + 1, 1, ' '); + + for (i = top; i < (top + height + 1); i++) { + SLsmg_gotorc(i, left + width + 1); + SLsmg_write_string(" "); + } + + return 0; +} + +/** + * @brief Draw a centered window. + * @param width - width in char cells + * @param height - no. of char cells. + * @param title - fixed title + * @returns zero on success + */ +int newtCenteredWindow(unsigned int width,unsigned int height, + const char * title) { + int top, left; + + top = (int)(SLtt_Screen_Rows - height) / 2; + + /* I don't know why, but this seems to look better */ + if ((SLtt_Screen_Rows % 2) && (top % 2)) top--; + + left = (int)(SLtt_Screen_Cols - width) / 2; + + return newtOpenWindow(left, top, width, height, title); +} + +/** + * @brief Remove the top window + */ +void newtPopWindow(void) { + newtPopWindowNoRefresh(); + newtRefresh(); +} + +void newtPopWindowNoRefresh(void) { + int j, row, col; + int n = 0; + + if (currentWindow == NULL) + return; + + row = col = 0; + + row = currentWindow->top - 1; + col = currentWindow->left - 2; + if (row < 0) + row = 0; + if (col < 0) + col = 0; + for (j = 0; j < currentWindow->height + 3; j++, row++) { + SLsmg_gotorc(row, col); + SLsmg_write_raw(currentWindow->buffer + n, + currentWindow->width + 5); + n += currentWindow->width + 5; + } + + free(currentWindow->buffer); + free(currentWindow->title); + + if (currentWindow == windowStack) + currentWindow = NULL; + else + currentWindow--; + + SLsmg_set_char_set(0); + + newtTrashScreen(); +} + +void newtGetWindowPos(int * x, int * y) { + if (currentWindow) { + *x = currentWindow->left; + *y = currentWindow->top; + } else + *x = *y = 0; +} + +void newtGetrc(int * row, int * col) { + *row = cursorRow; + *col = cursorCol; + + if (currentWindow) { + *row -= currentWindow->top; + *col -= currentWindow->left; + } +} + +void newtGotorc(int newRow, int newCol) { + if (currentWindow) { + newRow += currentWindow->top; + newCol += currentWindow->left; + } + + cursorRow = newRow; + cursorCol = newCol; + SLsmg_gotorc(cursorRow, cursorCol); +} + +void newtDrawBox(int left, int top, int width, int height, int shadow) { + if (currentWindow) { + top += currentWindow->top; + left += currentWindow->left; + } + + SLsmg_draw_box(top, left, height, width); + + if (shadow) { + SLsmg_set_color(NEWT_COLORSET_SHADOW); + SLsmg_fill_region(top + height, left + 1, 1, width - 1, ' '); + SLsmg_fill_region(top + 1, left + width, height, 1, ' '); + } +} + +void newtClearBox(int left, int top, int width, int height) { + if (currentWindow) { + top += currentWindow->top; + left += currentWindow->left; + } + + SLsmg_fill_region(top, left, height, width, ' '); +} + +static void initKeymap(void) { + const struct keymap * curr; + struct kmap_trie_entry *kmap_trie_escBrack, *kmap_trie_escO; + + /* Here are some entries that will help in handling esc O foo and + esc [ foo as variants of each other. */ + kmap_trie_root = calloc(3, sizeof (struct kmap_trie_entry)); + kmap_trie_escBrack = kmap_trie_root + 1; + kmap_trie_escO = kmap_trie_root + 2; + + kmap_trie_root->alloced = 1; + kmap_trie_root->c = '\033'; + kmap_trie_root->contseq = kmap_trie_escBrack; + + kmap_trie_escBrack->c = '['; + kmap_trie_escBrack->next = kmap_trie_escO; + + kmap_trie_escO->c = 'O'; + + /* First bind built-in default bindings. They may be shadowed by + the termcap entries that get bound later. */ + for (curr = keymap; curr->code; curr++) { + if (curr->str) + newtBindKey(curr->str,curr->code); + } + + /* Then bind strings from termcap entries */ + for (curr = keymap; curr->code; curr++) { + if (curr->tc) { + char *pc = SLtt_tgetstr(curr->tc); + if (pc) { + newtBindKey(pc,curr->code); + } + } + } + + /* Finally, invent lowest-priority keybindings that correspond to + searching for esc-O-foo if esc-[-foo was not found and vice + versa. That is needed because of strong confusion among + different emulators of VTxxx terminals; some terminfo/termcap + descriptions are apparently written by people who were not + aware of the differences between "applicataion" and "terminal" + keypad modes. Or perhaps they were, but tried to make their + description work with a program that puts the keyboard in the + wrong emulation mode. In short, one needs this: */ + kmap_trie_fallback(kmap_trie_escO->contseq, &kmap_trie_escBrack->contseq); + kmap_trie_fallback(kmap_trie_escBrack->contseq, &kmap_trie_escO->contseq); +} + +static void free_keys(struct kmap_trie_entry *kmap, struct kmap_trie_entry *parent, int prepare) { + if (kmap == NULL) + return; + + free_keys(kmap->contseq, kmap, prepare); + free_keys(kmap->next, kmap, prepare); + + if (!kmap->alloced && kmap - parent == 1) + return; + + /* find first element in array */ + while (!kmap->alloced) + kmap--; + + kmap->alloced += prepare ? 1 : -1; + if (!prepare && kmap->alloced == 1) + free(kmap); +} + +static void freeKeymap() { + free_keys(kmap_trie_root, NULL, 1); + free_keys(kmap_trie_root, NULL, 0); + kmap_trie_root = NULL; +} + +/** + * @brief Delay for a specified number of usecs + * @param int - number of usecs to wait for. + */ +void newtDelay(unsigned int usecs) { + usleep(usecs); +} + +struct eventResult newtDefaultEventHandler(newtComponent c, + struct event ev) { + struct eventResult er; + + er.result = ER_IGNORED; + return er; +} + +void newtRedrawHelpLine(void) { + char * buf; + + SLsmg_set_color(NEWT_COLORSET_HELPLINE); + + if (currentHelpline) { + /* buffer size needs to be wide enough to hold all the multibyte + currentHelpline + all the single byte ' ' to fill the line */ + int wlen = wstrlen(*currentHelpline, -1); + int len; + + if (wlen > SLtt_Screen_Cols) + wlen = SLtt_Screen_Cols; + len = strlen(*currentHelpline) + (SLtt_Screen_Cols - wlen); + buf = alloca(len + 1); + memset(buf, ' ', len); + memcpy(buf, *currentHelpline, strlen(*currentHelpline)); + buf[len] = '\0'; + } else { + buf = alloca(SLtt_Screen_Cols + 1); + memset(buf, ' ', SLtt_Screen_Cols); + buf[SLtt_Screen_Cols] = '\0'; + } + SLsmg_gotorc(SLtt_Screen_Rows - 1, 0); + SLsmg_write_string(buf); + SLsmg_gotorc(cursorRow, cursorCol); +} + +void newtPushHelpLine(const char * text) { + if (currentHelpline && currentHelpline - helplineStack + 1 + >= sizeof (helplineStack) / sizeof (char *)) + return; + + if (!text) + text = defaultHelpLine; + + if (currentHelpline) + (*(++currentHelpline)) = strdup(text); + else { + currentHelpline = helplineStack; + *currentHelpline = strdup(text); + } + + newtRedrawHelpLine(); +} + +void newtPopHelpLine(void) { + if (!currentHelpline) return; + + free(*currentHelpline); + if (currentHelpline == helplineStack) + currentHelpline = NULL; + else + currentHelpline--; + + newtRedrawHelpLine(); +} + +void newtDrawRootText(int col, int row, const char * text) { + SLsmg_set_color(NEWT_COLORSET_ROOTTEXT); + + if (col < 0) { + col = SLtt_Screen_Cols + col; + } + + if (row < 0) { + row = SLtt_Screen_Rows + row; + } + + SLsmg_gotorc(row, col); + SLsmg_write_string((char *)text); +} + +int newtSetFlags(int oldFlags, int newFlags, enum newtFlagsSense sense) { + switch (sense) { + case NEWT_FLAGS_SET: + return oldFlags | newFlags; + + case NEWT_FLAGS_RESET: + return oldFlags & (~newFlags); + + case NEWT_FLAGS_TOGGLE: + return oldFlags ^ newFlags; + + default: + return oldFlags; + } +} + +void newtBell(void) +{ + SLtt_beep(); +} + +void newtGetScreenSize(int * cols, int * rows) { + if (rows) *rows = SLtt_Screen_Rows; + if (cols) *cols = SLtt_Screen_Cols; +} + +void newtDefaultPlaceHandler(newtComponent c, int newLeft, int newTop) { + c->left = newLeft; + c->top = newTop; +} + +void newtDefaultMappedHandler(newtComponent c, int isMapped) { + c->isMapped = isMapped; +} + +void newtCursorOff(void) { + cursorOn = 0; + SLtt_set_cursor_visibility (cursorOn); +} + +void newtCursorOn(void) { + cursorOn = 1; + SLtt_set_cursor_visibility (cursorOn); +} + +void newtTrashScreen(void) { + if (trashScreen) + SLsmg_touch_lines(0, SLtt_Screen_Rows); +} + +void newtComponentGetPosition(newtComponent co, int * left, int * top) { + if (left) *left = co->left; + if (top) *top = co->top; +} + +void newtComponentGetSize(newtComponent co, int * width, int * height) { + if (width) *width = co->width; + if (height) *height = co->height; +} diff --git a/newt.h b/newt.h new file mode 100644 index 0000000..07becc7 --- /dev/null +++ b/newt.h @@ -0,0 +1,398 @@ +#ifndef H_NEWT +#define H_NEWT + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define NEWT_COLORSET_ROOT 2 +#define NEWT_COLORSET_BORDER 3 +#define NEWT_COLORSET_WINDOW 4 +#define NEWT_COLORSET_SHADOW 5 +#define NEWT_COLORSET_TITLE 6 +#define NEWT_COLORSET_BUTTON 7 +#define NEWT_COLORSET_ACTBUTTON 8 +#define NEWT_COLORSET_CHECKBOX 9 +#define NEWT_COLORSET_ACTCHECKBOX 10 +#define NEWT_COLORSET_ENTRY 11 +#define NEWT_COLORSET_LABEL 12 +#define NEWT_COLORSET_LISTBOX 13 +#define NEWT_COLORSET_ACTLISTBOX 14 +#define NEWT_COLORSET_TEXTBOX 15 +#define NEWT_COLORSET_ACTTEXTBOX 16 +#define NEWT_COLORSET_HELPLINE 17 +#define NEWT_COLORSET_ROOTTEXT 18 +#define NEWT_COLORSET_EMPTYSCALE 19 +#define NEWT_COLORSET_FULLSCALE 20 +#define NEWT_COLORSET_DISENTRY 21 +#define NEWT_COLORSET_COMPACTBUTTON 22 +#define NEWT_COLORSET_ACTSELLISTBOX 23 +#define NEWT_COLORSET_SELLISTBOX 24 + +#define NEWT_COLORSET_CUSTOM(x) (30 + (x)) + +#define NEWT_ARG_LAST -100000 +#define NEWT_ARG_APPEND -1 + +struct newtColors { + char * rootFg, * rootBg; + char * borderFg, * borderBg; + char * windowFg, * windowBg; + char * shadowFg, * shadowBg; + char * titleFg, * titleBg; + char * buttonFg, * buttonBg; + char * actButtonFg, * actButtonBg; + char * checkboxFg, * checkboxBg; + char * actCheckboxFg, * actCheckboxBg; + char * entryFg, * entryBg; + char * labelFg, * labelBg; + char * listboxFg, * listboxBg; + char * actListboxFg, * actListboxBg; + char * textboxFg, * textboxBg; + char * actTextboxFg, * actTextboxBg; + char * helpLineFg, * helpLineBg; + char * rootTextFg, * rootTextBg; + char * emptyScale, * fullScale; + char * disabledEntryFg, * disabledEntryBg; + char * compactButtonFg, * compactButtonBg; + char * actSelListboxFg, * actSelListboxBg; + char * selListboxFg, * selListboxBg; +}; + +enum newtFlagsSense { NEWT_FLAGS_SET, NEWT_FLAGS_RESET, NEWT_FLAGS_TOGGLE }; + +#define NEWT_FLAG_RETURNEXIT (1 << 0) +#define NEWT_FLAG_HIDDEN (1 << 1) +#define NEWT_FLAG_SCROLL (1 << 2) +#define NEWT_FLAG_DISABLED (1 << 3) +/* OBSOLETE #define NEWT_FLAG_NOSCROLL (1 << 4) for listboxes */ +#define NEWT_FLAG_BORDER (1 << 5) +#define NEWT_FLAG_WRAP (1 << 6) +#define NEWT_FLAG_NOF12 (1 << 7) +#define NEWT_FLAG_MULTIPLE (1 << 8) +#define NEWT_FLAG_SELECTED (1 << 9) +#define NEWT_FLAG_CHECKBOX (1 << 10) +#define NEWT_FLAG_PASSWORD (1 << 11) /* draw '*' of chars in entrybox */ +#define NEWT_FLAG_SHOWCURSOR (1 << 12) /* Only applies to listbox for now */ +#define NEWT_FD_READ (1 << 0) +#define NEWT_FD_WRITE (1 << 1) +#define NEWT_FD_EXCEPT (1 << 2) + +#define NEWT_CHECKBOXTREE_UNSELECTABLE (1 << 12) +#define NEWT_CHECKBOXTREE_HIDE_BOX (1 << 13) + +#define NEWT_CHECKBOXTREE_COLLAPSED '\0' +#define NEWT_CHECKBOXTREE_EXPANDED '\1' +#define NEWT_CHECKBOXTREE_UNSELECTED ' ' +#define NEWT_CHECKBOXTREE_SELECTED '*' + +/* Backwards compatibility */ +#define NEWT_LISTBOX_RETURNEXIT NEWT_FLAG_RETURNEXIT +#define NEWT_ENTRY_SCROLL NEWT_FLAG_SCROLL +#define NEWT_ENTRY_HIDDEN NEWT_FLAG_HIDDEN +#define NEWT_ENTRY_RETURNEXIT NEWT_FLAG_RETURNEXIT +#define NEWT_ENTRY_DISABLED NEWT_FLAG_DISABLED + +#define NEWT_TEXTBOX_WRAP NEWT_FLAG_WRAP +#define NEWT_TEXTBOX_SCROLL NEWT_FLAG_SCROLL +#define NEWT_FORM_NOF12 NEWT_FLAG_NOF12 + +#define newtListboxAddEntry newtListboxAppendEntry + + +typedef struct newtComponent_struct * newtComponent; + +extern const struct newtColors newtDefaultColorPalette; + +typedef void (*newtCallback)(newtComponent, void *); +typedef void (*newtSuspendCallback)(void * data); + +int newtInit(void); +int newtFinished(void); +void newtCls(void); +void newtResizeScreen(int redraw); +void newtWaitForKey(void); +void newtClearKeyBuffer(void); +void newtDelay(unsigned int usecs); +/* top, left are *not* counting the border */ +int newtOpenWindow(int left,int top, + unsigned int width,unsigned int height, + const char * title); +int newtCenteredWindow(unsigned int width,unsigned int height, const char * title); +void newtPopWindow(void); +void newtPopWindowNoRefresh(void); +void newtSetColors(struct newtColors colors); +void newtSetColor(int colorset, char *fg, char *bg); +void newtRefresh(void); +void newtSuspend(void); +void newtSetSuspendCallback(newtSuspendCallback cb, void * data); +void newtSetHelpCallback(newtCallback cb); +int newtResume(void); +void newtPushHelpLine(const char * text); +void newtRedrawHelpLine(void); +void newtPopHelpLine(void); +void newtDrawRootText(int col, int row, const char * text); +void newtBell(void); +void newtCursorOff(void); +void newtCursorOn(void); + +/* Components */ + +newtComponent newtCompactButton(int left, int top, const char * text); +newtComponent newtButton(int left, int top, const char * text); +newtComponent newtCheckbox(int left, int top, const char * text, char defValue, + const char * seq, char * result); +char newtCheckboxGetValue(newtComponent co); +void newtCheckboxSetValue(newtComponent co, char value); +void newtCheckboxSetFlags(newtComponent co, int flags, enum newtFlagsSense sense); + + +newtComponent newtRadiobutton(int left, int top, const char * text, int isDefault, + newtComponent prevButton); +newtComponent newtRadioGetCurrent(newtComponent setMember); +void newtRadioSetCurrent(newtComponent setMember); +void newtGetScreenSize(int * cols, int * rows); + +newtComponent newtLabel(int left, int top, const char * text); +void newtLabelSetText(newtComponent co, const char * text); +void newtLabelSetColors(newtComponent co, int colorset); +newtComponent newtVerticalScrollbar(int left, int top, int height, + int normalColorset, int thumbColorset); +void newtScrollbarSet(newtComponent co, int where, int total); +void newtScrollbarSetColors(newtComponent co, int normal, int thumb); + +newtComponent newtListbox(int left, int top, int height, int flags); +void * newtListboxGetCurrent(newtComponent co); +void newtListboxSetCurrent(newtComponent co, int num); +void newtListboxSetCurrentByKey(newtComponent co, void * key); +void newtListboxSetEntry(newtComponent co, int num, const char * text); +void newtListboxSetWidth(newtComponent co, int width); +void newtListboxSetData(newtComponent co, int num, void * data); +int newtListboxAppendEntry(newtComponent co, const char * text, + const void * data); +/* Send the key to insert after, or NULL to insert at the top */ +int newtListboxInsertEntry(newtComponent co, const char * text, const void * data, void * key); +int newtListboxDeleteEntry(newtComponent co, void * data); +void newtListboxClear(newtComponent co); /* removes all entries from listbox */ +void newtListboxGetEntry(newtComponent co, int num, char **text, void **data); +/* Returns an array of data pointers from items, last element is NULL */ +void **newtListboxGetSelection(newtComponent co, int *numitems); +void newtListboxClearSelection(newtComponent co); +void newtListboxSelectItem(newtComponent co, const void * key, + enum newtFlagsSense sense); +/* Returns number of items currently in listbox. */ +int newtListboxItemCount(newtComponent co); + +newtComponent newtCheckboxTree(int left, int top, int height, int flags); +newtComponent newtCheckboxTreeMulti(int left, int top, int height, char *seq, int flags); +const void ** newtCheckboxTreeGetSelection(newtComponent co, int *numitems); +const void * newtCheckboxTreeGetCurrent(newtComponent co); +void newtCheckboxTreeSetCurrent(newtComponent co, void * item); +const void ** newtCheckboxTreeGetMultiSelection(newtComponent co, int *numitems, char seqnum); +/* last item is NEWT_ARG_LAST for all of these */ +int newtCheckboxTreeAddItem(newtComponent co, + const char * text, const void * data, + int flags, int index, ...); +int newtCheckboxTreeAddArray(newtComponent co, + const char * text, const void * data, + int flags, int * indexes); +int * newtCheckboxTreeFindItem(newtComponent co, void * data); +void newtCheckboxTreeSetEntry(newtComponent co, const void * data, + const char * text); +void newtCheckboxTreeSetWidth(newtComponent co, int width); +char newtCheckboxTreeGetEntryValue(newtComponent co, const void * data); +void newtCheckboxTreeSetEntryValue(newtComponent co, const void * data, + char value); + +newtComponent newtTextboxReflowed(int left, int top, char * text, int width, + int flexDown, int flexUp, int flags); +newtComponent newtTextbox(int left, int top, int width, int height, int flags); +void newtTextboxSetText(newtComponent co, const char * text); +void newtTextboxSetHeight(newtComponent co, int height); +int newtTextboxGetNumLines(newtComponent co); +void newtTextboxSetColors(newtComponent co, int normal, int active); +char * newtReflowText(char * text, int width, int flexDown, int flexUp, + int * actualWidth, int * actualHeight); + +struct newtExitStruct { + enum { NEWT_EXIT_HOTKEY, NEWT_EXIT_COMPONENT, NEWT_EXIT_FDREADY, + NEWT_EXIT_TIMER, NEWT_EXIT_ERROR } reason; + union { + int watch; + int key; + newtComponent co; + } u; +} ; + +newtComponent newtForm(newtComponent vertBar, void * helpTag, int flags); +void newtFormSetTimer(newtComponent form, int millisecs); +void newtFormWatchFd(newtComponent form, int fd, int fdFlags); +void newtFormSetSize(newtComponent co); +newtComponent newtFormGetCurrent(newtComponent co); +void newtFormSetBackground(newtComponent co, int color); +void newtFormSetCurrent(newtComponent co, newtComponent subco); +void newtFormAddComponent(newtComponent form, newtComponent co); +void newtFormAddComponents(newtComponent form, ...); +void newtFormSetHeight(newtComponent co, int height); +void newtFormSetWidth(newtComponent co, int width); +newtComponent newtRunForm(newtComponent form); /* obsolete */ +void newtFormRun(newtComponent co, struct newtExitStruct * es); +void newtDrawForm(newtComponent form); +void newtFormAddHotKey(newtComponent co, int key); +int newtFormGetScrollPosition(newtComponent co); +void newtFormSetScrollPosition(newtComponent co, int position); + +typedef int (*newtEntryFilter)(newtComponent entry, void * data, int ch, + int cursor); +newtComponent newtEntry(int left, int top, const char * initialValue, int width, + const char ** resultPtr, int flags); +void newtEntrySet(newtComponent co, const char * value, int cursorAtEnd); +void newtEntrySetFilter(newtComponent co, newtEntryFilter filter, void * data); +char * newtEntryGetValue(newtComponent co); +void newtEntrySetFlags(newtComponent co, int flags, enum newtFlagsSense sense); +void newtEntrySetColors(newtComponent co, int normal, int disabled); +int newtEntryGetCursorPosition(newtComponent co); +void newtEntrySetCursorPosition(newtComponent co, int position); + +newtComponent newtScale(int left, int top, int width, long long fullValue); +void newtScaleSet(newtComponent co, unsigned long long amount); +void newtScaleSetColors(newtComponent co, int empty, int full); + +void newtComponentAddCallback(newtComponent co, newtCallback f, void * data); +void newtComponentTakesFocus(newtComponent co, int val); + +void newtComponentGetPosition(newtComponent co, int * left, int * top); +void newtComponentGetSize(newtComponent co, int * width, int * height); + +/* This callback is called when a component is destroyed. */ +void newtComponentAddDestroyCallback(newtComponent co, + newtCallback f, void * data); + +/* this also destroys all of the components (including other forms) on the + form */ +void newtFormDestroy(newtComponent form); + +/* NB: You SHOULD NOT call this for components which have been added + * to a form (ie. almost all components). They are destroyed along + * with the form when you call newtFormDestroy. + */ +void newtComponentDestroy(newtComponent co); + +/* Key codes */ + +#define NEWT_KEY_TAB '\t' +#define NEWT_KEY_ENTER '\r' +#define NEWT_KEY_SUSPEND '\032' /* ctrl - z*/ +#define NEWT_KEY_ESCAPE '' +#define NEWT_KEY_RETURN NEWT_KEY_ENTER + +#define NEWT_KEY_EXTRA_BASE 0x8000 +#define NEWT_KEY_UP NEWT_KEY_EXTRA_BASE + 1 +#define NEWT_KEY_DOWN NEWT_KEY_EXTRA_BASE + 2 +#define NEWT_KEY_LEFT NEWT_KEY_EXTRA_BASE + 4 +#define NEWT_KEY_RIGHT NEWT_KEY_EXTRA_BASE + 5 +#define NEWT_KEY_BKSPC NEWT_KEY_EXTRA_BASE + 6 +#define NEWT_KEY_DELETE NEWT_KEY_EXTRA_BASE + 7 +#define NEWT_KEY_HOME NEWT_KEY_EXTRA_BASE + 8 +#define NEWT_KEY_END NEWT_KEY_EXTRA_BASE + 9 +#define NEWT_KEY_UNTAB NEWT_KEY_EXTRA_BASE + 10 +#define NEWT_KEY_PGUP NEWT_KEY_EXTRA_BASE + 11 +#define NEWT_KEY_PGDN NEWT_KEY_EXTRA_BASE + 12 +#define NEWT_KEY_INSERT NEWT_KEY_EXTRA_BASE + 13 + +#define NEWT_KEY_F1 NEWT_KEY_EXTRA_BASE + 101 +#define NEWT_KEY_F2 NEWT_KEY_EXTRA_BASE + 102 +#define NEWT_KEY_F3 NEWT_KEY_EXTRA_BASE + 103 +#define NEWT_KEY_F4 NEWT_KEY_EXTRA_BASE + 104 +#define NEWT_KEY_F5 NEWT_KEY_EXTRA_BASE + 105 +#define NEWT_KEY_F6 NEWT_KEY_EXTRA_BASE + 106 +#define NEWT_KEY_F7 NEWT_KEY_EXTRA_BASE + 107 +#define NEWT_KEY_F8 NEWT_KEY_EXTRA_BASE + 108 +#define NEWT_KEY_F9 NEWT_KEY_EXTRA_BASE + 109 +#define NEWT_KEY_F10 NEWT_KEY_EXTRA_BASE + 110 +#define NEWT_KEY_F11 NEWT_KEY_EXTRA_BASE + 111 +#define NEWT_KEY_F12 NEWT_KEY_EXTRA_BASE + 112 + +/* not really a key, but newtGetKey returns it */ +#define NEWT_KEY_RESIZE NEWT_KEY_EXTRA_BASE + 113 +#define NEWT_KEY_ERROR NEWT_KEY_EXTRA_BASE + 114 + +#define NEWT_ANCHOR_LEFT (1 << 0) +#define NEWT_ANCHOR_RIGHT (1 << 1) +#define NEWT_ANCHOR_TOP (1 << 2) +#define NEWT_ANCHOR_BOTTOM (1 << 3) + +#define NEWT_GRID_FLAG_GROWX (1 << 0) +#define NEWT_GRID_FLAG_GROWY (1 << 1) + +typedef struct grid_s * newtGrid; +enum newtGridElement { NEWT_GRID_EMPTY = 0, + NEWT_GRID_COMPONENT, NEWT_GRID_SUBGRID }; + +newtGrid newtCreateGrid(int cols, int rows); +/* TYPE, what, TYPE, what, ..., NULL */ +newtGrid newtGridVStacked(enum newtGridElement type, void * what, ...); +newtGrid newtGridVCloseStacked(enum newtGridElement type, void * what, ...); +newtGrid newtGridHStacked(enum newtGridElement type1, void * what1, ...); +newtGrid newtGridHCloseStacked(enum newtGridElement type1, void * what1, ...); +newtGrid newtGridBasicWindow(newtComponent text, newtGrid middle, + newtGrid buttons); +newtGrid newtGridSimpleWindow(newtComponent text, newtComponent middle, + newtGrid buttons); +void newtGridSetField(newtGrid grid, int col, int row, + enum newtGridElement type, void * val, int padLeft, + int padTop, int padRight, int padBottom, int anchor, + int flags); +void newtGridPlace(newtGrid grid, int left, int top); +#define newtGridDestroy newtGridFree +void newtGridFree(newtGrid grid, int recurse); +void newtGridGetSize(newtGrid grid, int * width, int * height); +void newtGridWrappedWindow(newtGrid grid, char * title); +void newtGridWrappedWindowAt(newtGrid grid, char * title, int left, int top); +void newtGridAddComponentsToForm(newtGrid grid, newtComponent form, + int recurse); + +/* convienve */ +newtGrid newtButtonBarv(char * button1, newtComponent * b1comp, va_list args); +newtGrid newtButtonBar(char * button1, newtComponent * b1comp, ...); + +/* automatically centered and shrink wrapped */ +void newtWinMessage(char * title, char * buttonText, char * text, ...); +void newtWinMessagev(char * title, char * buttonText, char * text, + va_list argv); + +/* having separate calls for these two seems silly, but having two separate + variable length-arg lists seems like a bad idea as well */ + +/* Returns 0 if F12 was pressed, 1 for button1, 2 for button2 */ +int newtWinChoice(char * title, char * button1, char * button2, + char * text, ...); +/* Returns 0 if F12 was pressed, 1 for button1, 2 for button2, + 3 for button3 */ +int newtWinTernary(char * title, char * button1, char * button2, + char * button3, char * message, ...); + +/* Returns the button number pressed, 0 on F12 */ +int newtWinMenu(char * title, char * text, int suggestedWidth, int flexDown, + int flexUp, int maxListHeight, char ** items, int * listItem, + char * button1, ...); + +struct newtWinEntry { + char * text; + char ** value; /* may be initialized to set default */ + int flags; +}; + +/* Returns the button number pressed, 0 on F12. The final values are + dynamically allocated, and need to be freed. */ +int newtWinEntries(char * title, char * text, int suggestedWidth, int flexDown, + int flexUp, int dataWidth, + struct newtWinEntry * items, char * button1, ...); + +#ifdef __cplusplus +} /* End of extern "C" { */ +#endif + +#endif /* H_NEWT */ diff --git a/newt_pr.h b/newt_pr.h new file mode 100644 index 0000000..5d60ebe --- /dev/null +++ b/newt_pr.h @@ -0,0 +1,90 @@ +#ifndef H_NEWT_PR +#define H_NEWT_PR + +#define COLORSET_ROOT NEWT_COLORSET_ROOT +#define COLORSET_BORDER NEWT_COLORSET_BORDER +#define COLORSET_WINDOW NEWT_COLORSET_WINDOW +#define COLORSET_SHADOW NEWT_COLORSET_SHADOW +#define COLORSET_TITLE NEWT_COLORSET_TITLE +#define COLORSET_BUTTON NEWT_COLORSET_BUTTON +#define COLORSET_ACTBUTTON NEWT_COLORSET_ACTBUTTON +#define COLORSET_CHECKBOX NEWT_COLORSET_CHECKBOX +#define COLORSET_ACTCHECKBOX NEWT_COLORSET_ACTCHECKBOX +#define COLORSET_ENTRY NEWT_COLORSET_ENTRY +#define COLORSET_LABEL NEWT_COLORSET_LABEL +#define COLORSET_LISTBOX NEWT_COLORSET_LISTBOX +#define COLORSET_ACTLISTBOX NEWT_COLORSET_ACTLISTBOX +#define COLORSET_TEXTBOX NEWT_COLORSET_TEXTBOX +#define COLORSET_ACTTEXTBOX NEWT_COLORSET_ACTTEXTBOX + +int newtSetFlags(int oldFlags, int newFlags, enum newtFlagsSense sense); + +void newtGotorc(int row, int col); +void newtGetrc(int * row, int * col); +void newtGetWindowPos(int * x, int * y); +void newtDrawBox(int left, int top, int width, int height, int shadow); +void newtClearBox(int left, int top, int width, int height); + +int newtGetKey(void); +void newtTrashScreen(void); + +struct newtComponent_struct { + /* common data */ + int height, width; + int top, left; + int takesFocus; + int isMapped; + + struct componentOps * ops; + + newtCallback callback; + void * callbackData; + + newtCallback destroyCallback; + void * destroyCallbackData; + + void * data; +} ; + +enum eventResultTypes { ER_IGNORED, ER_SWALLOWED, ER_EXITFORM, ER_SETFOCUS, + ER_NEXTCOMP }; +struct eventResult { + enum eventResultTypes result; + union { + newtComponent focus; + } u; +}; + +enum eventTypes { EV_FOCUS, EV_UNFOCUS, EV_KEYPRESS, EV_MOUSE }; +enum eventSequence { EV_EARLY, EV_NORMAL, EV_LATE }; + +struct event { + enum eventTypes event; + enum eventSequence when; + union { + int key; + struct { + enum { MOUSE_MOTION, MOUSE_BUTTON_DOWN, MOUSE_BUTTON_UP } type; + int x, y; + } mouse; + } u; +} ; + +struct componentOps { + void (* draw)(newtComponent c); + struct eventResult (* event)(newtComponent c, struct event ev); + void (* destroy)(newtComponent c); + void (* place)(newtComponent c, int newLeft, int newTop); + void (* mapped)(newtComponent c, int isMapped); +} ; + +void newtDefaultPlaceHandler(newtComponent c, int newLeft, int newTop); +void newtDefaultMappedHandler(newtComponent c, int isMapped); +struct eventResult newtDefaultEventHandler(newtComponent c, + struct event ev); + +int _newt_wstrlen(const char *str, int len); +#define wstrlen(str,len) _newt_wstrlen((str),(len)) +void trim_string(char *title, int chrs); + +#endif /* H_NEWT_PR */ diff --git a/nls.h b/nls.h new file mode 100644 index 0000000..a803105 --- /dev/null +++ b/nls.h @@ -0,0 +1,22 @@ + + +#ifndef LOCALEDIR +#define LOCALEDIR "/usr/share/locale" +#endif + +# include + +#ifdef ENABLE_NLS +# include +# define _(Text) gettext (Text) +#else +# define _(Text) (Text) +# define dgettext(Package, String) (String) +#endif + +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif + diff --git a/peanuts.py b/peanuts.py new file mode 100755 index 0000000..535571d --- /dev/null +++ b/peanuts.py @@ -0,0 +1,46 @@ +#!/usr/bin/python + +# Demo program to show use of python-newt module + +from __future__ import absolute_import, print_function, unicode_literals +from snack import * + +screen = SnackScreen() + +li = Listbox(height = 3, width = 20, returnExit = 1) +li.append("First", 1) +li.append("Second", 2) +li.append("Third", 3) +rb = RadioBar(screen, (("This", "this", 0), + ("Default", "default", 1), + ("That", "that", 0))) +bb = ButtonBar(screen, (("Ok", "ok"), ("Cancel", "cancel"))) + +ct = CheckboxTree(height = 5, scroll = 1) +ct.append("Colors") +ct.addItem("Red", (0, snackArgs['append'])) +ct.addItem("Yellow", (0, snackArgs['append'])) +ct.addItem("Blue", (0, snackArgs['append'])) +ct.append("Flavors") +ct.append("Numbers") +ct.addItem("1", (2, snackArgs['append'])) +ct.addItem("2", (2, snackArgs['append'])) +ct.addItem("3", (2, snackArgs['append'])) +ct.append("Names") +ct.append("Months") +ct.append("Events") +g = GridForm(screen, "My Test", 1, 4) +g.add(li, 0, 0) +g.add(rb, 0, 1, (0, 1, 0, 1)) +g.add(ct, 0, 2) +g.add(bb, 0, 3, growx = 1) + +result = g.runOnce() + +screen.finish() + +print(result) +print("listbox:", li.current()) +print("rb:", rb.getSelection()) +print("bb:", bb.buttonPressed(result)) +print("checkboxtree:", ct.getSelection()) diff --git a/po/Makefile b/po/Makefile new file mode 100644 index 0000000..1c5c123 --- /dev/null +++ b/po/Makefile @@ -0,0 +1,66 @@ +INSTALL= /usr/bin/install -c +INSTALL_PROGRAM= ${INSTALL} +INSTALL_DATA= ${INSTALL} -m 644 +INSTALLNLSDIR=$(datadir)/locale + +MSGMERGE = msgmerge + +NLSPACKAGE = newt + +CATALOGS = $(shell ls *.po) +FMTCATALOGS = $(patsubst %.po,%.mo,$(CATALOGS)) + +POTFILES = ../dialogboxes.c + +all: $(NLSPACKAGE).pot $(FMTCATALOGS) + +$(NLSPACKAGE).pot: $(POTFILES) + xgettext --default-domain=$(NLSPACKAGE) \ + --package-name=$(NLSPACKAGE) \ + --add-comments --keyword=_ --keyword=N_ $(POTFILES) + if cmp -s $(NLSPACKAGE).po $(NLSPACKAGE).pot; then \ + rm -f $(NLSPACKAGE).po; \ + else \ + mv $(NLSPACKAGE).po $(NLSPACKAGE).pot; \ + fi + +refresh-po: Makefile + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + lang=`echo $$cat | sed 's/.po//'`; \ + if $(MSGMERGE) $$lang.po $(NLSPACKAGE).pot > $$lang.pot ; then \ + mv -f $$lang.pot $$lang.po ; \ + echo "$(MSGMERGE) of $$lang succeeded" ; \ + else \ + echo "$(MSGMERGE) of $$lang failed" ; \ + rm -f $$lang.pot ; \ + fi \ + done + +update-po: $(NLSPACKAGE).pot Makefile refresh-po + +report: + @for cat in $(CATALOGS); do \ + echo -n "$$cat: "; \ + msgfmt -v --statistics -o /dev/null $$cat; \ + done + +clean: + rm -f *mo + +depend: + +install: all + mkdir -p $(INSTALLNLSDIR) + for n in $(CATALOGS); do \ + l=`basename $$n .po`; \ + mo=$$l.mo; \ + $(INSTALL) -m 755 -d $(INSTALLNLSDIR)/$$l; \ + $(INSTALL) -m 755 -d $(INSTALLNLSDIR)/$$l/LC_MESSAGES; \ + if [ -f $$n ]; then \ + $(INSTALL) -m 644 $$mo $(INSTALLNLSDIR)/$$l/LC_MESSAGES/$(NLSPACKAGE).mo; \ + fi; \ + done + +%.mo: %.po + msgfmt -v -o $@ $< diff --git a/po/ar.mo b/po/ar.mo new file mode 100644 index 0000000..8798bf5 Binary files /dev/null and b/po/ar.mo differ diff --git a/po/ar.po b/po/ar.po new file mode 100644 index 0000000..b69539b --- /dev/null +++ b/po/ar.po @@ -0,0 +1,34 @@ +# translation of newt_newt_po_ar.po to Arabic +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. +# Abdulaziz Al-Arfaj , 2004. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-07-20 05:22-0400\n" +"Last-Translator: Abdulaziz Al-Arfaj \n" +"Language-Team: Arabic \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ar\n" +"Plural-Forms: nplurals=6; plural= n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "موافق" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "إلغاء" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "نعم" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "لا" diff --git a/po/as.mo b/po/as.mo new file mode 100644 index 0000000..2dd10fd Binary files /dev/null and b/po/as.mo differ diff --git a/po/as.po b/po/as.po new file mode 100644 index 0000000..25ed5ee --- /dev/null +++ b/po/as.po @@ -0,0 +1,34 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +#, 2009. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2009-09-10 07:16-0400\n" +"Last-Translator: \n" +"Language-Team: Assamese <>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: as\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "ঠিক আছে" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "বাতিল" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "হয়" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "নহয়" diff --git a/po/ast.mo b/po/ast.mo new file mode 100644 index 0000000..9935c73 Binary files /dev/null and b/po/ast.mo differ diff --git a/po/ast.po b/po/ast.po new file mode 100644 index 0000000..e3d7e65 --- /dev/null +++ b/po/ast.po @@ -0,0 +1,34 @@ +# Asturian translations for newt +# Copyright (C) 2003 Free Software Foundation +# This file is distributed under the same license as the newt package. +# Astur , 2009 +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2009-10-24 10:20-0400\n" +"Last-Translator: astur \n" +"Language-Team: Asturian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ast\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Aceutar" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Encaboxar" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Sí" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Non" diff --git a/po/bal.mo b/po/bal.mo new file mode 100644 index 0000000..061f466 Binary files /dev/null and b/po/bal.mo differ diff --git a/po/bal.po b/po/bal.po new file mode 100644 index 0000000..de11035 --- /dev/null +++ b/po/bal.po @@ -0,0 +1,36 @@ +# translation of newt.master.balochi.po to Balochi +# translation of newt.master.balochi.po to +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Mostafa Daneshvar , 2008. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2008-03-21 02:34-0400\n" +"Last-Translator: Mostafa Daneshvar \n" +"Language-Team: Balochi \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: bal\n" +"Plural-Forms: nplurals=1; plural=0\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "هوبنت" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "کنسل" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "بله" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "نه" diff --git a/po/bg.mo b/po/bg.mo new file mode 100644 index 0000000..288a9e8 Binary files /dev/null and b/po/bg.mo differ diff --git a/po/bg.po b/po/bg.po new file mode 100644 index 0000000..f4b56c9 --- /dev/null +++ b/po/bg.po @@ -0,0 +1,36 @@ +# Bulgarian translation of newt. +# This file is distributed under the same license as the newt package. +# Ognyan Kulev , 2004. +#, fuzzy +# +# +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-09-13 02:02-0400\n" +"Last-Translator: Ognyan Kulev \n" +"Language-Team: Bulgarian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: bg\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "OK" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Отказ" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Да" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Не" diff --git a/po/bn.mo b/po/bn.mo new file mode 100644 index 0000000..ce08840 Binary files /dev/null and b/po/bn.mo differ diff --git a/po/bn.po b/po/bn.po new file mode 100644 index 0000000..2cac894 --- /dev/null +++ b/po/bn.po @@ -0,0 +1,34 @@ +# Bangla translation of newt_newt.pot. +# Copyright (C) 2005, Debian Foundation. +# This file is distributed under the same license as the Newt_Newt package. +# Progga , 2005. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2005-11-20 08:00-0500\n" +"Last-Translator: Progga \n" +"Language-Team: Bangla \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: bn\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "ঠিক আছে" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "বাতিল" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "হ্যাঁ" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "না" diff --git a/po/bn_IN.mo b/po/bn_IN.mo new file mode 100644 index 0000000..5044d95 Binary files /dev/null and b/po/bn_IN.mo differ diff --git a/po/bn_IN.po b/po/bn_IN.po new file mode 100644 index 0000000..2f3dff7 --- /dev/null +++ b/po/bn_IN.po @@ -0,0 +1,35 @@ +# translation of newt.master.bn_IN.po to Bengali INDIA +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Runa Bhattacharjee , 2009. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2009-09-10 07:31-0400\n" +"Last-Translator: Runa Bhattacharjee \n" +"Language-Team: Bengali INDIA \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: bn-IN\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "ঠিক আছে" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "বাতিল" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "হ্যাঁ" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "না" diff --git a/po/bs.mo b/po/bs.mo new file mode 100644 index 0000000..8a45f39 Binary files /dev/null and b/po/bs.mo differ diff --git a/po/bs.po b/po/bs.po new file mode 100644 index 0000000..8877820 --- /dev/null +++ b/po/bs.po @@ -0,0 +1,34 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-05-06 12:39-0400\n" +"Last-Translator: Safir Šećerović \n" +"Language-Team: Bosnian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: bs\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Uredu" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Poništi" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Da" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Ne" diff --git a/po/ca.mo b/po/ca.mo new file mode 100644 index 0000000..d7c75ac Binary files /dev/null and b/po/ca.mo differ diff --git a/po/ca.po b/po/ca.po new file mode 100644 index 0000000..5e8362d --- /dev/null +++ b/po/ca.po @@ -0,0 +1,34 @@ +# Catalan translation for newt +# Copyright © 2004 Free Software Foundation, Inc. +# This file is distributed under the same licence as the newt package. +# Jordi Mallach , 2004. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-05-30 06:27-0400\n" +"Last-Translator: Jordi Mallach \n" +"Language-Team: Catalan \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ca\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "D'acord" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Cancel·la" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Sí" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "No" diff --git a/po/cs.mo b/po/cs.mo new file mode 100644 index 0000000..c74d75f Binary files /dev/null and b/po/cs.mo differ diff --git a/po/cs.po b/po/cs.po new file mode 100644 index 0000000..6e89376 --- /dev/null +++ b/po/cs.po @@ -0,0 +1,34 @@ +# Czech translations for newt +# Copyright (C) 2003 Free Software Foundation +# This file is distributed under the same license as the newt package. +# Alastair McKinstry , 2003. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-01-10 01:16-0500\n" +"Last-Translator: Miroslav Kure \n" +"Language-Team: Czech\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: cs\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Ok" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Zrušit" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Ano" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Ne" diff --git a/po/cy.mo b/po/cy.mo new file mode 100644 index 0000000..c1097b8 Binary files /dev/null and b/po/cy.mo differ diff --git a/po/cy.po b/po/cy.po new file mode 100644 index 0000000..280a4bf --- /dev/null +++ b/po/cy.po @@ -0,0 +1,33 @@ +# Newt in Welsh. +# This file is distributed under the same licence as the Newt package. +# Dafydd Harries +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-11-20 04:23-0500\n" +"Last-Translator: Dafydd Harries \n" +"Language-Team: Welsh \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: cy\n" +"Plural-Forms: nplurals=4; plural= (n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Iawn" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Diddymu" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Ie" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Na" diff --git a/po/da.mo b/po/da.mo new file mode 100644 index 0000000..0bdf614 Binary files /dev/null and b/po/da.mo differ diff --git a/po/da.po b/po/da.po new file mode 100644 index 0000000..f2ae402 --- /dev/null +++ b/po/da.po @@ -0,0 +1,35 @@ +# translation of da.po to Danish +# translation of newt to Danish +# Copyright (C) 2003 Free Software Foundation +# This file is distributed under the same license as the newt package. +# Claus Hindsgaul , 2004. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-01-12 10:54-0500\n" +"Last-Translator: Claus Hindsgaul \n" +"Language-Team: Danish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: da\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "O.k." + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Afbryd" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Ja" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Nej" diff --git a/po/de.mo b/po/de.mo new file mode 100644 index 0000000..82b1143 Binary files /dev/null and b/po/de.mo differ diff --git a/po/de.po b/po/de.po new file mode 100644 index 0000000..6905cb8 --- /dev/null +++ b/po/de.po @@ -0,0 +1,34 @@ +# German translations for newt +# Copyright (C) 2003 Free Software Foundation +# This file is distributed under the same license as the newt package. +# Alastair McKinstry , 2003. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2003-07-13 08:25-0400\n" +"Last-Translator: Alastair McKinstry \n" +"Language-Team: German \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Ok" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Abbrechen" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Ja" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Nein" diff --git a/po/dz.mo b/po/dz.mo new file mode 100644 index 0000000..c32dc9c Binary files /dev/null and b/po/dz.mo differ diff --git a/po/dz.po b/po/dz.po new file mode 100644 index 0000000..8c0bf5d --- /dev/null +++ b/po/dz.po @@ -0,0 +1,31 @@ +# Dzongkha translation of newt +# Copyright @ 2006 Free Software Foundation. +# Kinley Tshering +# +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2006-09-14 16:03+0200\n" +"PO-Revision-Date: 2006-04-05 20:34-0500\n" +"Last-Translator: kinley tshering \n" +"Language-Team: DZONGKHA \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../dialogboxes.c:43 ../dialogboxes.c:48 ../dialogboxes.c:493 +msgid "Ok" +msgstr "བཏུབ།" + +#: ../dialogboxes.c:51 +msgid "Cancel" +msgstr "ཆ་མེད་གཏང་།" + +#: ../dialogboxes.c:498 +msgid "Yes" +msgstr "ཨིན།" + +#: ../dialogboxes.c:500 +msgid "No" +msgstr "མེན།" diff --git a/po/el.mo b/po/el.mo new file mode 100644 index 0000000..d813dfc Binary files /dev/null and b/po/el.mo differ diff --git a/po/el.po b/po/el.po new file mode 100644 index 0000000..38df980 --- /dev/null +++ b/po/el.po @@ -0,0 +1,35 @@ +# translation of el.po to Greek +# translation of newt.po to Greek +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. +# Konstantinos Margaritis , 2004. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-01-08 04:10-0500\n" +"Last-Translator: Konstantinos Margaritis \n" +"Language-Team: Greek \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: el\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Εντάξει" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Ακύρωση" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Ναι" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Όχι" diff --git a/po/eo.mo b/po/eo.mo new file mode 100644 index 0000000..09de6ae Binary files /dev/null and b/po/eo.mo differ diff --git a/po/eo.po b/po/eo.po new file mode 100644 index 0000000..11674ca --- /dev/null +++ b/po/eo.po @@ -0,0 +1,36 @@ +# translation to Esperanto +# Copyright (C) 2006 Free Software Foundation, Inc. +# This file is distributed under the same license as the newt package. +# Serge Leblanc , 2006. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2006-04-18 09:00-0400\n" +"Last-Translator: Serge Leblanc \n" +"Language-Team: Esperanto \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: eo\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" +"X-Poedit-Language: Esperanto\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Akceptu" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Nuligu" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Jes" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Ne" diff --git a/po/es.mo b/po/es.mo new file mode 100644 index 0000000..2580717 Binary files /dev/null and b/po/es.mo differ diff --git a/po/es.po b/po/es.po new file mode 100644 index 0000000..e937da5 --- /dev/null +++ b/po/es.po @@ -0,0 +1,34 @@ +# Spanish translations for newt +# Copyright (C) 2003 Free Software Foundation +# This file is distributed under the same license as the newt package. +# Alastair McKinstry , 2003 +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2003-07-13 08:25-0400\n" +"Last-Translator: Alastair McKinstry \n" +"Language-Team: Spanish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: es\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Aceptar" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Cancelar" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "S�" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "No" diff --git a/po/et.mo b/po/et.mo new file mode 100644 index 0000000..283d148 Binary files /dev/null and b/po/et.mo differ diff --git a/po/et.po b/po/et.po new file mode 100644 index 0000000..55fe994 --- /dev/null +++ b/po/et.po @@ -0,0 +1,36 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2005-06-05 12:28-0400\n" +"Last-Translator: Siim Põder \n" +"Language-Team: ESTONIAN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: et\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" +"X-Poedit-Country: ESTONIA\n" +"X-Poedit-Language: Estonian\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Olgu" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Loobu" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Jah" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Ei" diff --git a/po/eu.mo b/po/eu.mo new file mode 100644 index 0000000..fc44ced Binary files /dev/null and b/po/eu.mo differ diff --git a/po/eu.po b/po/eu.po new file mode 100644 index 0000000..b6dbe86 --- /dev/null +++ b/po/eu.po @@ -0,0 +1,37 @@ +# Vasco translation of newt_po. +# Copyright (C) 2004 THE newt_po'S COPYRIGHT HOLDER +# This file is distributed under the same license as the newt_po package. +# Mikel Olasagasti , 2004. +#, fuzzy +# +# +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-04-02 01:59-0500\n" +"Last-Translator: Mikel Olasagasti \n" +"Language-Team: Vasco \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: eu\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Ados" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Utzi" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Bai" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Ez" diff --git a/po/fa.mo b/po/fa.mo new file mode 100644 index 0000000..e769c1c Binary files /dev/null and b/po/fa.mo differ diff --git a/po/fa.po b/po/fa.po new file mode 100644 index 0000000..6f85575 --- /dev/null +++ b/po/fa.po @@ -0,0 +1,36 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2010-08-19 09:32-0400\n" +"Last-Translator: Mostafa \n" +"Language-Team: Persian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: fa\n" +"Plural-Forms: nplurals=1; plural=0\n" +"X-Generator: Zanata 3.8.2\n" +"X-Poedit-Country: Iran\n" +"X-Poedit-Language: Persian\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "تایید" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "لغو" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "بله" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "نه" diff --git a/po/fi.mo b/po/fi.mo new file mode 100644 index 0000000..cc581c7 Binary files /dev/null and b/po/fi.mo differ diff --git a/po/fi.po b/po/fi.po new file mode 100644 index 0000000..67464da --- /dev/null +++ b/po/fi.po @@ -0,0 +1,33 @@ +# Copyright (C) 2004 Redhat. +# This file is distributed under the same license as the newt package. +# Tommi Vainikainen, 2004. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-01-09 03:34-0500\n" +"Last-Translator: Tommi Vainikainen \n" +"Language-Team: Finnish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: fi\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "OK" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Peru" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Kyllä" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Ei" diff --git a/po/fr.mo b/po/fr.mo new file mode 100644 index 0000000..3fe52de Binary files /dev/null and b/po/fr.mo differ diff --git a/po/fr.po b/po/fr.po new file mode 100644 index 0000000..b1102f0 --- /dev/null +++ b/po/fr.po @@ -0,0 +1,34 @@ +# French translations for newt +# Copyright (C) 2003 Free Software Foundation +# This file is distributed under the same license as the newt package. +# Alastair McKinstry , 2003. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2003-07-19 06:25-0400\n" +"Last-Translator: Christian Perrier\n" +"Language-Team: Debian French \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: fr\n" +"Plural-Forms: nplurals=2; plural=(n > 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Ok" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Annuler" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Oui" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Non" diff --git a/po/ga.mo b/po/ga.mo new file mode 100644 index 0000000..d7d7880 Binary files /dev/null and b/po/ga.mo differ diff --git a/po/ga.po b/po/ga.po new file mode 100644 index 0000000..30c39fb --- /dev/null +++ b/po/ga.po @@ -0,0 +1,34 @@ +# Irish translations for newt +# Copyright (C) 2003,2004 Free Software Foundation +# This file is distributed under the same license as the newt package. +# Alastair McKinstry , 2003. +msgid "" +msgstr "" +"Project-Id-Version: newt 0.51.4\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2006-09-14 16:03+0200\n" +"PO-Revision-Date: 2004-01-10 07:25-0500\n" +"Last-Translator: Alastair McKinstry \n" +"Language-Team: Irish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ga\n" +"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Ceart go Leor" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Ceallaigh" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Tá" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Níl" diff --git a/po/gl.mo b/po/gl.mo new file mode 100644 index 0000000..da93b7a Binary files /dev/null and b/po/gl.mo differ diff --git a/po/gl.po b/po/gl.po new file mode 100644 index 0000000..9efb27a --- /dev/null +++ b/po/gl.po @@ -0,0 +1,35 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the newt package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-11-20 11:21-0500\n" +"Last-Translator: Jacobo Tarrio \n" +"Language-Team: Galician \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: gl\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Aceptar" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Cancelar" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Si" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Non" diff --git a/po/gu.mo b/po/gu.mo new file mode 100644 index 0000000..6afb125 Binary files /dev/null and b/po/gu.mo differ diff --git a/po/gu.po b/po/gu.po new file mode 100644 index 0000000..d890cef --- /dev/null +++ b/po/gu.po @@ -0,0 +1,35 @@ +# translation of newt.po to Gujarati +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Sweta Kothari , 2009. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2009-09-10 07:21-0400\n" +"Last-Translator: Sweta Kothari \n" +"Language-Team: Gujarati\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: gu\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "બરાબર" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "રદ કરો" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "હા" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "ના" diff --git a/po/he.mo b/po/he.mo new file mode 100644 index 0000000..e3a6ee8 Binary files /dev/null and b/po/he.mo differ diff --git a/po/he.po b/po/he.po new file mode 100644 index 0000000..4137e9b --- /dev/null +++ b/po/he.po @@ -0,0 +1,36 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-04-19 06:37-0400\n" +"Last-Translator: Lior Kaplan \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: he\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +# FIXME: Ugh. DO SOMETHING ABOUT THESE HARD-CODED CONSTANTS +# THEY WILL BREAK WITH TRANSLATION +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "OK" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "ביטול" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "כן" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "לא" diff --git a/po/hi.mo b/po/hi.mo new file mode 100644 index 0000000..bae9f7b Binary files /dev/null and b/po/hi.mo differ diff --git a/po/hi.po b/po/hi.po new file mode 100644 index 0000000..1b80e4e --- /dev/null +++ b/po/hi.po @@ -0,0 +1,36 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-11-20 01:53-0500\n" +"Last-Translator: Ravishankar Shrivastava \n" +"Language-Team: Ravishankar Shrivastava \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: hi\n" +"Plural-Forms: 2\n" +"X-Generator: Zanata 3.8.2\n" +"X-Poedit-Country: INDIA\n" +"X-Poedit-Language: Hindi\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "à à@àU" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "रदàMद" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "हाàA" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "नहà@àB" diff --git a/po/hr.mo b/po/hr.mo new file mode 100644 index 0000000..4a877c9 Binary files /dev/null and b/po/hr.mo differ diff --git a/po/hr.po b/po/hr.po new file mode 100644 index 0000000..3f24010 --- /dev/null +++ b/po/hr.po @@ -0,0 +1,35 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the newt package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-07-25 08:52-0400\n" +"Last-Translator: Krunoslav Gernhard \n" +"Language-Team: Croatian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: hr\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "U redu" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Otkaži" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Da" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Ne" diff --git a/po/hu.mo b/po/hu.mo new file mode 100644 index 0000000..49a9387 Binary files /dev/null and b/po/hu.mo differ diff --git a/po/hu.po b/po/hu.po new file mode 100644 index 0000000..65af195 --- /dev/null +++ b/po/hu.po @@ -0,0 +1,38 @@ +# Hungarian translation of newt. +# Copyright (C) 2003 THE RedHat. +# This file is distributed under the same license as the newt package. +# VERÓK István , 2003. +# Translators, please read /usr/share/doc/po-debconf/README-trans +# or http://www.debian.org/intl/l10n/po-debconf/README-trans +# +# +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-01-09 02:35-0500\n" +"Last-Translator: VERÓK István \n" +"Language-Team: Hungarian\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: hu\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Ok" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Mégsem" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Igen" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Nem" diff --git a/po/ia.mo b/po/ia.mo new file mode 100644 index 0000000..30caee9 Binary files /dev/null and b/po/ia.mo differ diff --git a/po/ia.po b/po/ia.po new file mode 100644 index 0000000..f4e2572 --- /dev/null +++ b/po/ia.po @@ -0,0 +1,36 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Nik Kalach , 2012. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2012-09-26 07:04-0400\n" +"Last-Translator: Nik Kalach \n" +"Language-Team: Interlingua \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ia\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Ok" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Annullar" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Si" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "No" diff --git a/po/id.mo b/po/id.mo new file mode 100644 index 0000000..6e48833 Binary files /dev/null and b/po/id.mo differ diff --git a/po/id.po b/po/id.po new file mode 100644 index 0000000..59e8537 --- /dev/null +++ b/po/id.po @@ -0,0 +1,36 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-04-10 02:03-0400\n" +"Last-Translator: I Gede Wijaya S \n" +"Language-Team: Debian Indonesia \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: id\n" +"Plural-Forms: nplurals=1; plural=0\n" +"X-Generator: Zanata 3.8.2\n" + +# FIXME: Ugh. DO SOMETHING ABOUT THESE HARD-CODED CONSTANTS +# THEY WILL BREAK WITH TRANSLATION +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Ok" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Batal" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Ya" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Tidak" diff --git a/po/it.mo b/po/it.mo new file mode 100644 index 0000000..dabf30a Binary files /dev/null and b/po/it.mo differ diff --git a/po/it.po b/po/it.po new file mode 100644 index 0000000..6d66035 --- /dev/null +++ b/po/it.po @@ -0,0 +1,34 @@ +# Italian translations for newt +# Copyright (C) 2003 Free Software Foundation +# This file is distributed under the same license as the newt package. +# Giuseppe Sacco , 2004. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2003-07-19 06:25-0400\n" +"Last-Translator: Giuseppe Sacco \n" +"Language-Team: Debian Italian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: it\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Ok" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Annulla" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Sì" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "No" diff --git a/po/ja.mo b/po/ja.mo new file mode 100644 index 0000000..54ce761 Binary files /dev/null and b/po/ja.mo differ diff --git a/po/ja.po b/po/ja.po new file mode 100644 index 0000000..aef7b79 --- /dev/null +++ b/po/ja.po @@ -0,0 +1,34 @@ +# Japanese translations for newt +# Copyright (C) 2003,2004 Free Software Foundation +# This file is distributed under the same license as the newt package. +# Alastair McKinstry , 2003. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2003-07-18 07:02-0400\n" +"Last-Translator: Tomohiro KUBOTA \n" +"Language-Team: Japanese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ja\n" +"Plural-Forms: nplurals=1; plural=0\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "了解" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "取消" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "はい" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "いいえ" diff --git a/po/ka.mo b/po/ka.mo new file mode 100644 index 0000000..61bfe9e Binary files /dev/null and b/po/ka.mo differ diff --git a/po/ka.po b/po/ka.po new file mode 100644 index 0000000..0507ce7 --- /dev/null +++ b/po/ka.po @@ -0,0 +1,36 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# George Machitidze , 2013 +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2013-11-20 04:53-0500\n" +"Last-Translator: George Machitidze \n" +"Language-Team: Georgian (http://www.transifex.com/projects/p/newt/language/ka/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ka\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Ok" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "გაუქმება" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "კი" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "არა" diff --git a/po/km.mo b/po/km.mo new file mode 100644 index 0000000..4078959 Binary files /dev/null and b/po/km.mo differ diff --git a/po/km.po b/po/km.po new file mode 100644 index 0000000..59ebde5 --- /dev/null +++ b/po/km.po @@ -0,0 +1,35 @@ +# translation of newt_newt_po_km.po to Khmer +# Hok Kakada , 2006. +# auk piseth , 2006. +# Khoem Sokhem , 2006. +# Leang Chumsoben , 2006. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2006-03-27 04:11-0500\n" +"Last-Translator: Khoem Sokhem \n" +"Language-Team: Khmer \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: km\n" +"Plural-Forms: nplurals=1; plural=0\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "យល់ព្រម" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "បោះបង់" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "បាទ/ចាស" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "ទេ" diff --git a/po/kn.mo b/po/kn.mo new file mode 100644 index 0000000..b9b3b9e Binary files /dev/null and b/po/kn.mo differ diff --git a/po/kn.po b/po/kn.po new file mode 100644 index 0000000..6a6e97b --- /dev/null +++ b/po/kn.po @@ -0,0 +1,35 @@ +# translation of newt.master.newt.po to Kannada +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Shankar Prasad , 2009. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2009-09-10 08:02-0400\n" +"Last-Translator: Shankar Prasad \n" +"Language-Team: Kannada \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: kn\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "ಸರಿ" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "ರದ್ದುಗೊಳಿಸು" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "ಹೌದು" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "ಇಲ್ಲ" diff --git a/po/ko.mo b/po/ko.mo new file mode 100644 index 0000000..f1a1b3a Binary files /dev/null and b/po/ko.mo differ diff --git a/po/ko.po b/po/ko.po new file mode 100644 index 0000000..9f469c5 --- /dev/null +++ b/po/ko.po @@ -0,0 +1,31 @@ +# Changwoo Ryu , 2004. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-04-04 03:10-0400\n" +"Last-Translator: Changwoo Ryu \n" +"Language-Team: Korean \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ko\n" +"Plural-Forms: nplurals=1; plural=0\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "확인" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "취소" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "예" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "아니오" diff --git a/po/ku.mo b/po/ku.mo new file mode 100644 index 0000000..28193f6 Binary files /dev/null and b/po/ku.mo differ diff --git a/po/ku.po b/po/ku.po new file mode 100644 index 0000000..5929c6b --- /dev/null +++ b/po/ku.po @@ -0,0 +1,33 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2006-09-14 16:03+0200\n" +"PO-Revision-Date: 2005-10-20 20:44+0100\n" +"Last-Translator: Erdal Ronahî \n" +"Language-Team: KURDISH \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Kurdish\n" + +#: ../dialogboxes.c:43 ../dialogboxes.c:48 ../dialogboxes.c:493 +msgid "Ok" +msgstr "Temam" + +#: ../dialogboxes.c:51 +msgid "Cancel" +msgstr "Betal" + +#: ../dialogboxes.c:498 +msgid "Yes" +msgstr "Erê" + +#: ../dialogboxes.c:500 +msgid "No" +msgstr "Na" diff --git a/po/lt.mo b/po/lt.mo new file mode 100644 index 0000000..b606502 Binary files /dev/null and b/po/lt.mo differ diff --git a/po/lt.po b/po/lt.po new file mode 100644 index 0000000..13bbb7c --- /dev/null +++ b/po/lt.po @@ -0,0 +1,35 @@ +# Lithuanian translations for newt +# Copyright (C) 2003 Free Software Foundation +# This file is distributed under the same license as the newt package. +# Kęstutis Biliūnas , 2004. +# +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-01-13 03:07-0500\n" +"Last-Translator: Kęstutis Biliūnas \n" +"Language-Team: Lithuanian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: lt\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 or n%100>=20) ? 1 : 2)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Gerai" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Atšaukti" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Taip" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Ne" diff --git a/po/lv.mo b/po/lv.mo new file mode 100644 index 0000000..c7813b2 Binary files /dev/null and b/po/lv.mo differ diff --git a/po/lv.po b/po/lv.po new file mode 100644 index 0000000..dcc3489 --- /dev/null +++ b/po/lv.po @@ -0,0 +1,36 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Rūdolfs Mazurs , 2012. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2012-05-26 03:48-0400\n" +"Last-Translator: Rūdolfs Mazurs \n" +"Language-Team: Latvian (http://www.transifex.com/projects/p/fedora/language/lv/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: lv\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Labi" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Atcelt" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Jā" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Nē" diff --git a/po/mg.mo b/po/mg.mo new file mode 100644 index 0000000..0bdce3f Binary files /dev/null and b/po/mg.mo differ diff --git a/po/mg.po b/po/mg.po new file mode 100644 index 0000000..7da5a43 --- /dev/null +++ b/po/mg.po @@ -0,0 +1,32 @@ +# translation of newt_mg.po to +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER, 2004. +# +msgid "" +msgstr "" +"Project-Id-Version: newt_mg\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2006-09-14 16:03+0200\n" +"PO-Revision-Date: 2004-11-21 17:33+0100\n" +"Last-Translator: Jaonary Rabarisoa \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.9.1\n" + +#: ../dialogboxes.c:43 ../dialogboxes.c:48 ../dialogboxes.c:493 +msgid "Ok" +msgstr "Ekena" + +#: ../dialogboxes.c:51 +msgid "Cancel" +msgstr "Ajanony" + +#: ../dialogboxes.c:498 +msgid "Yes" +msgstr "Eny" + +#: ../dialogboxes.c:500 +msgid "No" +msgstr "Tsia" diff --git a/po/mk.mo b/po/mk.mo new file mode 100644 index 0000000..ed147a0 Binary files /dev/null and b/po/mk.mo differ diff --git a/po/mk.po b/po/mk.po new file mode 100644 index 0000000..5ed852c --- /dev/null +++ b/po/mk.po @@ -0,0 +1,32 @@ +# translation of newt_newt_po_mk.po to +# Georgi Stanojevski , 2004. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-10-09 06:18-0400\n" +"Last-Translator: Georgi Stanojevski \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: mk\n" +"Plural-Forms: nplurals=2; plural= n==1 || n%10==1 ? 0 : 1\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Во ред" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Откажи" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Да" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Не" diff --git a/po/ml.mo b/po/ml.mo new file mode 100644 index 0000000..41effd8 Binary files /dev/null and b/po/ml.mo differ diff --git a/po/ml.po b/po/ml.po new file mode 100644 index 0000000..82bd7da --- /dev/null +++ b/po/ml.po @@ -0,0 +1,34 @@ +# translation of newt.master.newt.ml.po to +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the newt package. +# ANI PETER , 2009 +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2009-09-10 06:41-0400\n" +"Last-Translator: ANI PETER \n" +"Language-Team: Swathantra Malayalam Computing|സ്വതന്ത്ര മലയാളം കമ്പ്യൂട്ടിങ് \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ml\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "ശരി" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "റദ്ദാക്കുക" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "ഉവ്വു്" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "ഇല്ല" diff --git a/po/mr.mo b/po/mr.mo new file mode 100644 index 0000000..075f820 Binary files /dev/null and b/po/mr.mo differ diff --git a/po/mr.po b/po/mr.po new file mode 100644 index 0000000..d53d1cf --- /dev/null +++ b/po/mr.po @@ -0,0 +1,34 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: \n" +"Last-Translator: Priti Patil \n" +"Language-Team: Marathi, janabhaaratii, C-DAC, Mumbai, India \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: mr\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "ठीक" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "रद्द" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "हो" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "नाही" diff --git a/po/ms.mo b/po/ms.mo new file mode 100644 index 0000000..4239df8 Binary files /dev/null and b/po/ms.mo differ diff --git a/po/ms.po b/po/ms.po new file mode 100644 index 0000000..1c07159 --- /dev/null +++ b/po/ms.po @@ -0,0 +1,34 @@ +# newt Bahasa Melayu (Malay) (ms) +# Copyright (C) Fedora Project +# This file is distributed under the same license as the newt package. +# Sharuzzaman Ahmat Raslan , 2008. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2008-09-25 11:31-0400\n" +"Last-Translator: Sharuzzaman Ahmat Raslan \n" +"Language-Team: Malay \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ms\n" +"Plural-Forms: nplurals=1; plural=0\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Ok" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Batal" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Ya" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Tidak" diff --git a/po/nb.mo b/po/nb.mo new file mode 100644 index 0000000..e7b22dc Binary files /dev/null and b/po/nb.mo differ diff --git a/po/nb.po b/po/nb.po new file mode 100644 index 0000000..1860284 --- /dev/null +++ b/po/nb.po @@ -0,0 +1,34 @@ +# Norwegian translations for newt +# Copyright (C) 2003 Free Software Foundation +# This file is distributed under the same license as the newt package. +# Alastair McKinstry , 2003 +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2003-07-13 08:25-0400\n" +"Last-Translator: Alastair McKinstry \n" +"Language-Team: Norwegian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: nb\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Ok" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Avbryt" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Ja" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Nei" diff --git a/po/nds.mo b/po/nds.mo new file mode 100644 index 0000000..8a13a81 Binary files /dev/null and b/po/nds.mo differ diff --git a/po/nds.po b/po/nds.po new file mode 100644 index 0000000..f4394d4 --- /dev/null +++ b/po/nds.po @@ -0,0 +1,34 @@ +# Low German translations for newt +# Copyright (C) 2003 Free Software Foundation +# This file is distributed under the same license as the newt package. +# Nils-Christoph Fiedler , 2010. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2010-12-03 09:30-0500\n" +"Last-Translator: Nils-Christoph Fiedler \n" +"Language-Team: Fedora Low German \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: nds\n" +"Plural-Forms: nplurals=1; plural=0\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Ok" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Avbreken" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Jau" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Nee" diff --git a/po/ne.mo b/po/ne.mo new file mode 100644 index 0000000..0a762fe Binary files /dev/null and b/po/ne.mo differ diff --git a/po/ne.po b/po/ne.po new file mode 100644 index 0000000..c836594 --- /dev/null +++ b/po/ne.po @@ -0,0 +1,32 @@ +# translation of newt_newt_po.po to Nepali +# Shyam Krishna Bal , 2006. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2006-05-21 02:26-0400\n" +"Last-Translator: Shyam Krishna Bal \n" +"Language-Team: Nepali \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ne\n" +"Plural-Forms: nplurals=2;plural=(n!=1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "ठीक छ" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "रद्द गर्नुहोस्" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "हो" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "होइन" diff --git a/po/newt.pot b/po/newt.pot new file mode 100644 index 0000000..01d03ab --- /dev/null +++ b/po/newt.pot @@ -0,0 +1,34 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the newt package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "" diff --git a/po/nl.mo b/po/nl.mo new file mode 100644 index 0000000..286d1bc Binary files /dev/null and b/po/nl.mo differ diff --git a/po/nl.po b/po/nl.po new file mode 100644 index 0000000..d9aa515 --- /dev/null +++ b/po/nl.po @@ -0,0 +1,34 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-01-09 05:49-0500\n" +"Last-Translator: Bart Cornelis \n" +"Language-Team: debian-l10n-dutch \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: nl\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Ok" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Annuleren" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Ja" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Nee" diff --git a/po/nn.mo b/po/nn.mo new file mode 100644 index 0000000..c8aff93 Binary files /dev/null and b/po/nn.mo differ diff --git a/po/nn.po b/po/nn.po new file mode 100644 index 0000000..d6bb5fd --- /dev/null +++ b/po/nn.po @@ -0,0 +1,34 @@ +# Norwegian translations for newt +# Copyright (C) 2003 Free Software Foundation +# This file is distributed under the same license as the newt package. +# Alastair McKinstry , 2003 +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2003-07-13 08:25-0400\n" +"Last-Translator: Alastair McKinstry \n" +"Language-Team: Irish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: nn\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Ok" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Avbryt" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Ja" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Nei" diff --git a/po/pa.mo b/po/pa.mo new file mode 100644 index 0000000..2fc8759 Binary files /dev/null and b/po/pa.mo differ diff --git a/po/pa.po b/po/pa.po new file mode 100644 index 0000000..442f075 --- /dev/null +++ b/po/pa.po @@ -0,0 +1,36 @@ +# translation of newt_newt_po.po to Panjabi +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. +# Amanpreet Singh Alam[ਆਲਮ] , 2005. +# Amanpreet Singh Alam[ਆਲਮ] , 2005. +# Amanpreet Singh Alam[ਆਲਮ] , 2005. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2005-03-27 11:54-0500\n" +"Last-Translator: Amanpreet Singh Alam[ਆਲਮ] \n" +"Language-Team: Panjabi \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pa\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "ਠੀਕ ਹੈ" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "ਰੱਦ ਕਰੋ" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "ਹਾਂ" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "ਨਹੀਂ" diff --git a/po/pl.mo b/po/pl.mo new file mode 100644 index 0000000..06e6951 Binary files /dev/null and b/po/pl.mo differ diff --git a/po/pl.po b/po/pl.po new file mode 100644 index 0000000..02e09ec --- /dev/null +++ b/po/pl.po @@ -0,0 +1,33 @@ +# translation of pl.po to Polish +# Bartosz Fenski , 2004. +# Piotr Drąg , 2008. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2008-02-19 04:14-0500\n" +"Last-Translator: Piotr Drąg \n" +"Language-Team: Polish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pl\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "OK" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Anuluj" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Tak" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Nie" diff --git a/po/pt.mo b/po/pt.mo new file mode 100644 index 0000000..0555736 Binary files /dev/null and b/po/pt.mo differ diff --git a/po/pt.po b/po/pt.po new file mode 100644 index 0000000..e9b736e --- /dev/null +++ b/po/pt.po @@ -0,0 +1,34 @@ +# Portuguese newt translation. +# Copyright (C) 2003 Alastair McKinstry <mckinstry@debian.org> +# This file is distributed under the same license as the newt package. +# Miguel Figueiredo <elmig@debianpt.org>, 2004 +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-03-31 04:19-0500\n" +"Last-Translator: Miguel Figueiredo <elmig@debianpt.org>\n" +"Language-Team: Portuguese <traduz@debianpt.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pt\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Ok" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Cancelar" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Sim" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Não" diff --git a/po/pt_BR.mo b/po/pt_BR.mo new file mode 100644 index 0000000..3846606 Binary files /dev/null and b/po/pt_BR.mo differ diff --git a/po/pt_BR.po b/po/pt_BR.po new file mode 100644 index 0000000..1de9289 --- /dev/null +++ b/po/pt_BR.po @@ -0,0 +1,34 @@ +# Brazilian Portuguese translations for newt +# Copyright (C) 2003 Free Software Foundation +# This file is distributed under the same license as the newt package. +# André Luís Lopes , 2003. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2003-07-13 02:37-0400\n" +"Last-Translator: André Luís Lopes \n" +"Language-Team: Debian-BR Project \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pt-BR\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Ok" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Cancelar" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Sim" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Não" diff --git a/po/ro.mo b/po/ro.mo new file mode 100644 index 0000000..822aca7 Binary files /dev/null and b/po/ro.mo differ diff --git a/po/ro.po b/po/ro.po new file mode 100644 index 0000000..9451a28 --- /dev/null +++ b/po/ro.po @@ -0,0 +1,35 @@ +# translation of newt_newt_ro.po to French +# Romanian translation +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. +# Eddy Petrisor , 2004. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-10-06 01:07-0400\n" +"Last-Translator: Eddy Petrisor \n" +"Language-Team: Romanian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ro\n" +"Plural-Forms: Plural-Forms: nplurals=2; plural=n>1;\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Ok" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Anulează" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Da" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Nu" diff --git a/po/ru.mo b/po/ru.mo new file mode 100644 index 0000000..e33581a Binary files /dev/null and b/po/ru.mo differ diff --git a/po/ru.po b/po/ru.po new file mode 100644 index 0000000..795ed68 --- /dev/null +++ b/po/ru.po @@ -0,0 +1,34 @@ +# translation of ru.po to Russian +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. +# Nikolai Prokoschenko , 2004. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-01-09 09:16-0500\n" +"Last-Translator: Nikolai Prokoschenko \n" +"Language-Team: Russian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ru\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Ok" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Отмена" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Да" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Нет" diff --git a/po/sk.mo b/po/sk.mo new file mode 100644 index 0000000..050f97e Binary files /dev/null and b/po/sk.mo differ diff --git a/po/sk.po b/po/sk.po new file mode 100644 index 0000000..86c986f --- /dev/null +++ b/po/sk.po @@ -0,0 +1,31 @@ +# newt - Slovak translation +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-04-25 05:13-0400\n" +"Last-Translator: Peter KLFMANiK Mann \n" +"Language-Team: Slovak \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: sk\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "OK" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Zrušiť" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Áno" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Nie" diff --git a/po/sl.mo b/po/sl.mo new file mode 100644 index 0000000..d7e3105 Binary files /dev/null and b/po/sl.mo differ diff --git a/po/sl.po b/po/sl.po new file mode 100644 index 0000000..947414f --- /dev/null +++ b/po/sl.po @@ -0,0 +1,34 @@ +# Slovenian translations for newt +# Copyright (C) 2003,2004 Free Software Foundation +# This file is distributed under the same license as the newt package. +# Alastair McKinstry , 2003. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2007-01-03 10:23-0500\n" +"Last-Translator: Matej Kovačič \n" +"Language-Team: Slovenian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: sl\n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n%100==4 ? 3 : 0)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "V redu" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Prekliči" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Da" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Ne" diff --git a/po/sq.mo b/po/sq.mo new file mode 100644 index 0000000..9c6638c Binary files /dev/null and b/po/sq.mo differ diff --git a/po/sq.po b/po/sq.po new file mode 100644 index 0000000..f876efd --- /dev/null +++ b/po/sq.po @@ -0,0 +1,36 @@ +# Albanian translation of newt. +# Copyright (C) 2004 THE newt'S COPYRIGHT HOLDER +# This file is distributed under the same license as the newt package. +# Elian Myftiu , 2004. +#, fuzzy +# +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-11-17 08:28-0500\n" +"Last-Translator: Elian Myftiu \n" +"Language-Team: Albanian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: sq\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Ok" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Anullo" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Po" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Jo" diff --git a/po/sr.mo b/po/sr.mo new file mode 100644 index 0000000..c775d96 Binary files /dev/null and b/po/sr.mo differ diff --git a/po/sr.po b/po/sr.po new file mode 100644 index 0000000..f5c8b82 --- /dev/null +++ b/po/sr.po @@ -0,0 +1,36 @@ +# translation of sr.po to Serbian +# Serbian translations for newt +# Copyright (C) 2006 Red Hat, Inc. +# This file is distributed under the same license as the newt package. +# +# Nikola Pajtić , 2008. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2008-03-13 09:53-0400\n" +"Last-Translator: Nikola Pajtić \n" +"Language-Team: Serbian (sr) \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: sr\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "У реду" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Откажи" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Да" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Не" diff --git a/po/sr@latin.mo b/po/sr@latin.mo new file mode 100644 index 0000000..fe78448 Binary files /dev/null and b/po/sr@latin.mo differ diff --git a/po/sr@latin.po b/po/sr@latin.po new file mode 100644 index 0000000..53e5657 --- /dev/null +++ b/po/sr@latin.po @@ -0,0 +1,36 @@ +# translation of sr.po to Serbian +# Serbian(Latin) translations for newt +# Copyright (C) 2006 Red Hat, Inc. +# This file is distributed under the same license as the newt package. +# +# Nikola Pajtić , 2008. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2008-03-13 09:53-0400\n" +"Last-Translator: Nikola Pajtić \n" +"Language-Team: Serbian (sr) \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: sr@latin\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "U redu" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Otkaži" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Da" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Ne" diff --git a/po/sv.mo b/po/sv.mo new file mode 100644 index 0000000..966637d Binary files /dev/null and b/po/sv.mo differ diff --git a/po/sv.po b/po/sv.po new file mode 100644 index 0000000..c251dea --- /dev/null +++ b/po/sv.po @@ -0,0 +1,34 @@ +# Swedish translations for newt +# Copyright (C) 2003 Free Software Foundation +# This file is distributed under the same license as the newt package. +# Alastair McKinstry , 2003 +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2003-07-13 08:25-0400\n" +"Last-Translator: Alastair McKinstry \n" +"Language-Team: Swedish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: sv\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Ok" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Avbryt" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Ja" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Nej" diff --git a/po/ta.mo b/po/ta.mo new file mode 100644 index 0000000..62cd5c2 Binary files /dev/null and b/po/ta.mo differ diff --git a/po/ta.po b/po/ta.po new file mode 100644 index 0000000..5901405 --- /dev/null +++ b/po/ta.po @@ -0,0 +1,35 @@ +# package name newt +# translation of ta.po to Tamil +# Tamil messages for debian-installer. +# Copyright (C) 2003 Software in the Public Interest, Inc. +# Senthil Kumar B ,2006 +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2006-12-18 04:15-0500\n" +"Last-Translator: Senthil Kumar B \n" +"Language-Team: Tamil \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ta\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "சரி" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "இரத்து செய்" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "ஆம்" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "இல்லை" diff --git a/po/te.mo b/po/te.mo new file mode 100644 index 0000000..344fe94 Binary files /dev/null and b/po/te.mo differ diff --git a/po/te.po b/po/te.po new file mode 100644 index 0000000..7a6d5d3 --- /dev/null +++ b/po/te.po @@ -0,0 +1,35 @@ +# translation of newt.master.newt.po to Telugu +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Krishna Babu K , 2009. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2009-09-10 08:05-0400\n" +"Last-Translator: Krishna Babu K \n" +"Language-Team: Telugu \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: te\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "సరే" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "రద్దుచేయి" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "అవును" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "కాదు/వద్దు" diff --git a/po/tg.mo b/po/tg.mo new file mode 100644 index 0000000..730ab79 Binary files /dev/null and b/po/tg.mo differ diff --git a/po/tg.po b/po/tg.po new file mode 100644 index 0000000..9ee7ed6 --- /dev/null +++ b/po/tg.po @@ -0,0 +1,35 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2011-12-09 04:57-0500\n" +"Last-Translator: Victor Ibragimov \n" +"Language-Team: Tajik (http://www.transifex.com/projects/p/fedora/language/tg/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: tg\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Хуб" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Бекор кардан" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Ҳа" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Не" diff --git a/po/th.mo b/po/th.mo new file mode 100644 index 0000000..53ed2fe Binary files /dev/null and b/po/th.mo differ diff --git a/po/th.po b/po/th.po new file mode 100644 index 0000000..7e35d50 --- /dev/null +++ b/po/th.po @@ -0,0 +1,34 @@ +# Thai translation of newt. +# Copyright (C) 2006 Software in the Public Interest, Inc. +# This file is distributed under the same license as debian-installer. +# Theppitak Karoonboonyanan , 2006. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2006-05-14 10:45-0400\n" +"Last-Translator: Theppitak Karoonboonyanan \n" +"Language-Team: Thai \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: th\n" +"Plural-Forms: nplurals=1; plural=0\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "ตกลง" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "ยกเลิก" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "ใช่" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "ไม่" diff --git a/po/tl.mo b/po/tl.mo new file mode 100644 index 0000000..04a3052 Binary files /dev/null and b/po/tl.mo differ diff --git a/po/tl.po b/po/tl.po new file mode 100644 index 0000000..844ac1e --- /dev/null +++ b/po/tl.po @@ -0,0 +1,33 @@ +# Tagalog translation of newt. +# Copyright (C) 2005 Eric Pareja +# This file is distributed under the same license as the newt package. +# Eric Pareja , 2005 +# +# +msgid "" +msgstr "" +"Project-Id-Version: newt 0.51.6-21\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2006-09-14 16:03+0200\n" +"PO-Revision-Date: 2005-01-06 17:34+0800\n" +"Last-Translator: Eric Pareja \n" +"Language-Team: Tagalog \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../dialogboxes.c:43 ../dialogboxes.c:48 ../dialogboxes.c:493 +msgid "Ok" +msgstr "OK" + +#: ../dialogboxes.c:51 +msgid "Cancel" +msgstr "Kanselahin" + +#: ../dialogboxes.c:498 +msgid "Yes" +msgstr "Oo" + +#: ../dialogboxes.c:500 +msgid "No" +msgstr "Hindi" diff --git a/po/tr.mo b/po/tr.mo new file mode 100644 index 0000000..461cdfc Binary files /dev/null and b/po/tr.mo differ diff --git a/po/tr.po b/po/tr.po new file mode 100644 index 0000000..2fbfcf4 --- /dev/null +++ b/po/tr.po @@ -0,0 +1,33 @@ +# Turkish translation of newt. +# This file is distributed under the same license as the newt package. +# Çağatay Tengiz , 2004. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-03-20 08:46-0500\n" +"Last-Translator: Çağatay Tengiz \n" +"Language-Team: Turkish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: tr\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Tamam" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "İptal" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Evet" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Hayır" diff --git a/po/uk.mo b/po/uk.mo new file mode 100644 index 0000000..37290c6 Binary files /dev/null and b/po/uk.mo differ diff --git a/po/uk.po b/po/uk.po new file mode 100644 index 0000000..e860c17 --- /dev/null +++ b/po/uk.po @@ -0,0 +1,34 @@ +# translation of uk.po to Ukrainian +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. +# Eugeniy Meshcheryakov , 2004. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-02-12 12:38-0500\n" +"Last-Translator: Eugeniy Meshcheryakov \n" +"Language-Team: Ukrainian\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uk\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Гаразд" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Скасувати" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Так" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Ні" diff --git a/po/vi.mo b/po/vi.mo new file mode 100644 index 0000000..d826701 Binary files /dev/null and b/po/vi.mo differ diff --git a/po/vi.po b/po/vi.po new file mode 100644 index 0000000..ab97543 --- /dev/null +++ b/po/vi.po @@ -0,0 +1,34 @@ +# Vietnamese translation for newt_newt. +# Copyright © 2005 Free Software Foundation, Inc. +# This file is distributed under the same license as the newt_newt package. +# Clytie Siddall , 2005. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: \n" +"Last-Translator: Clytie Siddall \n" +"Language-Team: Vietnamese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: vi\n" +"Plural-Forms: nplurals=1; plural=0\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "Được" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "Thôi" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "Có" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "Không" diff --git a/po/wo.mo b/po/wo.mo new file mode 100644 index 0000000..1560457 Binary files /dev/null and b/po/wo.mo differ diff --git a/po/wo.po b/po/wo.po new file mode 100644 index 0000000..3adf661 --- /dev/null +++ b/po/wo.po @@ -0,0 +1,33 @@ +# translation of newt_newt_po.po to Wolof +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. +# Mouhamadou Mamoune Mbacke , 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: newt_newt_po\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2006-09-14 16:03+0200\n" +"PO-Revision-Date: 2005-07-07 16:20+0000\n" +"Last-Translator: Mouhamadou Mamoune Mbacke \n" +"Language-Team: Wolof\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.9.1\n" + +#: ../dialogboxes.c:43 ../dialogboxes.c:48 ../dialogboxes.c:493 +msgid "Ok" +msgstr "Ok" + +#: ../dialogboxes.c:51 +msgid "Cancel" +msgstr "Neenal" + +#: ../dialogboxes.c:498 +msgid "Yes" +msgstr "Waaw" + +#: ../dialogboxes.c:500 +msgid "No" +msgstr "Déet" diff --git a/po/xh.mo b/po/xh.mo new file mode 100644 index 0000000..4e68682 Binary files /dev/null and b/po/xh.mo differ diff --git a/po/xh.po b/po/xh.po new file mode 100644 index 0000000..29f45fd --- /dev/null +++ b/po/xh.po @@ -0,0 +1,33 @@ +# Xhosa translations for newt +# Copyright (C) 2005 Canonical Ltd. +# This file is distributed under the same license as the newt package. +# Translation by Canonical Ltd with thanks to +# Translation World CC in South Africa, 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2006-09-14 16:03+0200\n" +"PO-Revision-Date: 2005-02-28 21:09+0200\n" +"Last-Translator: Canonical Ltd \n" +"Language-Team: Xhosa \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../dialogboxes.c:43 ../dialogboxes.c:48 ../dialogboxes.c:493 +msgid "Ok" +msgstr "Kulungile" + +#: ../dialogboxes.c:51 +msgid "Cancel" +msgstr "Rhoxisa" + +#: ../dialogboxes.c:498 +msgid "Yes" +msgstr "Ewe" + +#: ../dialogboxes.c:500 +msgid "No" +msgstr "Hayi" diff --git a/po/zanata.xml b/po/zanata.xml new file mode 100644 index 0000000..ab915bb --- /dev/null +++ b/po/zanata.xml @@ -0,0 +1,7 @@ + + + https://fedora.zanata.org/ + newt + master + gettext + diff --git a/po/zh_CN.mo b/po/zh_CN.mo new file mode 100644 index 0000000..8c1657a Binary files /dev/null and b/po/zh_CN.mo differ diff --git a/po/zh_CN.po b/po/zh_CN.po new file mode 100644 index 0000000..1f43dce --- /dev/null +++ b/po/zh_CN.po @@ -0,0 +1,34 @@ +# Simplified Chinese translations for newt +# Copyright (C) 2003 Free Software Foundation +# This file is distributed under the same license as the newt package. +# Alastair McKinstry , 2003. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-02-11 12:01-0500\n" +"Last-Translator: Carlos Z.F. Liu \n" +"Language-Team: Debian Chinese [GB] \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: zh-CN\n" +"Plural-Forms: nplurals=1; plural=0\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "确定" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "取消" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "是" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "否" diff --git a/po/zh_TW.mo b/po/zh_TW.mo new file mode 100644 index 0000000..8c73193 Binary files /dev/null and b/po/zh_TW.mo differ diff --git a/po/zh_TW.po b/po/zh_TW.po new file mode 100644 index 0000000..2270535 --- /dev/null +++ b/po/zh_TW.po @@ -0,0 +1,34 @@ +# Traditional Chinese translations for newt +# Copyright (C) 2003 Free Software Foundation +# This file is distributed under the same license as the newt package. +# Alastair McKinstry , 2003. +msgid "" +msgstr "" +"Project-Id-Version: newt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-23 15:59+0100\n" +"PO-Revision-Date: 2004-09-20 09:56-0400\n" +"Last-Translator: Tetralet \n" +"Language-Team: Debian-user in Chinese [Big5] \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: zh-TW\n" +"Plural-Forms: nplurals=1; plural=0\n" +"X-Generator: Zanata 3.8.2\n" + +#: ../dialogboxes.c:49 +msgid "Ok" +msgstr "確定" + +#: ../dialogboxes.c:50 +msgid "Cancel" +msgstr "取消" + +#: ../dialogboxes.c:51 +msgid "Yes" +msgstr "是" + +#: ../dialogboxes.c:52 +msgid "No" +msgstr "否" diff --git a/popcorn.py b/popcorn.py new file mode 100755 index 0000000..5d5a345 --- /dev/null +++ b/popcorn.py @@ -0,0 +1,113 @@ +#!/usr/bin/python + +from __future__ import absolute_import, print_function, unicode_literals +from snack import * +import sys + +def help(screen, text): + ButtonChoiceWindow(screen, "Help", text, help = "Help on help") + +t = TextboxReflowed(25, "Some text which needs to be wrapped at a good place.") +li = Listbox(5, width = 20, returnExit = 1) +li.append("First", "f") +li.append("Second", "s") +li.insert("Another", "a", "f") +li.delete("a") +ct = CheckboxTree(5, scroll = 1) +ct.append("Colors") +ct.addItem("Red", (0, snackArgs['append']), "red item key") +ct.addItem("Yellow", (0, snackArgs['append'])) +ct.addItem("Blue", (0, snackArgs['append'])) +ct.append("Flavors") +ct.addItem("Vanilla", (1, snackArgs['append'])) +ct.addItem("Chocolate", (1, snackArgs['append'])) +ct.addItem("Stawberry", (1, snackArgs['append'])) +ct.append("Numbers") +ct.addItem("1", (2, snackArgs['append'])) +ct.addItem("2", (2, snackArgs['append'])) +ct.addItem("3", (2, snackArgs['append'])) +ct.append("Names") +ct.addItem("Matt", (3, snackArgs['append'])) +ct.addItem("Shawn", (3, snackArgs['append'])) +ct.addItem("Wilson", (3, snackArgs['append'])) +ct.append("Months") +ct.addItem("February", (4, snackArgs['append'])) +ct.addItem("August", (4, snackArgs['append'])) +ct.addItem("September", (4, snackArgs['append'])) +ct.append("Events") +ct.addItem("Christmas", (5, snackArgs['append'])) +ct.addItem("Labor Day", (5, snackArgs['append'])) +ct.addItem("My Vacation", (5, snackArgs['append'])) +b = Button("Button") +e = Entry(15, "Entry") +l = Label("label") +cb = Checkbox("checkbox") +r1 = SingleRadioButton("Radio 1", None, 1) +r2 = SingleRadioButton("Radio 2", r1) + +def something(): + print(hello) + +screen = SnackScreen() + +screen.helpCallback(help) + +foo = EntryWindow(screen, 'Title', 'This is some text for the entry window', + ['prompt', 'more', 'info']) + +lbcw = ListboxChoiceWindow(screen, 'Title 2', + 'Choose one item from the list below:', + ('One', 'Two', 'Three', 'Four', 'Five'), default = 2, + help = "Help for a listbox") + +sg = Grid(2, 3) +sg.setField(b, 0, 0, anchorLeft = 1) +sg.setField(e, 1, 0, (1, 0, 0, 0), anchorLeft = 1, anchorTop = 1) +sg.setField(l, 0, 1, (0, 1, 0, 0), anchorLeft = 1) +sg.setField(cb, 1, 1, (1, 1, 0, 0), anchorLeft = 1) +sg.setField(r1, 0, 2, (0, 0, 0, 0), anchorLeft = 1) +sg.setField(r2, 1, 2, (1, 0, 0, 0), anchorLeft = 1) + +g = Grid(1, 3) + +g.setField(t, 0, 0) +g.setField(li, 0, 1, (0, 1, 0, 1)) +g.setField(sg, 0, 2) + +g.place(1, 1) + +screen.gridWrappedWindow(g, "title") + +f = Form("This is some help") +f.add(li) +f.add(b) +f.add(e) +f.add(l) +f.add(cb) +f.add(r1) +f.add(r2) +f.add(t) + +res = f.run() + +screen.popWindow() + +g = GridForm(screen, "Tree", 1, 2) +g.add(ct, 0, 0, (0, 0, 0, 1)) +g.add(Button("Ok"), 0, 1) +g.runOnce() + + +screen.finish() + +print("val", e.value()) +print("check", cb.value()) +print("r1", r1.selected()) +print("listbox", li.current()) +# returns a tuple of the wrapped text, the actual width, and the actual height +print(res) + +print(foo) +print('lbcw', lbcw) +print("ct selected", ct.getSelection()) +print("ct current", ct.getCurrent()) diff --git a/scale.c b/scale.c new file mode 100644 index 0000000..35dcdde --- /dev/null +++ b/scale.c @@ -0,0 +1,107 @@ +#include +#include +#include + +#include "newt.h" +#include "newt_pr.h" + +struct scale { + long long fullValue; + int charsSet; + unsigned int percentage; + int csEmpty; + int csFull; +}; + +static void scaleDraw(newtComponent co); + +static struct componentOps scaleOps = { + scaleDraw, + newtDefaultEventHandler, + NULL, + newtDefaultPlaceHandler, + newtDefaultMappedHandler, +} ; + +newtComponent newtScale(int left, int top, int width, long long fullValue) { + newtComponent co; + struct scale * sc; + + co = malloc(sizeof(*co)); + sc = malloc(sizeof(struct scale)); + co->data = sc; + co->destroyCallback = NULL; + + co->ops = &scaleOps; + + co->height = 1; + co->width = width; + co->top = top; + co->left = left; + co->takesFocus = 0; + co->isMapped = 0; + + sc->fullValue = fullValue; + sc->charsSet = 0; + sc->percentage = 0; + sc->csEmpty = NEWT_COLORSET_EMPTYSCALE; + sc->csFull = NEWT_COLORSET_FULLSCALE; + + return co; +} + +void newtScaleSet(newtComponent co, unsigned long long amount) { + struct scale * sc = co->data; + int newPercentage; + + if (amount >= sc->fullValue) { + newPercentage = 100; + sc->charsSet = co->width; + } else if (sc->fullValue >= -1ULL / (100 > co->width ? 100 : co->width)) { + /* avoid overflow on large numbers */ + sc->charsSet = amount / (sc->fullValue / co->width); + newPercentage = amount / (sc->fullValue / 100); + } else { + sc->charsSet = (amount * co->width) / sc->fullValue; + newPercentage = (amount * 100) / sc->fullValue; + } + + if (newPercentage != sc->percentage) { + sc->percentage = newPercentage; + scaleDraw(co); + } +} + +void newtScaleSetColors(newtComponent co, int empty, int full) { + struct scale * sc = co->data; + + sc->csEmpty = empty; + sc->csFull = full; + scaleDraw(co); +} + +static void scaleDraw(newtComponent co) { + struct scale * sc = co->data; + int i; + int xlabel = (co->width-4) /2; + char percent[10]; + + if (!co->isMapped) return; + + newtGotorc(co->top, co->left); + + sprintf(percent, "%3d%%", sc->percentage); + + SLsmg_set_color(sc->csFull); + + for (i = 0; i < co->width; i++) { + if (i == sc->charsSet) + SLsmg_set_color(sc->csEmpty); + if (i >= xlabel && i < xlabel+4) + SLsmg_write_char(percent[i-xlabel]); + else + SLsmg_write_char(' '); + } + /* put cursor at beginning of text for better accessibility */ + newtGotorc(co->top, co->left + xlabel); +} diff --git a/scrollbar.c b/scrollbar.c new file mode 100644 index 0000000..0c706b3 --- /dev/null +++ b/scrollbar.c @@ -0,0 +1,133 @@ +#include +#include +#include + +#include "newt.h" +#include "newt_pr.h" + +struct scrollbar { + int curr; + int cs, csThumb; + int arrows; +} ; + +static void sbDraw(newtComponent co); +static void sbDestroy(newtComponent co); +static void sbDrawThumb(newtComponent co, int isOn); + +static struct componentOps sbOps = { + sbDraw, + newtDefaultEventHandler, + sbDestroy, + newtDefaultPlaceHandler, + newtDefaultMappedHandler, +} ; + +void newtScrollbarSet(newtComponent co, int where, int total) { + struct scrollbar * sb = co->data; + int new; + + if (sb->arrows) + new = (where * (co->height - 3)) / (total ? total : 1) + 1; + else + new = (where * (co->height - 1)) / (total ? total : 1); + if (new != sb->curr) { + sbDrawThumb(co, 0); + sb->curr = new; + sbDrawThumb(co, 1); + } +} + +newtComponent newtVerticalScrollbar(int left, int top, int height, + int normalColorset, int thumbColorset) { + newtComponent co; + struct scrollbar * sb; + + co = malloc(sizeof(*co)); + sb = malloc(sizeof(*sb)); + co->data = sb; + co->destroyCallback = NULL; + + if (height >= 2) { + sb->arrows = 1; + sb->curr = 1; + } else { + sb->arrows = 0; + sb->curr = 0; + } + sb->cs = normalColorset; + sb->csThumb = thumbColorset; + + co->ops = &sbOps; + co->isMapped = 0; + co->left = left; + co->top = top; + co->height = height; + co->width = 1; + co->takesFocus = 0; + + return co; +} + +void newtScrollbarSetColors(newtComponent co, int normal, int thumb) { + struct scrollbar * sb = co->data; + + sb->cs = normal; + sb->csThumb = thumb; + sbDraw(co); +} + +static void sbDraw(newtComponent co) { + struct scrollbar * sb = co->data; + int i; + + if (!co->isMapped) return; + + SLsmg_set_color(sb->cs); + + SLsmg_set_char_set(1); + if (sb->arrows) { + newtGotorc(co->top, co->left); + SLsmg_write_char(SLSMG_UARROW_CHAR); + for (i = 1; i < co->height - 1; i++) { + newtGotorc(i + co->top, co->left); + SLsmg_write_char(SLSMG_CKBRD_CHAR); + } + newtGotorc(co->top + co->height - 1, co->left); + SLsmg_write_char(SLSMG_DARROW_CHAR); + } else { + for (i = 0; i < co->height; i++) { + newtGotorc(i + co->top, co->left); + SLsmg_write_char(SLSMG_CKBRD_CHAR); + } + } + + SLsmg_set_char_set(0); + + sbDrawThumb(co, 1); +} + +static void sbDrawThumb(newtComponent co, int isOn) { + struct scrollbar * sb = co->data; + SLtt_Char_Type ch = isOn ? SLSMG_BLOCK_CHAR : SLSMG_CKBRD_CHAR; + + if (!co->isMapped) return; + + newtGotorc(sb->curr + co->top, co->left); + SLsmg_set_char_set(1); + + /*if (isOn) + SLsmg_set_color(sb->csThumb); + else*/ + SLsmg_set_color(sb->cs); + + SLsmg_write_char(ch); + SLsmg_set_char_set(0); +} + +static void sbDestroy(newtComponent co) { + struct scrollbar * sb = co->data; + + free(sb); + free(co); +} diff --git a/showchars.c b/showchars.c new file mode 100644 index 0000000..eb999ed --- /dev/null +++ b/showchars.c @@ -0,0 +1,42 @@ +#include + +void printall(int offset) { + int n = 0; + int i, j; + + SLsmg_gotorc(0, offset); + SLsmg_write_string(" 0 1 2 3 4 5 6 7 8 9 A B C D E F"); + for (i = 0; i < 16; i++) { + SLsmg_gotorc(i + 1, offset); + SLsmg_printf("%x", i); + for (j = 0; j < 16; j++) { + SLsmg_gotorc(i + 1, (j + 1) * 2 + offset); + SLsmg_write_char(n++); + } + } +} + +int main(void) { + SLtt_get_terminfo(); + + SLtt_Use_Ansi_Colors = 1; + + SLsmg_init_smg(); + SLang_init_tty(4, 0, 0); + + SLsmg_cls(); + + printall(0); + SLsmg_set_char_set(1); + printall(40); + + SLsmg_refresh(); + SLang_getkey(); + + SLsmg_gotorc(SLtt_Screen_Rows - 1, 0); + SLsmg_refresh(); + SLsmg_reset_smg(); + SLang_reset_tty(); + + return 0; +} diff --git a/showkey.c b/showkey.c new file mode 100644 index 0000000..14baf6c --- /dev/null +++ b/showkey.c @@ -0,0 +1,41 @@ +#include +#include + +int main(void) { + int i; + char * buf; + + SLtt_get_terminfo(); + SLang_init_tty(4, 0, 0); + + buf = SLtt_tgetstr("ku"); + if (!buf) { + printf("termcap entry not found for kl\n\r"); + } else { + printf("termcap entry found for kl: %s", buf); + while (*buf) { + printf("0x%02x ", *buf++); + } + printf("\n\r"); + } + + printf("\n\r"); + + printf("Press a key: "); + fflush(stdout); + + SLang_input_pending(50); + + printf("\n\r"); + printf("You pressed: "); + + while (SLang_input_pending(1)) { + i = SLang_getkey(); + printf("0x%02x ", i); + } + + printf("\n\r"); + + SLang_reset_tty(); + return 0; +} diff --git a/snack.c b/snack.c new file mode 100644 index 0000000..880a431 --- /dev/null +++ b/snack.c @@ -0,0 +1,1534 @@ + +#include "Python.h" +#include "config.h" + +#ifdef HAVE_ALLOCA_H +#include +#endif + +#include +#include +#include +#include +#include + +#include "structmember.h" +#include "nls.h" +#include "newt.h" +#include "newt_pr.h" + +#if PY_MAJOR_VERSION >= 3 + #define PyInt_FromLong PyLong_FromLong + #define PyInt_AsLong PyLong_AsLong + #define PyString_FromString PyUnicode_FromString + #define MOD_ERROR_VAL NULL + #define MOD_SUCCESS_VAL(val) val + #define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void) +#else + #define MOD_ERROR_VAL + #define MOD_SUCCESS_VAL(val) + #define MOD_INIT(name) void init##name(void) +#endif + +typedef struct snackWidget_s snackWidget; +typedef struct snackGrid_s snackGrid; +typedef struct snackForm_s snackForm; + +struct callbackStruct { + PyObject * cb, * data; +}; + +/* Integer to pointer, 64-bit-sane */ +#define I2P(x) ((void *)(long)(x)) + +static struct callbackStruct suspend; +static struct callbackStruct helpCallback; + +static void emptyDestructor(PyObject * s); + +static snackWidget * buttonWidget(PyObject * s, PyObject * args); +static snackWidget * compactbuttonWidget(PyObject * s, PyObject * args); +static PyObject * centeredWindow(PyObject * s, PyObject * args); +static snackWidget * checkboxWidget(PyObject * s, PyObject * args); +static PyObject * choiceWindow(PyObject * s, PyObject * args); +static snackWidget * entryWidget(PyObject * s, PyObject * args); +static PyObject * drawRootText(PyObject * s, PyObject * args); +static PyObject * doResume(PyObject * s, PyObject * args); +static PyObject * doSuspend(PyObject * s, PyObject * args); +static PyObject * doSuspend(PyObject * s, PyObject * args); +static snackForm * formCreate(PyObject * s, PyObject * args); +static snackGrid * gridCreate(PyObject * s, PyObject * args); +static PyObject * gridWrappedWindow(PyObject * s, PyObject * args); +static PyObject * finishScreen(PyObject * s, PyObject * args); +static PyObject * initScreen(PyObject * s, PyObject * args); +static snackWidget * labelWidget(PyObject * s, PyObject * args); +static snackWidget * listboxWidget(PyObject * s, PyObject * args); +static PyObject * messageWindow(PyObject * s, PyObject * args); +static PyObject * openWindow(PyObject * s, PyObject * args); +static PyObject * popHelpLine(PyObject * s, PyObject * args); +static PyObject * popWindow(PyObject * s, PyObject * args); +static PyObject * popWindowNoRefresh(PyObject * s, PyObject * args); +static PyObject * pushHelpLine(PyObject * s, PyObject * args); +static snackWidget * radioButtonWidget(PyObject * s, PyObject * args); +static PyObject * refreshScreen(PyObject * s, PyObject * args); +static PyObject * setColor(PyObject * s, PyObject * args); +static PyObject * scaleWidget(PyObject * s, PyObject * args); +static PyObject * scaleSet(snackWidget * s, PyObject * args); +static PyObject * screenSize(PyObject * s, PyObject * args); +static PyObject * setSuspendCallback(PyObject * s, PyObject * args); +static PyObject * setHelpCallback(PyObject * s, PyObject * args); +static PyObject * reflowText(PyObject * s, PyObject * args); +static snackWidget * textWidget(PyObject * s, PyObject * args); +static PyObject * ternaryWindow(PyObject * s, PyObject * args); +static snackWidget * checkboxTreeWidget(PyObject * s, PyObject * args, PyObject * kwargs); +static PyObject * pywstrlen(PyObject * s, PyObject * args); +static PyObject * widget_get_checkboxValue(PyObject *self, void *closure); +static PyObject * widget_get_radioValue(PyObject *self, void *closure); + +static PyMethodDef snackModuleMethods[] = { + { "button", (PyCFunction) buttonWidget, METH_VARARGS, NULL }, + { "compactbutton", (PyCFunction) compactbuttonWidget, METH_VARARGS, NULL }, + { "checkbox", (PyCFunction) checkboxWidget, METH_VARARGS, NULL }, + { "choice", choiceWindow, METH_VARARGS, NULL }, + { "centeredwindow", centeredWindow, METH_VARARGS, NULL }, + { "drawroottext", drawRootText, METH_VARARGS, NULL }, + { "entry", (PyCFunction) entryWidget, METH_VARARGS, NULL }, + { "finish", finishScreen, METH_VARARGS, NULL }, + { "form", (PyCFunction) formCreate, METH_VARARGS, NULL }, + { "grid", (PyCFunction) gridCreate, METH_VARARGS, NULL }, + { "gridwrappedwindow", gridWrappedWindow, METH_VARARGS, NULL }, + { "helpcallback", setHelpCallback, METH_VARARGS, NULL }, + { "init", initScreen, METH_VARARGS, NULL }, + { "label", (PyCFunction) labelWidget, METH_VARARGS, NULL }, + { "listbox", (PyCFunction) listboxWidget, METH_VARARGS, NULL }, + { "message", messageWindow, METH_VARARGS, NULL }, + { "openwindow", openWindow, METH_VARARGS, NULL }, + { "pophelpline", popHelpLine, METH_VARARGS, NULL }, + { "popwindow", popWindow, METH_VARARGS, NULL }, + { "popwindownorefresh", popWindowNoRefresh, METH_VARARGS, NULL }, + { "pushhelpline", pushHelpLine, METH_VARARGS, NULL }, + { "radiobutton", (PyCFunction) radioButtonWidget, METH_VARARGS, NULL }, + { "reflow", (PyCFunction) reflowText, METH_VARARGS, NULL }, + { "refresh", refreshScreen, METH_VARARGS, NULL }, + { "setcolor", setColor, METH_VARARGS, NULL }, + { "resume", doResume, METH_VARARGS, NULL }, + { "scale", scaleWidget, METH_VARARGS, NULL }, + { "size", screenSize, METH_VARARGS, NULL }, + { "suspend", doSuspend, METH_VARARGS, NULL }, + { "suspendcallback", setSuspendCallback, METH_VARARGS, NULL }, + { "ternary", ternaryWindow, METH_VARARGS, NULL }, + { "textbox", (PyCFunction) textWidget, METH_VARARGS, NULL }, + { "checkboxtree", (PyCFunction) checkboxTreeWidget, METH_VARARGS | METH_KEYWORDS, NULL }, + { "wstrlen", (PyCFunction) pywstrlen, METH_VARARGS | METH_KEYWORDS, NULL }, + { NULL } +} ; + +#if PY_MAJOR_VERSION >= 3 +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "_snack", /* m_name */ + NULL, /* m_doc */ + -1, /* m_size */ + snackModuleMethods, /* m_methods */ + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ + }; +#endif + +static struct PyGetSetDef widget_getset[] = { + { "checkboxValue", widget_get_checkboxValue, 0, NULL, NULL }, + { "radioValue", widget_get_radioValue, 0, NULL, NULL }, + { NULL } +}; + +struct snackGrid_s { + PyObject_HEAD + newtGrid grid; +} ; + +static PyObject * gridPlace(snackGrid * s, PyObject * args); +static PyObject * gridSetField(snackGrid * s, PyObject * args); + +static PyMethodDef gridMethods[] = { + { "place", (PyCFunction) gridPlace, METH_VARARGS, NULL }, + { "setfield", (PyCFunction) gridSetField, METH_VARARGS, NULL }, + { NULL } +}; + +static PyTypeObject snackGridType = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "snackgrid", /* tp_name */ + sizeof(snackGrid), /* tp_size */ + 0, /* tp_itemsize */ + emptyDestructor, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + gridMethods /* tp_methods */ +}; + +struct snackForm_s { + PyObject_HEAD + newtComponent fo; +} ; + +static PyObject * formAdd(snackForm * s, PyObject * args); +static PyObject * formDraw(snackForm * s, PyObject * args); +static PyObject * formRun(snackForm * s, PyObject * args); +static PyObject * formHotKey(snackForm * s, PyObject * args); +static PyObject * formSetCurrent(snackForm * form, PyObject * args); +static PyObject * formSetTimer(snackForm * form, PyObject * args); +static PyObject * formWatchFD(snackForm * form, PyObject * args); + +static PyMethodDef formMethods[] = { + { "add", (PyCFunction) formAdd, METH_VARARGS, NULL }, + { "draw", (PyCFunction) formDraw, METH_VARARGS, NULL }, + { "run", (PyCFunction) formRun, METH_VARARGS, NULL }, + { "addhotkey", (PyCFunction) formHotKey, METH_VARARGS, NULL }, + { "setcurrent", (PyCFunction) formSetCurrent, METH_VARARGS, NULL }, + { "settimer", (PyCFunction) formSetTimer, METH_VARARGS, NULL }, + { "watchfd", (PyCFunction) formWatchFD, METH_VARARGS, NULL }, + { NULL } +}; + +static PyTypeObject snackFormType = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "snackform", /* tp_name */ + sizeof(snackForm), /* tp_size */ + 0, /* tp_itemsize */ + emptyDestructor, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + formMethods /* tp_methods */ +}; + +struct snackWidget_s { + PyObject_HEAD + newtComponent co; + char achar; + void * apointer; + int anint; + struct callbackStruct scs; +} ; + +static PyObject * widgetAddCallback(snackWidget * s, PyObject * args); +static void widgetDestructor(PyObject * s); +static PyObject * widgetEntrySetValue(snackWidget * s, PyObject * args); +static PyObject * widgetLabelText(snackWidget * s, PyObject * args); +static PyObject * widgetLabelSetColors(snackWidget * s, PyObject * args); +static PyObject * widgetListboxSetW(snackWidget * s, PyObject * args); +static PyObject * widgetListboxAdd(snackWidget * s, PyObject * args); +static PyObject * widgetListboxIns(snackWidget * s, PyObject * args); +static PyObject * widgetListboxDel(snackWidget * s, PyObject * args); +static PyObject * widgetListboxGet(snackWidget * s, PyObject * args); +static PyObject * widgetListboxGetSel(snackWidget * s, PyObject * args); +static PyObject * widgetListboxSet(snackWidget * s, PyObject * args); +static PyObject * widgetListboxClear(snackWidget * s, PyObject * args); +static PyObject * widgetTextboxText(snackWidget * s, PyObject * args); +static PyObject * widgetTextboxHeight(snackWidget * s, PyObject * args); +static PyObject * widgetCheckboxTreeAddItem(snackWidget * s, PyObject * args); +static PyObject * widgetCheckboxTreeGetSel(snackWidget * s, PyObject * args); +static PyObject * widgetCheckboxTreeGetCur(snackWidget * s, PyObject * args); +static PyObject * widgetCheckboxTreeSetEntry(snackWidget * s, PyObject * args); +static PyObject * widgetCheckboxTreeSetWidth(snackWidget * s, PyObject * args); +static PyObject * widgetCheckboxTreeSetCurrent(snackWidget * s, PyObject * args); +static PyObject * widgetCheckboxTreeSetEntryValue(snackWidget * s, PyObject * args); +static PyObject * widgetCheckboxTreeGetEntryValue(snackWidget * s, PyObject * args); +static PyObject * widgetEntrySetFlags(snackWidget * s, PyObject * args); +static PyObject * widgetCheckboxSetFlags(snackWidget * s, PyObject * args); +static PyObject * widgetCheckboxSetValue(snackWidget * s, PyObject * args); + +static PyMethodDef widgetMethods[] = { + { "setCallback", (PyCFunction) widgetAddCallback, METH_VARARGS, NULL }, + { "labelSetColors", (PyCFunction) widgetLabelSetColors, METH_VARARGS, NULL }, + { "labelText", (PyCFunction) widgetLabelText, METH_VARARGS, NULL }, + { "textboxText", (PyCFunction) widgetTextboxText, METH_VARARGS, NULL }, + { "textboxHeight", (PyCFunction) widgetTextboxHeight, METH_VARARGS, NULL }, + { "entrySetValue", (PyCFunction) widgetEntrySetValue, METH_VARARGS, NULL }, + { "listboxAddItem", (PyCFunction) widgetListboxAdd, METH_VARARGS, NULL }, + { "listboxInsertItem", (PyCFunction) widgetListboxIns, METH_VARARGS, NULL }, + { "listboxGetCurrent", (PyCFunction) widgetListboxGet, METH_VARARGS, NULL }, + { "listboxGetSelection", (PyCFunction) widgetListboxGetSel, METH_VARARGS, NULL }, + { "listboxSetCurrent", (PyCFunction) widgetListboxSet, METH_VARARGS, NULL }, + { "listboxSetWidth", (PyCFunction) widgetListboxSetW, METH_VARARGS, NULL }, + { "listboxDeleteItem", (PyCFunction) widgetListboxDel, METH_VARARGS, NULL }, + { "listboxClear", (PyCFunction) widgetListboxClear, METH_VARARGS, NULL }, + { "scaleSet", (PyCFunction) scaleSet, METH_VARARGS, NULL }, + { "checkboxtreeAddItem", (PyCFunction) widgetCheckboxTreeAddItem, + METH_VARARGS, NULL }, + { "checkboxtreeGetCurrent", (PyCFunction) widgetCheckboxTreeGetCur, + METH_VARARGS, NULL }, + { "checkboxtreeGetEntryValue", (PyCFunction) widgetCheckboxTreeGetEntryValue, + METH_VARARGS, NULL }, + { "checkboxtreeSetEntry", (PyCFunction) widgetCheckboxTreeSetEntry, + METH_VARARGS, NULL }, + { "checkboxtreeSetWidth", (PyCFunction) widgetCheckboxTreeSetWidth, METH_VARARGS, NULL }, + { "checkboxtreeSetCurrent", (PyCFunction) widgetCheckboxTreeSetCurrent, + METH_VARARGS, NULL }, + { "checkboxtreeSetEntryValue", (PyCFunction) widgetCheckboxTreeSetEntryValue, + METH_VARARGS, NULL }, + { "checkboxtreeGetSelection", (PyCFunction) widgetCheckboxTreeGetSel, + METH_VARARGS, NULL }, + { "entrySetFlags", (PyCFunction) widgetEntrySetFlags, METH_VARARGS, NULL }, + { "checkboxSetFlags", (PyCFunction) widgetCheckboxSetFlags, METH_VARARGS, NULL }, + { "checkboxSetValue", (PyCFunction) widgetCheckboxSetValue, METH_VARARGS, NULL }, + { NULL } +}; + +static PyMemberDef widget_members[] = { + { "key", +#if SIZEOF_VOID_P == SIZEOF_LONG + T_LONG, +#elif SIZEOF_VOID_P == SIZEOF_LONG_LONG + T_LONGLONG, +#else +#error unsupported pointer size +#endif + offsetof(snackWidget, co), 0, NULL }, + { "entryValue", T_STRING, offsetof(snackWidget, apointer), 0, NULL }, + { NULL } +}; + +static PyTypeObject snackWidgetType = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "snackwidget", /* tp_name */ + sizeof(snackWidget), /* tp_size */ + 0, /* tp_itemsize */ + widgetDestructor, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + widgetMethods, /* tp_methods */ + widget_members, /* tp_members */ + widget_getset /* tp_getset */ +}; + +static snackWidget * snackWidgetNew (void) { + snackWidget * widget; + + widget = PyObject_NEW(snackWidget, &snackWidgetType); + if (!widget) + return NULL; + + widget->scs.cb = NULL; + widget->scs.data = NULL; + + return widget; +} + +static PyObject * initScreen(PyObject * s, PyObject * args) { + suspend.cb = NULL; + suspend.data = NULL; + + newtInit(); + newtCls(); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * finishScreen(PyObject * s, PyObject * args) { + Py_XDECREF (suspend.cb); + Py_XDECREF (suspend.data); + + newtFinished(); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * refreshScreen(PyObject * s, PyObject * args) { + newtRefresh(); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * setColor(PyObject * s, PyObject * args) { + char * fg, * bg; + int colorset; + if (!PyArg_ParseTuple(args, "iss", &colorset, &fg, &bg)) + return NULL; + + newtSetColor(colorset, fg, bg); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * scaleWidget(PyObject * s, PyObject * args) { + snackWidget * widget; + int width, fullAmount; + + if (!PyArg_ParseTuple(args, "ii", &width, &fullAmount)) return NULL; + + widget = snackWidgetNew (); + if (!widget) + return NULL; + widget->co = newtScale(-1, -1, width, fullAmount); + + return (PyObject *) widget; +} + +static PyObject * scaleSet(snackWidget * s, PyObject * args) { + int amount; + + if (!PyArg_ParseTuple(args, "i", &amount)) return NULL; + + newtScaleSet(s->co, amount); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * screenSize(PyObject * s, PyObject * args) { + int width, height; + + if (!PyArg_ParseTuple(args, "")) + return NULL; + + newtGetScreenSize(&width, &height); + + return Py_BuildValue("(ii)", width, height); +} + +static void helpCallbackMarshall(newtComponent co, void * data) { + PyObject * args, * result; + + PyGILState_STATE _state = PyGILState_Ensure(); + + args = Py_BuildValue("(O)", data); + result = PyEval_CallObject(helpCallback.cb, args); + Py_DECREF (args); + Py_XDECREF(result); + + PyGILState_Release(_state); + + return; +} + +static void suspendCallbackMarshall(void * data) { + struct callbackStruct * scs = data; + PyObject * args, * result; + + PyGILState_STATE _state = PyGILState_Ensure(); + + if (scs->data) { + args = Py_BuildValue("(O)", scs->data); + result = PyEval_CallObject(scs->cb, args); + Py_DECREF (args); + } else + result = PyEval_CallObject(scs->cb, NULL); + + if (!result) { + PyErr_Print(); + PyErr_Clear(); + } + + Py_XDECREF(result); + + PyGILState_Release(_state); + + return; +} + +static void callbackMarshall(newtComponent co, void * data) { + struct callbackStruct * scs = data; + PyObject * args, * result; + + PyGILState_STATE _state = PyGILState_Ensure(); + + if (scs->data) { + args = Py_BuildValue("(O)", scs->data); + result = PyEval_CallObject(scs->cb, args); + Py_DECREF (args); + } else + result = PyEval_CallObject(scs->cb, NULL); + + if (!result) { + PyErr_Print(); + PyErr_Clear(); + } + + Py_XDECREF(result); + + PyGILState_Release(_state); + + return; +} + +static PyObject * setSuspendCallback(PyObject * s, PyObject * args) { + if (!PyArg_ParseTuple(args, "O|O", &suspend.cb, &suspend.data)) + return NULL; + + Py_INCREF (suspend.cb); + Py_XINCREF (suspend.data); + + newtSetSuspendCallback(suspendCallbackMarshall, &suspend); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * setHelpCallback(PyObject * s, PyObject * args) { + if (!PyArg_ParseTuple(args, "O", &helpCallback.cb)) + return NULL; + + /*if (helpCallback.cb) { + Py_DECREF (helpCallback.cb); + }*/ + + Py_INCREF (helpCallback.cb); + + newtSetHelpCallback(helpCallbackMarshall); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * drawRootText(PyObject * s, PyObject * args) { + int left, top; + char * text; + + if (!PyArg_ParseTuple(args, "iis", &left, &top, &text)) + return NULL; + + newtDrawRootText(left, top, text); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doSuspend(PyObject * s, PyObject * args) { + newtSuspend(); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doResume(PyObject * s, PyObject * args) { + newtResume(); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * popHelpLine(PyObject * s, PyObject * args) { + newtPopHelpLine(); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * pushHelpLine(PyObject * s, PyObject * args) { + char * text; + + if (!PyArg_ParseTuple(args, "s", &text)) + return NULL; + + if (!strcmp(text, "*default*")) + newtPushHelpLine(NULL); + else + newtPushHelpLine(text); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * reflowText(PyObject * s, PyObject * args) { + char * text, * new; + int width, minus = 5, plus = 5; + int realWidth, realHeight; + PyObject * tuple; + + if (!PyArg_ParseTuple(args, "si|ii", &text, &width, &minus, &plus)) + return NULL; + + new = newtReflowText(text, width, minus, plus, &realWidth, &realHeight); + + tuple = Py_BuildValue("(sii)", new, realWidth, realHeight); + free(new); + + return tuple; +} + +static PyObject * centeredWindow(PyObject * s, PyObject * args) { + int width, height; + char * title; + + if (!PyArg_ParseTuple(args, "iis", &width, &height, &title)) + return NULL; + + newtCenteredWindow(width, height, title); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * gridWrappedWindow(PyObject * s, PyObject * args) { + snackGrid * grid; + char * title; + int x = -1, y = -1; + + if (!PyArg_ParseTuple(args, "O!s|ii", &snackGridType, &grid, &title, + &x, &y)) + return NULL; + + if (y == -1) + newtGridWrappedWindow(grid->grid, title); + else + newtGridWrappedWindowAt(grid->grid, title, x, y); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * openWindow(PyObject * s, PyObject * args) { + int left, top, width, height; + char * title; + + if (!PyArg_ParseTuple(args, "iiiis", &left, &top, &width, &height, &title)) + return NULL; + + newtOpenWindow(left, top, width, height, title); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * popWindow(PyObject * s, PyObject * args) { + newtPopWindow(); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * popWindowNoRefresh(PyObject * s, PyObject * args) { + newtPopWindowNoRefresh(); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * messageWindow(PyObject * s, PyObject * args) { + char * title, * text; + char * okbutton = "Ok"; + + if (!PyArg_ParseTuple(args, "ss|s", &title, &text, &okbutton)) + return NULL; + + Py_BEGIN_ALLOW_THREADS + newtWinMessage(title, okbutton, text); + Py_END_ALLOW_THREADS + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * choiceWindow(PyObject * s, PyObject * args) { + char * title, * text; + char * okbutton = "Ok"; + char * cancelbutton = "Cancel"; + int rc; + + if (!PyArg_ParseTuple(args, "ss|ss", &title, &text, &okbutton, + &cancelbutton)) + return NULL; + + Py_BEGIN_ALLOW_THREADS + rc = newtWinChoice(title, okbutton, cancelbutton, text); + Py_END_ALLOW_THREADS + + return Py_BuildValue("i", rc); +} + +static PyObject * ternaryWindow(PyObject * s, PyObject * args) { + char * title, * text, * button1, * button2, * button3; + int rc; + + if (!PyArg_ParseTuple(args, "sssss", &title, &text, &button1, &button2, + &button3)) + return NULL; + + Py_BEGIN_ALLOW_THREADS + rc = newtWinTernary(title, button1, button2, button3, text); + Py_END_ALLOW_THREADS + + return Py_BuildValue("i", rc); +} + +static snackWidget * buttonWidget(PyObject * s, PyObject * args) { + snackWidget * widget; + char * label; + + if (!PyArg_ParseTuple(args, "s", &label)) return NULL; + + widget = snackWidgetNew (); + if (!widget) + return NULL; + widget->co = newtButton(-1, -1, label); + + return widget; +} + +static snackWidget * compactbuttonWidget(PyObject * s, PyObject * args) { + snackWidget * widget; + char * label; + + if (!PyArg_ParseTuple(args, "s", &label)) return NULL; + + widget = snackWidgetNew (); + if (!widget) + return NULL; + widget->co = newtCompactButton(-1, -1, label); + + return widget; +} + +static snackWidget * labelWidget(PyObject * s, PyObject * args) { + char * label; + snackWidget * widget; + + if (!PyArg_ParseTuple(args, "s", &label)) return NULL; + + widget = snackWidgetNew (); + if (!widget) + return NULL; + widget->co = newtLabel(-1, -1, label); + + return widget; +} + +static PyObject * widgetLabelText(snackWidget * s, PyObject * args) { + char * label; + + if (!PyArg_ParseTuple(args, "s", &label)) return NULL; + + newtLabelSetText(s->co, label); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * widgetLabelSetColors(snackWidget * s, PyObject * args) { + int colorset; + + if (!PyArg_ParseTuple(args, "i", &colorset)) return NULL; + + newtLabelSetColors(s->co, colorset); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * widgetTextboxText(snackWidget * s, PyObject * args) { + char * text; + + if (!PyArg_ParseTuple(args, "s", &text)) return NULL; + + newtTextboxSetText(s->co, text); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * widgetTextboxHeight(snackWidget * s, PyObject * args) { + int height; + + if (!PyArg_ParseTuple(args, "i", &height)) return NULL; + + newtTextboxSetHeight(s->co, height); + + Py_INCREF(Py_None); + return Py_None; +} + +static snackWidget * listboxWidget(PyObject * s, PyObject * args) { + snackWidget * widget; + int height; + int doScroll = 0, returnExit = 0, showCursor = 0, multiple = 0, border = 0; + + if (!PyArg_ParseTuple(args, "i|iiiii", &height, &doScroll, &returnExit, + &showCursor, &multiple, &border)) + return NULL; + + widget = snackWidgetNew (); + if (!widget) + return NULL; + widget->co = newtListbox(-1, -1, height, + (doScroll ? NEWT_FLAG_SCROLL : 0) | + (returnExit ? NEWT_FLAG_RETURNEXIT : 0) | + (showCursor ? NEWT_FLAG_SHOWCURSOR : 0) | + (multiple ? NEWT_FLAG_MULTIPLE : 0) | + (border ? NEWT_FLAG_BORDER : 0) + ); + widget->anint = 1; + + return widget; +} + +static snackWidget * textWidget(PyObject * s, PyObject * args) { + char * text; + int width, height; + int scrollBar = 0; + int wrap = 0; + snackWidget * widget; + + if (!PyArg_ParseTuple(args, "iis|ii", &width, &height, &text, &scrollBar, &wrap)) + return NULL; + + widget = snackWidgetNew (); + if (!widget) + return NULL; + widget->co = newtTextbox(-1, -1, width, height, + (scrollBar ? NEWT_FLAG_SCROLL : 0) | + (wrap ? NEWT_FLAG_WRAP : 0)); + newtTextboxSetText(widget->co, text); + + return widget; +} + +static snackWidget * radioButtonWidget(PyObject * s, PyObject * args) { + snackWidget * widget, * group; + char * text; + int isOn; + + if (!PyArg_ParseTuple(args, "sOi", &text, &group, &isOn)) + return NULL; + + widget = snackWidgetNew (); + if (!widget) + return NULL; + + if ((PyObject *) group == Py_None) + widget->co = newtRadiobutton(-1, -1, text, isOn, NULL); + else + widget->co = newtRadiobutton(-1, -1, text, isOn, group->co); + + return widget; +} + +static snackWidget * checkboxWidget(PyObject * s, PyObject * args) { + snackWidget * widget; + char * text; + int isOn; + + if (!PyArg_ParseTuple(args, "si", &text, &isOn)) return NULL; + + widget = snackWidgetNew (); + if (!widget) + return NULL; + widget->co = newtCheckbox(-1, -1, text, isOn ? '*' : ' ', NULL, + &widget->achar); + + return widget; +} + +static PyObject * widgetCheckboxSetFlags(snackWidget * s, PyObject * args) { + int flag, sense; + + if (!PyArg_ParseTuple(args, "ii", &flag, &sense)) return NULL; + + newtCheckboxSetFlags(s->co, flag, sense); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * widgetCheckboxSetValue(snackWidget * s, PyObject * args) { + char *value; + + if (!PyArg_ParseTuple(args, "s", &value)) return NULL; + + newtCheckboxSetValue(s->co, *value); + + Py_INCREF(Py_None); + return Py_None; +} + +static snackWidget * entryWidget(PyObject * s, PyObject * args) { + snackWidget * widget; + int width; + char * initial; + int isHidden, isScrolled, returnExit, isPassword; + + if (!PyArg_ParseTuple(args, "isiiii", &width, &initial, + &isHidden, &isPassword, &isScrolled, &returnExit)) return NULL; + + widget = snackWidgetNew (); + if (!widget) + return NULL; + widget->co = newtEntry(-1, -1, initial, width, + (const char **) &widget->apointer, + (isHidden ? NEWT_FLAG_HIDDEN : 0) | + (isPassword ? NEWT_FLAG_PASSWORD : 0) | + (returnExit ? NEWT_FLAG_RETURNEXIT : 0) | + (isScrolled ? NEWT_FLAG_SCROLL : 0)); + + return widget; +} + +static snackForm * formCreate(PyObject * s, PyObject * args) { + snackForm * form; + PyObject * help = Py_None; + + if (!PyArg_ParseTuple(args, "|O", &help)) return NULL; + + if (help == Py_None) + help = NULL; + + form = PyObject_NEW(snackForm, &snackFormType); + form->fo = newtForm(NULL, help, 0); + + return form; +} + +static snackGrid * gridCreate(PyObject * s, PyObject * args) { + int rows, cols; + snackGrid * grid; + + if (!PyArg_ParseTuple(args, "ii", &cols, &rows)) return NULL; + + grid = PyObject_NEW(snackGrid, &snackGridType); + grid->grid = newtCreateGrid(cols, rows); + + return grid; +} + +static PyObject * gridPlace(snackGrid * grid, PyObject * args) { + int x, y; + + if (!PyArg_ParseTuple(args, "ii", &x, &y)) return NULL; + + newtGridPlace(grid->grid, x, y); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * gridSetField(snackGrid * grid, PyObject * args) { + snackWidget * w; + snackGrid * g; + int x, y; + int pLeft = 0, pTop = 0, pRight = 0, pBottom = 0; + int anchorFlags = 0, growFlags = 0; + + if (!PyArg_ParseTuple(args, "iiO|(iiii)ii", &x, &y, + &w, &pLeft, &pTop, &pRight, &pBottom, + &anchorFlags, &growFlags)) + return NULL; + + if (Py_TYPE(w) == &snackWidgetType) { + newtGridSetField(grid->grid, x, y, NEWT_GRID_COMPONENT, + w->co, pLeft, pTop, pRight, pBottom, anchorFlags, + growFlags); + } else { + g = (snackGrid *) w; + newtGridSetField(grid->grid, x, y, NEWT_GRID_SUBGRID, + g->grid, pLeft, pTop, pRight, pBottom, anchorFlags, + growFlags); + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * formDraw(snackForm * s, PyObject * args) { + newtDrawForm(s->fo); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * formAdd(snackForm * s, PyObject * args) { + snackWidget * w; + int size = PyTuple_Size(args), i; + + if (!size) { + /* this is a hack, I should give an error directly */ + if (!PyArg_ParseTuple(args, "O!", &snackWidgetType, &w)) + return NULL; + } + + for (i = 0; i < size; i++) { + w = (snackWidget *) PyTuple_GET_ITEM(args, i); + newtFormAddComponent(s->fo, w->co); + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * formRun(snackForm * s, PyObject * args) { + struct newtExitStruct result; + + Py_BEGIN_ALLOW_THREADS + newtFormRun(s->fo, &result); + Py_END_ALLOW_THREADS + + if (result.reason == NEWT_EXIT_HOTKEY) + return Py_BuildValue("(si)", "hotkey", result.u.key); + else if (result.reason == NEWT_EXIT_TIMER) + return Py_BuildValue("(si)", "timer", 0); + else if (result.reason == NEWT_EXIT_FDREADY) + return Py_BuildValue("(si)", "fdready", result.u.watch); + else if (result.reason == NEWT_EXIT_COMPONENT) +#if SIZEOF_VOID_P <= SIZEOF_LONG + return Py_BuildValue("(sl)", "widget", (long)result.u.co); +#else + return Py_BuildValue("(sL)", "widget", (long long)result.u.co); +#endif + else + return Py_BuildValue("(si)", "error", 0); +} + +static PyObject * formHotKey(snackForm * s, PyObject * args) { + int key; + + if (!PyArg_ParseTuple(args, "i", &key)) + return NULL; + + newtFormAddHotKey(s->fo, key); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * formSetTimer(snackForm * form, PyObject * args) { + int millisecs; + + if (!PyArg_ParseTuple(args, "i", &millisecs)) + return NULL; + + newtFormSetTimer(form->fo, millisecs); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * formWatchFD(snackForm * form, PyObject * args) { + int fd, fdflags; + + if (!PyArg_ParseTuple(args, "ii", &fd, &fdflags)) + return NULL; + + newtFormWatchFd(form->fo, fd, fdflags); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * formSetCurrent(snackForm * form, PyObject * args) { + snackWidget * w; + + if (!PyArg_ParseTuple(args, "O", &w)) + return NULL; + + newtFormSetCurrent(form->fo, w->co); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * widget_get_checkboxValue(PyObject *self, void *closure) +{ + snackWidget *w = (snackWidget *)self; + + return Py_BuildValue("i", w->achar == ' ' ? 0 : 1); +} + +static PyObject * widget_get_radioValue(PyObject *self, void *closure) +{ + snackWidget *w = (snackWidget *)self; + + return Py_BuildValue("i", newtRadioGetCurrent(w->co)); +} + +static void widgetDestructor(PyObject * o) { + snackWidget * s = (snackWidget *) o; + + Py_XDECREF (s->scs.cb); + Py_XDECREF (s->scs.data); + + PyObject_Free(o); +} + +static PyObject * widgetAddCallback(snackWidget * s, PyObject * args) { + s->scs.cb = NULL; + s->scs.data = NULL; + + if (!PyArg_ParseTuple(args, "O|O", &s->scs.cb, &s->scs.data)) + return NULL; + + Py_INCREF (s->scs.cb); + Py_XINCREF (s->scs.data); + + newtComponentAddCallback(s->co, callbackMarshall, &s->scs); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * widgetEntrySetValue(snackWidget * s, PyObject * args) { + char * val; + int cursorAtEnd = 1; + + if (!PyArg_ParseTuple(args, "s|i", &val, &cursorAtEnd)) + return NULL; + + newtEntrySet(s->co, val, cursorAtEnd); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * widgetEntrySetFlags(snackWidget * s, PyObject * args) { + int flag, sense; + + if (!PyArg_ParseTuple(args, "ii", &flag, &sense)) return NULL; + + newtEntrySetFlags(s->co, flag, sense); + + Py_INCREF(Py_None); + return Py_None; +} + + +static PyObject * widgetListboxAdd(snackWidget * s, PyObject * args) { + char * text; + + if (!PyArg_ParseTuple(args, "s", &text)) + return NULL; + + newtListboxAddEntry(s->co, text, I2P(s->anint)); + + return PyInt_FromLong(s->anint++); +} + +static PyObject * widgetListboxIns(snackWidget * s, PyObject * args) { + char * text; + int key; + + if (!PyArg_ParseTuple(args, "si", &text, &key)) + return NULL; + + newtListboxInsertEntry(s->co, text, I2P(s->anint), I2P(key)); + + return PyInt_FromLong(s->anint++); +} + +static PyObject * widgetListboxDel(snackWidget * s, PyObject * args) { + int key; + + if (!PyArg_ParseTuple(args, "i", &key)) + return NULL; + + newtListboxDeleteEntry(s->co, I2P(key)); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * widgetListboxGet(snackWidget * s, PyObject * args) { + if (!PyArg_ParseTuple(args, "")) + return NULL; + + return PyInt_FromLong((long) newtListboxGetCurrent(s->co)); +} + +static PyObject * widgetListboxGetSel(snackWidget * s, PyObject * args) { + void ** selection; + int numselected; + int i; + PyObject * sel, * int_obj; + + if (!PyArg_ParseTuple(args, "")) + return NULL; + + selection = (void **) newtListboxGetSelection(s->co, &numselected); + + sel = PyList_New(0); + + if (!selection) { + return sel; + } + + for (i = 0; i < numselected; i++) { + int_obj = PyInt_FromLong((long) selection[i]); + PyList_Append(sel, int_obj); + Py_DECREF(int_obj); + } + free(selection); + + return sel; +} + +static PyObject * widgetListboxSet(snackWidget * s, PyObject * args) { + int index; + + if (!PyArg_ParseTuple(args, "i", &index)) + return NULL; + + newtListboxSetCurrentByKey(s->co, I2P(index)); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * widgetListboxSetW(snackWidget * s, PyObject * args) { + int width; + + if (!PyArg_ParseTuple(args, "i", &width)) + return NULL; + + newtListboxSetWidth(s->co, width); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * widgetListboxClear(snackWidget * s, PyObject * args) { + if (!PyArg_ParseTuple(args, "")) + return NULL; + + newtListboxClear(s->co); + + Py_INCREF(Py_None); + return Py_None; +} + +static void emptyDestructor(PyObject * s) { +} + +static snackWidget * checkboxTreeWidget(PyObject * s, PyObject * args, PyObject * kwargs) { + int height; + int scrollBar = 0; + int hide_checkbox = 0; + int unselectable = 0; + int flags; + snackWidget * widget; + const char *kw[] = {"height", "scrollbar", "hide_checkbox", "unselectable", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|iii", (char **) kw, + &height, &scrollBar, &hide_checkbox, &unselectable)) + return NULL; + + flags = (scrollBar ? NEWT_FLAG_SCROLL : 0) | + (hide_checkbox ? NEWT_CHECKBOXTREE_HIDE_BOX : 0) | + (unselectable ? NEWT_CHECKBOXTREE_UNSELECTABLE : 0); + + widget = snackWidgetNew (); + if (!widget) + return NULL; + widget->co = newtCheckboxTree(-1, -1, height, flags); + + widget->anint = 1; + + return widget; +} + +static PyObject * widgetCheckboxTreeAddItem(snackWidget * s, PyObject * args) { + char * text; + int selected = 0; + PyObject * pathList, * o; + int len; + int * path; + int i; + + if (!PyArg_ParseTuple(args, "sOi", &text, &pathList, &selected)) + return NULL; + + len = PyTuple_Size(pathList); + path = alloca(sizeof(*path) * (len + 1)); + for (i = 0; i < len; i++) { + o = PyTuple_GetItem(pathList, i); + path[i] = PyInt_AsLong(o); + } + path[len] = NEWT_ARG_LAST; + + newtCheckboxTreeAddArray(s->co, text, I2P(s->anint), + selected ? NEWT_FLAG_SELECTED : 0, path); + + return PyInt_FromLong(s->anint++); +} + +static PyObject * widgetCheckboxTreeGetCur(snackWidget * s, PyObject * args) { + if (!PyArg_ParseTuple(args, "")) + return NULL; + + return PyInt_FromLong((long)newtCheckboxTreeGetCurrent(s->co)); +} + +static PyObject * widgetCheckboxTreeSetEntry(snackWidget * s, PyObject * args) { + int data; + char *text; + + if (!PyArg_ParseTuple(args, "is", &data, &text)) return NULL; + + newtCheckboxTreeSetEntry(s->co, I2P(data), text); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * widgetCheckboxTreeSetWidth(snackWidget * s, PyObject * args) { + int width; + + if (!PyArg_ParseTuple(args, "i", &width)) + return NULL; + + newtCheckboxTreeSetWidth(s->co, width); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * widgetCheckboxTreeSetCurrent(snackWidget * s, PyObject * args) { + int data; + + if (!PyArg_ParseTuple(args, "i", &data)) return NULL; + + newtCheckboxTreeSetCurrent(s->co, I2P(data)); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * widgetCheckboxTreeSetEntryValue(snackWidget * s, PyObject * args) { + int data; + int isOn = 1; + + if (!PyArg_ParseTuple(args, "i|i", &data, &isOn)) return NULL; + + newtCheckboxTreeSetEntryValue(s->co, I2P(data), + isOn ? NEWT_CHECKBOXTREE_SELECTED : + NEWT_CHECKBOXTREE_UNSELECTED); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * widgetCheckboxTreeGetEntryValue(snackWidget * s, PyObject * args) { + int data; + int isOn = 0; + int isBranch = 0; + char selection; + + if (!PyArg_ParseTuple(args, "i", &data)) return NULL; + + selection = newtCheckboxTreeGetEntryValue(s->co, I2P(data)); + + if (selection == -1) { + PyErr_SetString(PyExc_KeyError, "unknown entry"); + return NULL; + } + + switch (selection) { + case NEWT_CHECKBOXTREE_EXPANDED: + isOn = 1; + case NEWT_CHECKBOXTREE_COLLAPSED: + isBranch = 1; + break; + case NEWT_CHECKBOXTREE_UNSELECTED: + break; + default: + isOn = 1; + break; + } + return Py_BuildValue("(ii)", isBranch, isOn); +} + +static PyObject * widgetCheckboxTreeGetSel(snackWidget * s, + PyObject * args) { + void ** selection; + int numselected; + int i; + PyObject * sel, * int_obj; + + if (!PyArg_ParseTuple(args, "")) + return NULL; + + selection = (void **) newtCheckboxTreeGetSelection(s->co, &numselected); + + sel = PyList_New(0); + + if (!selection) { + return sel; + } + + for (i = 0; i < numselected; i++) { + int_obj = PyInt_FromLong((long) selection[i]); + PyList_Append(sel, int_obj); + Py_DECREF(int_obj); + } + free(selection); + + return sel; +} + +static PyObject * pywstrlen(PyObject * s, PyObject * args) +{ + char *str; + int len = -1; + + if (!PyArg_ParseTuple(args, "s|i", &str, &len)) return NULL; + + return PyInt_FromLong(wstrlen(str, len)); +} + +static void setitemstring_decref(PyObject * dict, + const char * s, PyObject * o) +{ + PyDict_SetItemString(dict, s, o); + Py_DECREF(o); +} + +MOD_INIT(_snack) +{ + PyObject * d, * m; + +#if PY_MAJOR_VERSION >= 3 + m = PyModule_Create(&moduledef); +#else + m = Py_InitModule("_snack", snackModuleMethods); +#endif + + if (!m) + return MOD_ERROR_VAL; + + d = PyModule_GetDict(m); + + setitemstring_decref(d, "ANCHOR_LEFT", PyInt_FromLong(NEWT_ANCHOR_LEFT)); + setitemstring_decref(d, "ANCHOR_TOP", PyInt_FromLong(NEWT_ANCHOR_TOP)); + setitemstring_decref(d, "ANCHOR_RIGHT", PyInt_FromLong(NEWT_ANCHOR_RIGHT)); + setitemstring_decref(d, "ANCHOR_BOTTOM", + PyInt_FromLong(NEWT_ANCHOR_BOTTOM)); + setitemstring_decref(d, "GRID_GROWX", PyInt_FromLong(NEWT_GRID_FLAG_GROWX)); + setitemstring_decref(d, "GRID_GROWY", PyInt_FromLong(NEWT_GRID_FLAG_GROWY)); + + setitemstring_decref(d, "FD_READ", PyInt_FromLong(NEWT_FD_READ)); + setitemstring_decref(d, "FD_WRITE", PyInt_FromLong(NEWT_FD_WRITE)); + setitemstring_decref(d, "FD_EXCEPT", PyInt_FromLong(NEWT_FD_EXCEPT)); + + setitemstring_decref(d, "FORM_EXIT_HOTKEY", PyString_FromString("hotkey")); + setitemstring_decref(d, "FORM_EXIT_WIDGET", PyString_FromString("widget")); + setitemstring_decref(d, "FORM_EXIT_TIMER", PyString_FromString("timer")); + setitemstring_decref(d, "FORM_EXIT_FDREADY", PyString_FromString("fdready")); + setitemstring_decref(d, "FORM_EXIT_ERROR", PyString_FromString("error")); + + setitemstring_decref(d, "KEY_TAB", PyInt_FromLong(NEWT_KEY_TAB)); + setitemstring_decref(d, "KEY_ENTER", PyInt_FromLong(NEWT_KEY_ENTER)); + setitemstring_decref(d, "KEY_SUSPEND", PyInt_FromLong(NEWT_KEY_SUSPEND)); + setitemstring_decref(d, "KEY_UP", PyInt_FromLong(NEWT_KEY_UP)); + setitemstring_decref(d, "KEY_DOWN", PyInt_FromLong(NEWT_KEY_DOWN)); + setitemstring_decref(d, "KEY_LEFT", PyInt_FromLong(NEWT_KEY_LEFT)); + setitemstring_decref(d, "KEY_RIGHT", PyInt_FromLong(NEWT_KEY_RIGHT)); + setitemstring_decref(d, "KEY_BACKSPACE", PyInt_FromLong(NEWT_KEY_BKSPC)); + setitemstring_decref(d, "KEY_DELETE", PyInt_FromLong(NEWT_KEY_DELETE)); + setitemstring_decref(d, "KEY_HOME", PyInt_FromLong(NEWT_KEY_HOME)); + setitemstring_decref(d, "KEY_END", PyInt_FromLong(NEWT_KEY_END)); + setitemstring_decref(d, "KEY_UNTAB", PyInt_FromLong(NEWT_KEY_UNTAB)); + setitemstring_decref(d, "KEY_PAGEUP", PyInt_FromLong(NEWT_KEY_PGUP)); + setitemstring_decref(d, "KEY_PAGEGDOWN", PyInt_FromLong(NEWT_KEY_PGDN)); + setitemstring_decref(d, "KEY_INSERT", PyInt_FromLong(NEWT_KEY_INSERT)); + setitemstring_decref(d, "KEY_F1", PyInt_FromLong(NEWT_KEY_F1)); + setitemstring_decref(d, "KEY_F2", PyInt_FromLong(NEWT_KEY_F2)); + setitemstring_decref(d, "KEY_F3", PyInt_FromLong(NEWT_KEY_F3)); + setitemstring_decref(d, "KEY_F4", PyInt_FromLong(NEWT_KEY_F4)); + setitemstring_decref(d, "KEY_F5", PyInt_FromLong(NEWT_KEY_F5)); + setitemstring_decref(d, "KEY_F6", PyInt_FromLong(NEWT_KEY_F6)); + setitemstring_decref(d, "KEY_F7", PyInt_FromLong(NEWT_KEY_F7)); + setitemstring_decref(d, "KEY_F8", PyInt_FromLong(NEWT_KEY_F8)); + setitemstring_decref(d, "KEY_F9", PyInt_FromLong(NEWT_KEY_F9)); + setitemstring_decref(d, "KEY_F10", PyInt_FromLong(NEWT_KEY_F10)); + setitemstring_decref(d, "KEY_F11", PyInt_FromLong(NEWT_KEY_F11)); + setitemstring_decref(d, "KEY_F12", PyInt_FromLong(NEWT_KEY_F12)); + setitemstring_decref(d, "KEY_ESC", PyInt_FromLong(NEWT_KEY_ESCAPE)); + setitemstring_decref(d, "KEY_RESIZE", PyInt_FromLong(NEWT_KEY_RESIZE)); + + setitemstring_decref(d, "FLAG_DISABLED", PyInt_FromLong(NEWT_FLAG_DISABLED)); + setitemstring_decref(d, "FLAGS_SET", PyInt_FromLong(NEWT_FLAGS_SET)); + setitemstring_decref(d, "FLAGS_RESET", PyInt_FromLong(NEWT_FLAGS_RESET)); + setitemstring_decref(d, "FLAGS_TOGGLE", PyInt_FromLong(NEWT_FLAGS_TOGGLE)); + + setitemstring_decref(d, "COLORSET_ROOT", PyInt_FromLong(NEWT_COLORSET_ROOT)); + setitemstring_decref(d, "COLORSET_BORDER", PyInt_FromLong(NEWT_COLORSET_BORDER)); + setitemstring_decref(d, "COLORSET_WINDOW", PyInt_FromLong(NEWT_COLORSET_WINDOW)); + setitemstring_decref(d, "COLORSET_SHADOW", PyInt_FromLong(NEWT_COLORSET_SHADOW)); + setitemstring_decref(d, "COLORSET_TITLE", PyInt_FromLong(NEWT_COLORSET_TITLE)); + setitemstring_decref(d, "COLORSET_BUTTON", PyInt_FromLong(NEWT_COLORSET_BUTTON)); + setitemstring_decref(d, "COLORSET_ACTBUTTON", PyInt_FromLong(NEWT_COLORSET_ACTBUTTON)); + setitemstring_decref(d, "COLORSET_CHECKBOX", PyInt_FromLong(NEWT_COLORSET_CHECKBOX)); + setitemstring_decref(d, "COLORSET_ACTCHECKBOX", PyInt_FromLong(NEWT_COLORSET_ACTCHECKBOX)); + setitemstring_decref(d, "COLORSET_ENTRY", PyInt_FromLong(NEWT_COLORSET_ENTRY)); + setitemstring_decref(d, "COLORSET_LABEL", PyInt_FromLong(NEWT_COLORSET_LABEL)); + setitemstring_decref(d, "COLORSET_LISTBOX", PyInt_FromLong(NEWT_COLORSET_LISTBOX)); + setitemstring_decref(d, "COLORSET_ACTLISTBOX", PyInt_FromLong(NEWT_COLORSET_ACTLISTBOX)); + setitemstring_decref(d, "COLORSET_TEXTBOX", PyInt_FromLong(NEWT_COLORSET_TEXTBOX)); + setitemstring_decref(d, "COLORSET_ACTTEXTBOX", PyInt_FromLong(NEWT_COLORSET_ACTTEXTBOX)); + setitemstring_decref(d, "COLORSET_HELPLINE", PyInt_FromLong(NEWT_COLORSET_HELPLINE)); + setitemstring_decref(d, "COLORSET_ROOTTEXT", PyInt_FromLong(NEWT_COLORSET_ROOTTEXT)); + setitemstring_decref(d, "COLORSET_EMPTYSCALE", PyInt_FromLong(NEWT_COLORSET_EMPTYSCALE)); + setitemstring_decref(d, "COLORSET_FULLSCALE", PyInt_FromLong(NEWT_COLORSET_FULLSCALE)); + setitemstring_decref(d, "COLORSET_DISENTRY", PyInt_FromLong(NEWT_COLORSET_DISENTRY)); + setitemstring_decref(d, "COLORSET_COMPACTBUTTON", PyInt_FromLong(NEWT_COLORSET_COMPACTBUTTON)); + setitemstring_decref(d, "COLORSET_ACTSELLISTBOX", PyInt_FromLong(NEWT_COLORSET_ACTSELLISTBOX)); + setitemstring_decref(d, "COLORSET_SELLISTBOX", PyInt_FromLong(NEWT_COLORSET_SELLISTBOX)); + + return MOD_SUCCESS_VAL(m); +} diff --git a/snack.py b/snack.py new file mode 100644 index 0000000..a9d2b44 --- /dev/null +++ b/snack.py @@ -0,0 +1,998 @@ +# snack.py: maps C extension module _snack to proper python types in module +# snack. +# The first section is a very literal mapping. +# The second section contains convenience classes that amalgamate +# the literal classes and make them more object-oriented. + +""" +This module provides the NEWT Windowing toolkit API for Python +This is a lightweight text-mode windowing library, based on slang. + +Classes: + + - Widget + - Button + - CompactButton + - Checkbox + - SingleRadioButton + - Listbox + - Textbox + - TextboxReflowed + - Label + - Scale + - Entry + - Form + - Grid + - SnackScreen + - RadioGroup + - RadioBar + - ButtonBar + - GridFormHelp + - GridForm + - CheckboxTree + - Clistbox + +Functions: + + - ListboxChoiceWindow + - ButtonChoiceWindow + - EntryWindow +""" + + +from __future__ import absolute_import, print_function, unicode_literals +import _snack +import string +import sys + +from _snack import FLAG_DISABLED, FLAGS_SET, FLAGS_RESET, FLAGS_TOGGLE, FD_READ, FD_WRITE, FD_EXCEPT + +LEFT = (-1, 0) +DOWN = (-1, -1) +CENTER = (0, 0) +UP = (1, 1) +RIGHT = (1, 0) + +snackArgs = {"append":-1} + +class Widget: + """Base class for NEWT toolkit - Do not use directly + + methods: + + - Widget(self) + - setCallback(self, obj, data = None) : + The callback for when object activated. + data is passed to obj. + """ + def setCallback(self, obj, data = None): + if data: + self.w.setCallback(obj, data) + else: + self.w.setCallback(obj) + + def __init__(self): + raise NotImplementedError + +class Button(Widget): + """Basic button class, takes button text as parameter + + method: + + - Button(self, text): returns a button + """ + def __init__(self, text): + self.w = _snack.button(text) + +class CompactButton(Widget): + """Compact Button class (less frilly button decoration). + + methods: + + - CompactButton(self,text) : create button, with text. + """ + def __init__(self, text): + self.w = _snack.compactbutton(text) + +class Checkbox(Widget): + """A checkbox. + + methods: + + - Checkbox(self, text, isOn = 0) : text, and boolean as to default value + - setValue(self) : set value + - value(self, value) : return checkbox value + - selected(self) : returns boolean + - setFlags(self, flag, sense) : set flags + + flags: FLAG_DISABLED, FLAGS_SET, FLAGS_RESET + """ + def value(self): + return self.w.checkboxValue + + def selected(self): + return self.w.checkboxValue != 0 + + def setFlags (self, flag, sense): + + return self.w.checkboxSetFlags(flag, sense) + + def setValue (self, value): + return self.w.checkboxSetValue(value) + + def __init__(self, text, isOn = 0): + self.w = _snack.checkbox(text, isOn) + +class SingleRadioButton(Widget): + """Single Radio Button. + + methods: + + - SingleRadioButton(text, group, isOn = 0) : create button + - selected(self) : returns bool, whether or not is selected. + """ + + def selected(self): + return self.w.key == self.w.radioValue; + + def __init__(self, text, group, isOn = 0): + if group: + self.w = _snack.radiobutton(text, group.w, isOn) + else: + self.w = _snack.radiobutton(text, None, isOn) + +class Listbox(Widget): + """Listbox class. + + methods: + + - Listbox(self, height, scroll = 0, returnExit = 0, width = 0, showCursor = 0, multiple = 0, border = 0) + - insert(self, text, item, before) : insert element; before = key to item to insert before, or None. + - delete(self, item) : delete item from list. + - replace(self, text,item) : Replace a given item's text + - current(self) : returns currently selected item + - getSelection(self) : returns a list of selected items + - setCurrent(self,i tem) : select current. + - clear(self) : clear listbox + """ + + def append(self, text, item): + key = self.w.listboxAddItem(text) + self.key2item[key] = item + self.item2key[item] = key + + def insert(self, text, item, before): + if (not before): + key = self.w.listboxInsertItem(text, 0) + else: + key = self.w.listboxInsertItem(text, self.item2key[before]) + self.key2item[key] = item + self.item2key[item] = key + + def delete(self, item): + self.w.listboxDeleteItem(self.item2key[item]) + del self.key2item[self.item2key[item]] + del self.item2key[item] + + def replace(self, text, item): + key = self.w.listboxInsertItem(text, self.item2key[item]) + self.w.listboxDeleteItem(self.item2key[item]) + del self.key2item[self.item2key[item]] + self.item2key[item] = key + self.key2item[key] = item + + def current(self): + return self.key2item[self.w.listboxGetCurrent()] + + def getSelection(self): + selection = [] + list = self.w.listboxGetSelection() + for key in list: + selection.append(self.key2item[key]) + return selection + + def setCurrent(self, item): + self.w.listboxSetCurrent(self.item2key[item]) + + def clear(self): + self.key2item = {} + self.item2key = {} + self.w.listboxClear() + + def __init__(self, height, scroll = 0, returnExit = 0, width = 0, showCursor = 0, multiple = 0, border = 0): + self.w = _snack.listbox(height, scroll, returnExit, showCursor, multiple, border) + self.key2item = {} + self.item2key = {} + if (width): + self.w.listboxSetWidth(width) + +class Textbox(Widget): + """Textbox, container for text. + + methods: + + - Textbox(self, width, height, scroll = 0, wrap = 0): scroll, wrap are flags + include scroll bars, or text wrap. + - setText(text) : set text. + - setHeight(height): set height. + """ + + def setText(self, text): + self.w.textboxText(text) + + def setHeight(self, height): + self.w.textboxHeight(height) + + def __init__(self, width, height, text, scroll = 0, wrap = 0): + self.w = _snack.textbox(width, height, text, scroll, wrap) + +class TextboxReflowed(Textbox): + + def __init__(self, width, text, flexDown = 5, flexUp = 10, maxHeight = -1): + (newtext, width, height) = reflow(text, width, flexDown, flexUp) + if maxHeight != -1 and height > maxHeight: + Textbox.__init__(self, width, maxHeight, newtext, 1) + else: + Textbox.__init__(self, width, height, newtext, 0) + +class Label(Widget): + """A Label (simple text). + + methods: + + - Label(self,text) : create label + - setText(self,text) : change text. + - setColors(self, colorset) : change individual colors + """ + def setText(self, text): + self.w.labelText(text) + + def __init__(self, text): + self.w = _snack.label(text) + + def setColors(self, colorset): + self.w.labelSetColors(colorset) + +class Scale(Widget): + """A Scale (progress bar). + + methods: + + - Scale(self,width, total) : create scale; width: size on screen, fullamount: integer. + - set(self,amount) : set amount to integer. + """ + def set(self, amount): + self.w.scaleSet(amount) + + def __init__(self, width, total): + self.w = _snack.scale(width, total) + +class Entry(Widget): + """Entry widget. + + methods: + + - Entry(self, width, text = "", hidden = 0, password = 0, scroll = 1, returnExit = 0) + constructor. hidden doesn't show text, password stars it out, + scroll includes scroll bars; + if returnExit is set, return from Form when exiting this element, else + proceed to next entry widget. + - value(self): return value. + - set(text, cursorAtEnd = 1) : set the text + - setFlags (flag, sense) : flags can be FLAG_DISABLED, FLAGS_SET, FLAGS_RESET, FLAGS_TOGGLE + """ + def value(self): + return self.w.entryValue + + def set(self, text, cursorAtEnd = 1): + return self.w.entrySetValue(text, cursorAtEnd) + + def setFlags (self, flag, sense): + return self.w.entrySetFlags(flag, sense) + + def __init__(self, width, text = "", hidden = 0, password = 0, scroll = 1, + returnExit = 0): + self.w = _snack.entry(width, text, hidden, password, scroll, returnExit) + + +# Form uses hotkeys +hotkeys = { "F1" : _snack.KEY_F1, "F2" : _snack.KEY_F2, "F3" : _snack.KEY_F3, + "F4" : _snack.KEY_F4, "F5" : _snack.KEY_F5, "F6" : _snack.KEY_F6, + "F7" : _snack.KEY_F7, "F8" : _snack.KEY_F8, "F9" : _snack.KEY_F9, + "F10" : _snack.KEY_F10, "F11" : _snack.KEY_F11, + "F12" : _snack.KEY_F12, "ESC" : _snack.KEY_ESC, + "ENTER": _snack.KEY_ENTER, "SUSPEND" : _snack.KEY_SUSPEND, + "BACKSPACE": _snack.KEY_BACKSPACE, "DELETE": _snack.KEY_DELETE, + "INSERT": _snack.KEY_INSERT, "RESIZE": _snack.KEY_RESIZE, + " " : ord(" ") } + +for n in list(hotkeys.keys()): + hotkeys[hotkeys[n]] = n +for o,c in [ (ord(c),c) for c in string.ascii_letters+string.digits ]: + hotkeys[c] = o + hotkeys[o] = c + +class Form: + """ Base Form class, from which Grid, etc. inherit + + methods: + + - Form(self, helpArg = None) : constructor. + - addHotKey(self, keyname) : keynames of form "F1" through "F12", "ESC" + - add(self, widget) : Add a widget + - run(self): run a form, expecting input + - draw(self): draw form. + - setTimer(self, timer) : add a timer + - watchFile(self, file, flags) : watch a named file + - setCurrent (self, co): Set a given widget as the current focus + """ + def addHotKey(self, keyname): + self.w.addhotkey(hotkeys[keyname]) + + def add(self, widget): + if 'hotkeys' in widget.__dict__: + for key in widget.hotkeys.keys(): + self.addHotKey(key) + + if 'gridmembers' in widget.__dict__: + for w in widget.gridmembers: + self.add(w) + elif 'w' in widget.__dict__: + self.trans[widget.w.key] = widget + return self.w.add(widget.w) + return None + + def run(self): + (what, which) = self.w.run() + if (what == _snack.FORM_EXIT_WIDGET): + return self.trans[which] + elif (what == _snack.FORM_EXIT_TIMER): + return "TIMER" + elif (what == _snack.FORM_EXIT_FDREADY): + return self.filemap[which] + elif (what == _snack.FORM_EXIT_HOTKEY): + return hotkeys[which] + raise RuntimeError("EOF or IO error") + + def draw(self): + self.w.draw() + return None + + def __init__(self, helpArg = None): + self.trans = {} + self.filemap = {} + self.w = _snack.form(helpArg) + # we do the reference count for the helpArg in python! gross + self.helpArg = helpArg + + def setCurrent (self, co): + self.w.setcurrent (co.w) + + def setTimer (self, timer): + self.w.settimer (timer) + + def watchFile (self, file, flags): + self.filemap[file.fileno()] = file + self.w.watchfd (file.fileno(), flags) + +class Grid: + """Grid class. + + methods: + + - place(self,x,y): Return what is placed at (x,y) + - setField(self, what, col, row, padding = (0, 0, 0, 0), + anchorLeft = 0, anchorTop = 0, anchorRight = 0, + anchorBottom = 0, growx = 0, growy = 0): + used to add widget 'what' to grid. + - Grid(self, *args): eg. g = Grid(2,3) for 2x3 grid + """ + def place(self, x, y): + return self.g.place(x, y) + + def setField(self, what, col, row, padding = (0, 0, 0, 0), + anchorLeft = 0, anchorTop = 0, anchorRight = 0, + anchorBottom = 0, growx = 0, growy = 0): + self.gridmembers.append(what) + anchorFlags = 0 + if (anchorLeft): + anchorFlags = _snack.ANCHOR_LEFT + elif (anchorRight): + anchorFlags = _snack.ANCHOR_RIGHT + + if (anchorTop): + anchorFlags = anchorFlags | _snack.ANCHOR_TOP + elif (anchorBottom): + anchorFlags = anchorFlags | _snack.ANCHOR_BOTTOM + + gridFlags = 0 + if (growx): + gridFlags = _snack.GRID_GROWX + if (growy): + gridFlags = gridFlags | _snack.GRID_GROWY + + if 'g' in what.__dict__: + return self.g.setfield(col, row, what.g, padding, anchorFlags, + gridFlags) + else: + return self.g.setfield(col, row, what.w, padding, anchorFlags) + + def __init__(self, *args): + self.g = _snack.grid(*args) + self.gridmembers = [] + +colorsets = { "ROOT" : _snack.COLORSET_ROOT, + "BORDER" : _snack.COLORSET_BORDER, + "WINDOW" : _snack.COLORSET_WINDOW, + "SHADOW" : _snack.COLORSET_SHADOW, + "TITLE" : _snack.COLORSET_TITLE, + "BUTTON" : _snack.COLORSET_BUTTON, + "ACTBUTTON" : _snack.COLORSET_ACTBUTTON, + "CHECKBOX" : _snack.COLORSET_CHECKBOX, + "ACTCHECKBOX" : _snack.COLORSET_ACTCHECKBOX, + "ENTRY" : _snack.COLORSET_ENTRY, + "LABEL" : _snack.COLORSET_LABEL, + "LISTBOX" : _snack.COLORSET_LISTBOX, + "ACTLISTBOX" : _snack.COLORSET_ACTLISTBOX, + "TEXTBOX" : _snack.COLORSET_TEXTBOX, + "ACTTEXTBOX" : _snack.COLORSET_ACTTEXTBOX, + "HELPLINE" : _snack.COLORSET_HELPLINE, + "ROOTTEXT" : _snack.COLORSET_ROOTTEXT, + "EMPTYSCALE" : _snack.COLORSET_EMPTYSCALE, + "FULLSCALE" : _snack.COLORSET_FULLSCALE, + "DISENTRY" : _snack.COLORSET_DISENTRY, + "COMPACTBUTTON" : _snack.COLORSET_COMPACTBUTTON, + "ACTSELLISTBOX" : _snack.COLORSET_ACTSELLISTBOX, + "SELLISTBOX" : _snack.COLORSET_SELLISTBOX } + +class SnackScreen: + """A Screen; + + methods: + + - Screen(self) : constructor + - finish(self) + - resume(self) + - suspend(self) + - doHelpCallback(self,arg) call callback with arg + - helpCallback(self,cb): Set help callback + - suspendcallback(self,cb, data=None) : set callback. data=data to pass to cb. + - openWindow(self,left, top, width, height, title): Open a window. + - pushHelpLine(self,text): put help line on screen. Returns current help line if text=None + - setColor(self, colorset, fg, bg): Set foreground and background colors; + colorset = key from snack.colorsets, + fg & bg = english color names defined by S-Lang + (ref: S-Lang Library C Programmer's Guide section: + 8.4.4. Setting Character Attributes) + """ + def __init__(self): + _snack.init() + (self.width, self.height) = _snack.size() + self.pushHelpLine(None) + + def finish(self): + return _snack.finish() + + def resume(self): + _snack.resume() + + def suspend(self): + _snack.suspend() + + def doHelpCallback(self, arg): + self.helpCb(self, arg) + + def helpCallback(self, cb): + self.helpCb = cb + return _snack.helpcallback(self.doHelpCallback) + + def suspendCallback(self, cb, data = None): + if data: + return _snack.suspendcallback(cb, data) + return _snack.suspendcallback(cb) + + def openWindow(self, left, top, width, height, title): + return _snack.openwindow(left, top, width, height, title) + + def pushHelpLine(self, text): + if (not text): + return _snack.pushhelpline("*default*") + else: + return _snack.pushhelpline(text) + + def popHelpLine(self): + return _snack.pophelpline() + + def drawRootText(self, left, top, text): + return _snack.drawroottext(left, top, text) + + def centeredWindow(self, width, height, title): + return _snack.centeredwindow(width, height, title) + + def gridWrappedWindow(self, grid, title, x = None, y = None): + if x and y: + return _snack.gridwrappedwindow(grid.g, title, x, y) + + return _snack.gridwrappedwindow(grid.g, title) + + def popWindow(self, refresh = True): + if refresh: + return _snack.popwindow() + return _snack.popwindownorefresh() + + def refresh(self): + return _snack.refresh() + + def setColor(self, colorset, fg, bg): + if colorset in colorsets: + return _snack.setcolor(colorsets[colorset], fg, bg) + else: + # assume colorset is an integer for the custom color set + return _snack.setcolor(colorset, fg, bg) + +def reflow(text, width, flexDown = 5, flexUp = 5): + """ returns a tuple of the wrapped text, the actual width, and the actual height + """ + return _snack.reflow(text, width, flexDown, flexUp) + +# combo widgets + +class RadioGroup(Widget): + """ Combo widget: Group of Radio buttons + + methods: + + - RadioGroup(self): constructor. + - add(self,title, value, default = None): add a button. Returns button. + - getSelection(self) : returns value of selected button | None + """ + def __init__(self): + self.prev = None + self.buttonlist = [] + + def add(self, title, value, default = None): + if not self.prev and default == None: + # If the first element is not explicitly set to + # not be the default, make it be the default + default = 1 + b = SingleRadioButton(title, self.prev, default) + self.prev = b + self.buttonlist.append((b, value)) + return b + + def getSelection(self): + for (b, value) in self.buttonlist: + if b.selected(): return value + return None + + +class RadioBar(Grid): + """ Bar of Radio buttons, based on Grid. + + methods: + + - RadioBar(self, screen, buttonlist) : constructor. + - getSelection(self): return value of selected button + """ + + def __init__(self, screen, buttonlist): + self.list = [] + self.item = 0 + self.group = RadioGroup() + Grid.__init__(self, 1, len(buttonlist)) + for (title, value, default) in buttonlist: + b = self.group.add(title, value, default) + self.list.append((b, value)) + self.setField(b, 0, self.item, anchorLeft = 1) + self.item = self.item + 1 + + def getSelection(self): + return self.group.getSelection() + + +# you normally want to pack a ButtonBar with growx = 1 + +class ButtonBar(Grid): + """ Bar of buttons, based on grid. + + methods: + + - ButtonBar(screen, buttonlist,buttonlist, compact = 0): + - buttonPressed(self, result): Takes the widget returned by Form.run and looks to see + if it was one of the widgets in the ButtonBar. + """ + def __init__(self, screen, buttonlist, compact = 0): + self.list = [] + self.hotkeys = {} + self.item = 0 + Grid.__init__(self, len(buttonlist), 1) + for blist in buttonlist: + if isinstance(blist, str if sys.version >= '3' else basestring): + title = blist + value = blist.lower() + elif len(blist) == 2: + (title, value) = blist + else: + (title, value, hotkey) = blist + self.hotkeys[hotkey] = value + + if compact: + b = CompactButton(title) + else: + b = Button(title) + self.list.append((b, value)) + self.setField(b, self.item, 0, (1, 0, 1, 0)) + self.item = self.item + 1 + + def buttonPressed(self, result): + if result in self.hotkeys: + return self.hotkeys[result] + + for (button, value) in self.list: + if result == button: + return value + return None + + +class GridFormHelp(Grid): + """ Subclass of Grid, for the help form text. + + methods: + + - GridFormHelp(self, screen, title, help, *args) : + - add (self, widget, col, row, padding = (0, 0, 0, 0), + anchorLeft = 0, anchorTop = 0, anchorRight = 0, + anchorBottom = 0, growx = 0, growy = 0): + - runOnce(self, x = None, y = None): pop up the help window + - addHotKey(self, keyname): + - setTimer(self, keyname): + - create(self, x = None, y = None): + - run(self, x = None, y = None): + - draw(self): + - runPopup(self): + - setCurrent (self, co): + """ + def __init__(self, screen, title, help, *args): + self.screen = screen + self.title = title + self.form = Form(help) + self.childList = [] + self.form_created = 0 + args = list(args) + args[:0] = [self] + Grid.__init__(*tuple(args)) + + def add(self, widget, col, row, padding = (0, 0, 0, 0), + anchorLeft = 0, anchorTop = 0, anchorRight = 0, + anchorBottom = 0, growx = 0, growy = 0): + self.setField(widget, col, row, padding, anchorLeft, + anchorTop, anchorRight, anchorBottom, + growx, growy); + self.childList.append(widget) + + def runOnce(self, x = None, y = None): + result = self.run(x, y) + self.screen.popWindow() + return result + + def addHotKey(self, keyname): + self.form.addHotKey(keyname) + + def setTimer(self, keyname): + self.form.setTimer(keyname) + + def create(self, x = None, y = None): + if not self.form_created: + self.place(1,1) + for child in self.childList: + self.form.add(child) + self.screen.gridWrappedWindow(self, self.title, x, y) + self.form_created = 1 + + def run(self, x = None, y = None): + self.create(x, y) + return self.form.run() + + def draw(self): + self.create() + return self.form.draw() + + def runPopup(self): + self.create() + self.screen.gridWrappedWindow(self, self.title) + result = self.form.run() + self.screen.popWindow() + return result + + def setCurrent (self, co): + self.form.setCurrent (co) + +class GridForm(GridFormHelp): + """ GridForm class (extends GridFormHelp): + + methods: + + - GridForm(self, screen, title, *args): + """ + def __init__(self, screen, title, *args): + myargs = (self, screen, title, None) + args + GridFormHelp.__init__(*myargs) + +class CheckboxTree(Widget): + """ CheckboxTree combo widget, + + methods: + + - CheckboxTree(self, height, scroll = 0, width = None, hide_checkbox = 0, unselectable = 0) + constructor. + - append(self, text, item = None, selected = 0): + - addItem(self, text, path, item = None, selected = 0): + - getCurrent(self): + - getSelection(self): + - setEntry(self, item, text): + - setCurrent(self, item): + - setEntryValue(self, item, selected = 1): + - getEntryValue(self, item): + """ + def append(self, text, item = None, selected = 0): + self.addItem(text, (snackArgs['append'], ), item, selected) + + def addItem(self, text, path, item = None, selected = 0): + if item is None: + item = text + key = self.w.checkboxtreeAddItem(text, path, selected) + self.key2item[key] = item + self.item2key[item] = key + + def getCurrent(self): + curr = self.w.checkboxtreeGetCurrent() + return self.key2item[curr] + + def __init__(self, height, scroll = 0, width = None, hide_checkbox = 0, unselectable = 0): + self.w = _snack.checkboxtree(height, scroll, hide_checkbox, unselectable) + self.key2item = {} + self.item2key = {} + if (width): + self.w.checkboxtreeSetWidth(width) + + def getSelection(self): + selection = [] + list = self.w.checkboxtreeGetSelection() + for key in list: + selection.append(self.key2item[key]) + return selection + + def setEntry(self, item, text): + self.w.checkboxtreeSetEntry(self.item2key[item], text) + + def setCurrent(self, item): + self.w.checkboxtreeSetCurrent(self.item2key[item]) + + def setEntryValue(self, item, selected = 1): + self.w.checkboxtreeSetEntryValue(self.item2key[item], selected) + + def getEntryValue(self, item): + return self.w.checkboxtreeGetEntryValue(self.item2key[item]) + +def ListboxChoiceWindow(screen, title, text, items, + buttons = ('Ok', 'Cancel'), + width = 40, scroll = 0, height = -1, default = None, + help = None): + """ + - ListboxChoiceWindow(screen, title, text, items, + buttons = ('Ok', 'Cancel'), + width = 40, scroll = 0, height = -1, default = None, + help = None): + """ + if (height == -1): height = len(items) + + bb = ButtonBar(screen, buttons) + t = TextboxReflowed(width, text) + l = Listbox(height, scroll = scroll, returnExit = 1) + count = 0 + for item in items: + if type(item) == tuple: + (text, key) = item + else: + text = item + key = count + + if (default == count): + default = key + elif (default == item): + default = key + + l.append(text, key) + count = count + 1 + + if (default != None): + l.setCurrent (default) + + g = GridFormHelp(screen, title, help, 1, 3) + g.add(t, 0, 0) + g.add(l, 0, 1, padding = (0, 1, 0, 1)) + g.add(bb, 0, 2, growx = 1) + + rc = g.runOnce() + + return (bb.buttonPressed(rc), l.current()) + +def ButtonChoiceWindow(screen, title, text, + buttons = [ 'Ok', 'Cancel' ], + width = 40, x = None, y = None, help = None): + """ + - ButtonChoiceWindow(screen, title, text, + buttons = [ 'Ok', 'Cancel' ], + width = 40, x = None, y = None, help = None): + """ + bb = ButtonBar(screen, buttons) + t = TextboxReflowed(width, text, maxHeight = screen.height - 12) + + g = GridFormHelp(screen, title, help, 1, 2) + g.add(t, 0, 0, padding = (0, 0, 0, 1)) + g.add(bb, 0, 1, growx = 1) + return bb.buttonPressed(g.runOnce(x, y)) + +def EntryWindow(screen, title, text, prompts, allowCancel = 1, width = 40, + entryWidth = 20, buttons = [ 'Ok', 'Cancel' ], help = None): + """ + EntryWindow(screen, title, text, prompts, allowCancel = 1, width = 40, + entryWidth = 20, buttons = [ 'Ok', 'Cancel' ], help = None): + """ + bb = ButtonBar(screen, buttons); + t = TextboxReflowed(width, text) + + count = 0 + for n in prompts: + count = count + 1 + + sg = Grid(2, count) + + count = 0 + entryList = [] + for n in prompts: + if type(n) == tuple: + (n, e) = n + if isinstance(e, str if sys.version >= '3' else basestring): + e = Entry(entryWidth, e) + else: + e = Entry(entryWidth) + + sg.setField(Label(n), 0, count, padding = (0, 0, 1, 0), anchorLeft = 1) + sg.setField(e, 1, count, anchorLeft = 1) + count = count + 1 + entryList.append(e) + + g = GridFormHelp(screen, title, help, 1, 3) + + g.add(t, 0, 0, padding = (0, 0, 0, 1)) + g.add(sg, 0, 1, padding = (0, 0, 0, 1)) + g.add(bb, 0, 2, growx = 1) + + result = g.runOnce() + + entryValues = [] + count = 0 + for n in prompts: + entryValues.append(entryList[count].value()) + count = count + 1 + + return (bb.buttonPressed(result), tuple(entryValues)) + +class CListbox(Grid): + """Clistbox convenience class. + + methods: + + - Clistbox(self, height, cols, cols_widths, scroll = 0) : constructor + - colFormText(self, col_text, align = None, adjust_width = 0) : column text. + - append(self, col_text, item, col_text_align = None) : + - insert(self, col_text, item, before, col_text_align = None) + - delete(self, item) + - replace(self, col_text, item, col_text_align = None) + - current(self) : returns current item + - setCurrent(self, item): sets an item as current + - clear(self): clear the listbox + + Alignments may be LEFT, RIGHT, CENTER, None + """ + def __init__(self, height, cols, col_widths, scroll = 0, + returnExit = 0, width = 0, col_pad = 1, + col_text_align = None, col_labels = None, + col_label_align = None, adjust_width=0): + + self.cols = cols + self.col_widths = col_widths[:] + self.col_pad = col_pad + self.col_text_align = col_text_align + + if col_labels != None: + Grid.__init__(self, 1, 2) + box_y = 1 + + lstr = self.colFormText(col_labels, col_label_align, + adjust_width=adjust_width) + self.label = Label(lstr) + self.setField(self.label, 0, 0, anchorLeft=1) + + else: + Grid.__init__(self, 1, 1) + box_y = 0 + + + self.listbox = Listbox(height, scroll, returnExit, width) + self.setField(self.listbox, 0, box_y, anchorRight=1) + + def colFormText(self, col_text, align = None, adjust_width=0): + i = 0 + str = "" + c_len = len(col_text) + while (i < self.cols) and (i < c_len): + + cstr = col_text[i] + cstrlen = _snack.wstrlen(cstr) + if self.col_widths[i] < cstrlen: + if adjust_width: + self.col_widths[i] = cstrlen + else: + cstr = cstr[:self.col_widths[i]] + + delta = self.col_widths[i] - _snack.wstrlen(cstr) + + if delta > 0: + if align == None: + a = LEFT + else: + a = align[i] + + if a == LEFT: + cstr = cstr + (" " * delta) + if a == CENTER: + cstr = (" " * (delta / 2)) + cstr + \ + (" " * ((delta + 1) / 2)) + if a == RIGHT: + cstr = (" " * delta) + cstr + + if i != c_len - 1: + pstr = (" " * self.col_pad) + else: + pstr = "" + + str = str + cstr + pstr + + i = i + 1 + + return str + + def append(self, col_text, item, col_text_align = None): + if col_text_align == None: + col_text_align = self.col_text_align + text = self.colFormText(col_text, col_text_align) + self.listbox.append(text, item) + + def insert(self, col_text, item, before, col_text_align = None): + if col_text_align == None: + col_text_align = self.col_text_align + text = self.colFormText(col_text, col_text_align) + self.listbox.insert(text, item, before) + + def delete(self, item): + self.listbox.delete(item) + + def replace(self, col_text, item, col_text_align = None): + if col_text_align == None: + col_text_align = self.col_text_align + text = self.colFormText(col_text, col_text_align) + self.listbox.replace(text, item) + + def current(self): + return self.listbox.current() + + def setCurrent(self, item): + self.listbox.setCurrent(item) + + def clear(self): + self.listbox.clear() + +def customColorset(x): + return 30 + x diff --git a/test.c b/test.c new file mode 100644 index 0000000..5a6958c --- /dev/null +++ b/test.c @@ -0,0 +1,161 @@ +#include +#include +#include +#include + +#include "newt.h" + +struct callbackInfo { + newtComponent en; + char * state; +}; + +void disableCallback(newtComponent co, void * data) { + struct callbackInfo * cbi = data; + + if (*cbi->state == ' ') { + newtEntrySetFlags(cbi->en, NEWT_FLAG_DISABLED, NEWT_FLAGS_RESET); + } else { + newtEntrySetFlags(cbi->en, NEWT_FLAG_DISABLED, NEWT_FLAGS_SET); + } + + newtRefresh(); +} + +void suspend(void * d) { + newtSuspend(); + raise(SIGTSTP); + newtResume(); +} + +void helpCallback(newtComponent co, void * tag) { + newtWinMessage("Help", "Ok", tag); +} + +int main(void) { + newtComponent b1, b2, r1, r2, r3, e2, e3, l1, l2, l3, scale; + newtComponent lb, t, rsf, timeLabel; + newtComponent cs[10]; + newtComponent f, chklist, e1; + struct callbackInfo cbis[3]; + char results[10]; + const char * enr2, * enr3, *scaleVal; + void ** selectedList; + int i, numsel; + char buf[20]; + const char * spinner = "-\\|/"; + const char * spinState; + struct newtExitStruct es; + + newtInit(); + newtCls(); + + newtSetSuspendCallback(suspend, NULL); + newtSetHelpCallback(helpCallback); + + newtDrawRootText(0, 0, "Newt test program"); + newtPushHelpLine(NULL); + newtDrawRootText(-50, 0, "More root text"); + + newtOpenWindow(2, 2, 30, 10, "first window"); + newtOpenWindow(10, 5, 65, 16, "window 2"); + + f = newtForm(NULL, "This is some help text", 0); + chklist = newtForm(NULL, NULL, 0); + + b1 = newtButton(3, 1, "Exit"); + b2 = newtButton(18, 1, "Update"); + r1 = newtRadiobutton(20, 10, "Choice 1", 0, NULL); + r2 = newtRadiobutton(20, 11, "Choice 2", 1, r1); + r3 = newtRadiobutton(20, 12, "Choice 3", 0, r2); + rsf = newtForm(NULL, NULL, 0); + newtFormAddComponents(rsf, r1, r2, r3, NULL); + newtFormSetBackground(rsf, NEWT_COLORSET_CHECKBOX); + + for (i = 0; i < 10; i++) { + sprintf(buf, "Check %d", i); + cs[i] = newtCheckbox(3, 10 + i, buf, ' ', NULL, &results[i]); + newtFormAddComponent(chklist, cs[i]); + } + + l1 = newtLabel(3, 6, "Scale:"); + l2 = newtLabel(3, 7, "Scrolls:"); + l3 = newtLabel(3, 8, "Hidden:"); + e1 = newtEntry(12, 6, "", 20, &scaleVal, 0); + e2 = newtEntry(12, 7, "Default", 20, &enr2, NEWT_FLAG_SCROLL); +/* e3 = newtEntry(12, 8, NULL, 20, &enr3, NEWT_FLAG_HIDDEN); */ + e3 = newtEntry(12, 8, NULL, 20, &enr3, NEWT_FLAG_PASSWORD); + + cbis[0].state = &results[0]; + cbis[0].en = e1; + newtComponentAddCallback(cs[0], disableCallback, &cbis[0]); + + scale = newtScale(3, 14, 32, 100); + + newtFormSetHeight(chklist, 3); + + newtFormAddComponents(f, b1, b2, l1, l2, l3, e1, e2, e3, chklist, NULL); + newtFormAddComponents(f, rsf, scale, NULL); + + lb = newtListbox(45, 1, 6, NEWT_FLAG_MULTIPLE | NEWT_FLAG_BORDER | + NEWT_FLAG_SCROLL | NEWT_FLAG_SHOWCURSOR); + newtListboxAppendEntry(lb, "First", (void *) 1); + newtListboxAppendEntry(lb, "Second", (void *) 2); + newtListboxAppendEntry(lb, "Third", (void *) 3); + newtListboxAppendEntry(lb, "Fourth", (void *) 4); + newtListboxAppendEntry(lb, "Sixth", (void *) 6); + newtListboxAppendEntry(lb, "Seventh", (void *) 7); + newtListboxAppendEntry(lb, "Eighth", (void *) 8); + newtListboxAppendEntry(lb, "Ninth", (void *) 9); + newtListboxAppendEntry(lb, "Tenth", (void *) 10); + + newtListboxInsertEntry(lb, "Fifth", (void *) 5, (void *) 4); + newtListboxInsertEntry(lb, "Eleventh", (void *) 11, (void *) 10); + newtListboxDeleteEntry(lb, (void *) 11); + + spinState = spinner; + timeLabel = newtLabel(45, 8, "Spinner: -"); + + t = newtTextbox(45, 10, 17, 5, NEWT_FLAG_WRAP); + newtTextboxSetText(t, "This is some text does it look okay?\nThis should be alone.\nThis shouldn't be printed"); + + newtFormAddComponents(f, lb, timeLabel, t, NULL); + newtRefresh(); + newtFormSetTimer(f, 200); + + do { + newtFormRun(f, &es); + + if (es.reason == NEWT_EXIT_COMPONENT && es.u.co == b2) { + newtScaleSet(scale, atoi(scaleVal)); + newtRefresh(); + } else if (es.reason == NEWT_EXIT_TIMER) { + spinState++; + if (!*spinState) spinState = spinner; + sprintf(buf, "Spinner: %c", *spinState); + newtLabelSetText(timeLabel, buf); + } + } while (es.reason != NEWT_EXIT_COMPONENT || es.u.co == b2); + + numsel = 0; + selectedList = newtListboxGetSelection(lb, &numsel); + + newtPopWindow(); + newtPopWindow(); + newtFinished(); + + printf("got string 1: %s\n", scaleVal); + printf("got string 2: %s\n", enr2); + printf("got string 3: %s\n", enr3); + + newtFormDestroy(f); + + printf("\nSelected listbox items (%d):\n", numsel); + if(selectedList) { + for(i = 0; i < numsel; i++) + printf("#%d\n", (int)(long) selectedList[i]); + } + free(selectedList); + + return 0; +} diff --git a/testgrid.c b/testgrid.c new file mode 100644 index 0000000..7cc9dd7 --- /dev/null +++ b/testgrid.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include + +#include "newt.h" + +int main(void) { + newtComponent b1, b2, b3, b4; + newtComponent f, t; + newtGrid grid, subgrid; + char * flowedText; + int textWidth, textHeight, rc, i; + char * menuContents[] = { "One", "Two", "Three", "Four", "Five", NULL }; + char * entries[10]; + struct newtWinEntry autoEntries[] = { + { "An entry", entries + 0, 0 }, + { "Another entry", entries + 1, 0 }, + { "Third entry", entries + 2, 0 }, + { "Fourth entry", entries + 3, 0 }, + { NULL, NULL, 0 } }; + + memset(entries, 0, sizeof(entries)); + + newtInit(); + newtCls(); + + b1 = newtCheckbox(-1, -1, "An pretty long checkbox for testing", ' ', NULL, NULL); + b2 = newtButton(-1, -1, "Another Button"); + b3 = newtButton(-1, -1, "But, but"); + b4 = newtButton(-1, -1, "But what?"); + + f = newtForm(NULL, NULL, 0); + + grid = newtCreateGrid(2, 2); + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, b1, 0, 0, 0, 0, + NEWT_ANCHOR_RIGHT, 0); + newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, b2, 0, 0, 0, 0, 0, 0); + newtGridSetField(grid, 1, 0, NEWT_GRID_COMPONENT, b3, 0, 0, 0, 0, 0, 0); + newtGridSetField(grid, 1, 1, NEWT_GRID_COMPONENT, b4, 0, 0, 0, 0, 0, 0); + + + newtFormAddComponents(f, b1, b2, b3, b4, NULL); + + newtGridWrappedWindow(grid, "first window"); + newtGridFree(grid, 1); + + newtRunForm(f); + + newtFormDestroy(f); + newtPopWindow(); + + flowedText = newtReflowText("This is a quite a bit of text. It is 40 " + "columns long, so some wrapping should be " + "done. Did you know that the quick, brown " + "fox jumped over the lazy dog?\n\n" + "In other news, it's pretty important that we " + "can properly force a line break.", + 40, 5, 5, &textWidth, &textHeight); + t = newtTextbox(-1, -1, textWidth, textHeight, NEWT_FLAG_WRAP); + newtTextboxSetText(t, flowedText); + free(flowedText); + + + b1 = newtButton(-1, -1, "Okay"); + b2 = newtButton(-1, -1, "Cancel"); + + grid = newtCreateGrid(1, 2); + subgrid = newtCreateGrid(2, 1); + + newtGridSetField(subgrid, 0, 0, NEWT_GRID_COMPONENT, b1, 0, 0, 0, 0, 0, 0); + newtGridSetField(subgrid, 1, 0, NEWT_GRID_COMPONENT, b2, 0, 0, 0, 0, 0, 0); + + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, t, 0, 0, 0, 1, 0, 0); + newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, subgrid, 0, 0, 0, 0, 0, + NEWT_GRID_FLAG_GROWX); + newtGridWrappedWindow(grid, "another example"); + newtGridDestroy(grid, 1); + + f = newtForm(NULL, NULL, 0); + newtFormAddComponents(f, b1, t, b2, NULL); + newtRunForm(f); + + newtPopWindow(); + newtFormDestroy(f); + + newtWinMessage("Simple", "Ok", "This is a simple message window"); + newtWinChoice("Simple", "Ok", "Cancel", "This is a simple choice window"); + + textWidth = 0; + rc = newtWinMenu("Test Menu", "This is a sample invovation of the " + "newtWinMenu() call. It may or may not have a scrollbar, " + "depending on the need for one.", 50, 5, 5, 3, + menuContents, &textWidth, "Ok", "Cancel", NULL); + + rc = newtWinEntries("Text newtWinEntries()", "This is a sample invovation of " + "newtWinEntries() call. It lets you get a lot of input " + "quite easily.", 50, 5, 5, 20, autoEntries, "Ok", + "Cancel", NULL); + for (i = 0; i < sizeof (autoEntries) / sizeof (struct newtWinEntry) && autoEntries[i].value; i++) + free(*(autoEntries[i].value)); + + newtFinished(); + + printf("rc = 0x%x item = %d\n", rc, textWidth); + + return 0; +} diff --git a/testtree.c b/testtree.c new file mode 100644 index 0000000..0ae65c5 --- /dev/null +++ b/testtree.c @@ -0,0 +1,146 @@ +#include +#include +#include +#include + +#include "newt.h" + +int main(void) { + newtGrid grid; + newtComponent checktree; + newtComponent button; + newtComponent form; + const void **result, **ptr; + int numselected, i, j; + int * list; + + newtInit(); + newtCls(); + + checktree = newtCheckboxTreeMulti(-1, -1, 10, " ab", NEWT_FLAG_SCROLL); + newtCheckboxTreeAddItem(checktree, "Numbers", (void *) 2, 0, + NEWT_ARG_APPEND, NEWT_ARG_LAST); + newtCheckboxTreeAddItem(checktree, "Really really long thing", + (void *) 3, 0, NEWT_ARG_APPEND, NEWT_ARG_LAST); + newtCheckboxTreeAddItem(checktree, "number 5", (void *) 5, + NEWT_FLAG_SELECTED, + NEWT_ARG_APPEND, NEWT_ARG_LAST); + newtCheckboxTreeAddItem(checktree, "number 6", (void *) 6, 0, + NEWT_ARG_APPEND, NEWT_ARG_LAST); + newtCheckboxTreeAddItem(checktree, "number 7", (void *) 7, + NEWT_FLAG_SELECTED, + NEWT_ARG_APPEND, NEWT_ARG_LAST); + newtCheckboxTreeAddItem(checktree, "number 8", (void *) 8, 0, + NEWT_ARG_APPEND, NEWT_ARG_LAST); + newtCheckboxTreeAddItem(checktree, "number 9", (void *) 9, 0, + NEWT_ARG_APPEND, NEWT_ARG_LAST); + newtCheckboxTreeAddItem(checktree, "number 10", (void *) 10, + NEWT_FLAG_SELECTED, + NEWT_ARG_APPEND, NEWT_ARG_LAST); + newtCheckboxTreeAddItem(checktree, "number 11", (void *) 11, 0, + NEWT_ARG_APPEND, NEWT_ARG_LAST); + newtCheckboxTreeAddItem(checktree, "Donuts", (void *) 12, + NEWT_FLAG_SELECTED, + NEWT_ARG_APPEND, NEWT_ARG_LAST); + + newtCheckboxTreeAddItem(checktree, "Bavarian Cream", (void *) 301, + NEWT_FLAG_SELECTED, + 9, NEWT_ARG_APPEND, NEWT_ARG_LAST); + newtCheckboxTreeAddItem(checktree, "Honey dipped", (void *) 302, + NEWT_FLAG_SELECTED, + 9, NEWT_ARG_APPEND, NEWT_ARG_LAST); + newtCheckboxTreeAddItem(checktree, "Jelly", (void *) 303, + NEWT_FLAG_SELECTED, + 9, NEWT_ARG_APPEND, NEWT_ARG_LAST); + + newtCheckboxTreeAddItem(checktree, "Colors", (void *) 1, 0, + 0, NEWT_ARG_LAST); + newtCheckboxTreeAddItem(checktree, "Red", (void *) 100, 0, + 0, NEWT_ARG_APPEND, NEWT_ARG_LAST); + newtCheckboxTreeAddItem(checktree, "White", (void *) 101, 0, + 0, NEWT_ARG_APPEND, NEWT_ARG_LAST); + newtCheckboxTreeAddItem(checktree, "Blue", (void *) 102, 0, + 0, NEWT_ARG_APPEND, NEWT_ARG_LAST); + + newtCheckboxTreeAddItem(checktree, "number 4", (void *) 4, 0, + 3, NEWT_ARG_LAST); + + newtCheckboxTreeAddItem(checktree, "Single digit", (void *) 200, 0, + 1, NEWT_ARG_APPEND, NEWT_ARG_LAST); + newtCheckboxTreeAddItem(checktree, "One", (void *) 201, 0, + 1, 0, NEWT_ARG_APPEND, NEWT_ARG_LAST); + newtCheckboxTreeAddItem(checktree, "Two", (void *) 202, 0, + 1, 0, NEWT_ARG_APPEND, NEWT_ARG_LAST); + newtCheckboxTreeAddItem(checktree, "Three", (void *) 203, 0, + 1, 0, NEWT_ARG_APPEND, NEWT_ARG_LAST); + newtCheckboxTreeAddItem(checktree, "Four", (void *) 204, 0, + 1, 0, NEWT_ARG_APPEND, NEWT_ARG_LAST); + + newtCheckboxTreeAddItem(checktree, "Double digit", (void *) 300, 0, + 1, NEWT_ARG_APPEND, NEWT_ARG_LAST); + newtCheckboxTreeAddItem(checktree, "Ten", (void *) 210, 0, + 1, 1, NEWT_ARG_APPEND, NEWT_ARG_LAST); + newtCheckboxTreeAddItem(checktree, "Eleven", (void *) 211, 0, + 1, 1, NEWT_ARG_APPEND, NEWT_ARG_LAST); + newtCheckboxTreeAddItem(checktree, "Twelve", (void *) 212, 0, + 1, 1, NEWT_ARG_APPEND, NEWT_ARG_LAST); + newtCheckboxTreeAddItem(checktree, "Thirteen", (void *) 213, 0, + 1, 1, NEWT_ARG_APPEND, NEWT_ARG_LAST); + + newtCheckboxTreeSetCurrent(checktree, (void *) 12); + + button = newtButton(-1, -1, "Exit"); + + grid = newtCreateGrid(1, 2); + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, checktree, 0, 0, 0, 1, + NEWT_ANCHOR_RIGHT, 0); + newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, button, 0, 0, 0, 0, + 0, 0); + + newtGridWrappedWindow(grid, "Checkbox Tree Test"); + newtGridFree(grid, 1); + + form = newtForm(NULL, NULL, 0); + newtFormAddComponents(form, checktree, button, NULL); + + newtRunForm(form); + + newtFinished(); + + result = newtCheckboxTreeGetSelection(checktree, &numselected); + ptr = result; + if (!result || !numselected) + printf("none selected\n"); + else + printf("Current selection (all) (%d):\n", numselected); + for (i = 0; i < numselected; i++) { + j = (long) *ptr++; + printf("%d\n", j); + } + free(result); + + result = newtCheckboxTreeGetMultiSelection(checktree, &numselected, 'b'); + ptr = result; + if (!result || !numselected) + printf("none selected\n"); + else + printf("Current selection (b) (%d):\n",numselected); + for (i = 0; i < numselected; i++) { + j = (long) *ptr++; + printf("%d\n", j); + } + + if (result) + free(result); + + list = newtCheckboxTreeFindItem(checktree, (void *) 213); + printf("path:"); + for (i = 0; list && list[i] != NEWT_ARG_LAST; i++) + printf(" %d", list[i]); + printf("\n"); + free(list); + + newtFormDestroy(form); + + return 0; +} diff --git a/textbox.c b/textbox.c new file mode 100644 index 0000000..b6fedd6 --- /dev/null +++ b/textbox.c @@ -0,0 +1,485 @@ + +#include +#include +#include +#include +#include +#include + +#include "newt.h" +#include "newt_pr.h" + +struct textbox { + char ** lines; + int numLines; + int linesAlloced; + int doWrap; + newtComponent sb; + int topLine; + int textWidth; + int isActive; + int cs; + int csActive; +}; + +static char * expandTabs(const char * text); +static void textboxDraw(newtComponent co); +static void addLine(newtComponent co, const char * s, int len); +static void doReflow(const char * text, char ** resultPtr, int width, + int * badness, int * heightPtr); +static struct eventResult textboxEvent(newtComponent c, + struct event ev); +static void textboxDestroy(newtComponent co); +static void textboxPlace(newtComponent co, int newLeft, int newTop); +static void textboxMapped(newtComponent co, int isMapped); + +static struct componentOps textboxOps = { + textboxDraw, + textboxEvent, + textboxDestroy, + textboxPlace, + textboxMapped, +} ; + +static void textboxMapped(newtComponent co, int isMapped) { + struct textbox * tb = co->data; + + co->isMapped = isMapped; + if (tb->sb) { + tb->sb->ops->mapped(tb->sb, isMapped); + } +} + +static void textboxPlace(newtComponent co, int newLeft, int newTop) { + struct textbox * tb = co->data; + + co->top = newTop; + co->left = newLeft; + + if (tb->sb) { + tb->sb->ops->place(tb->sb, co->left + co->width - 1, co->top); + } +} + +void newtTextboxSetHeight(newtComponent co, int height) { + co->height = height; +} + +int newtTextboxGetNumLines(newtComponent co) { + struct textbox * tb = co->data; + + return (tb->numLines); +} + +newtComponent newtTextboxReflowed(int left, int top, char * text, int width, + int flexDown, int flexUp, int flags) { + newtComponent co; + char * reflowedText; + int actWidth, actHeight; + + reflowedText = newtReflowText(text, width, flexDown, flexUp, + &actWidth, &actHeight); + + co = newtTextbox(left, top, actWidth, actHeight, NEWT_FLAG_WRAP); + newtTextboxSetText(co, reflowedText); + free(reflowedText); + + return co; +} + +newtComponent newtTextbox(int left, int top, int width, int height, int flags) { + newtComponent co; + struct textbox * tb; + + co = malloc(sizeof(*co)); + tb = malloc(sizeof(*tb)); + co->data = tb; + + if (width < 1) + width = 1; + + co->ops = &textboxOps; + + co->isMapped = 0; + co->height = height; + co->top = top; + co->left = left; + co->takesFocus = 0; + co->width = width; + co->destroyCallback = NULL; + + tb->doWrap = flags & NEWT_FLAG_WRAP; + tb->numLines = 0; + tb->linesAlloced = 0; + tb->lines = NULL; + tb->topLine = 0; + tb->textWidth = width; + tb->isActive = 0; + tb->cs = COLORSET_TEXTBOX; + tb->csActive = COLORSET_ACTTEXTBOX; + + if (flags & NEWT_FLAG_SCROLL) { + co->width += 2; + tb->sb = newtVerticalScrollbar(co->left + co->width - 1, co->top, + co->height, tb->cs, tb->cs); + co->takesFocus = 1; + } else { + tb->sb = NULL; + } + + return co; +} + +void newtTextboxSetColors(newtComponent co, int normal, int active) { + struct textbox * tb = co->data; + + tb->cs = normal; + tb->csActive = active; + textboxDraw(co); +} + +static char * expandTabs(const char * text) { + int bufAlloced = strlen(text) + 40; + char * buf, * dest; + const char * src; + int bufUsed = 0; + int linePos = 0; + int i; + + buf = malloc(bufAlloced + 1); + for (src = text, dest = buf; *src; src++) { + if ((bufUsed + 10) > bufAlloced) { + bufAlloced += strlen(text) / 2; + buf = realloc(buf, bufAlloced + 1); + dest = buf + bufUsed; + } + if (*src == '\t') { + i = 8 - (linePos & 8); + memset(dest, ' ', i); + dest += i, bufUsed += i, linePos += i; + } else { + if (*src == '\n') + linePos = 0; + else + linePos++; + + *dest++ = *src; + bufUsed++; + } + } + + *dest = '\0'; + return buf; +} + +static void doReflow(const char * text, char ** resultPtr, int width, + int * badness, int * heightPtr) { + char * result = NULL; + const char * chptr, * end; + int i; + int howbad = 0; + int height = 0; + wchar_t tmp; + mbstate_t ps; + + if (resultPtr) { + if (width > 1) { + /* use width - 1 for double width characters + that won't fit at end of line */ + result = malloc(strlen(text) + (strlen(text) / (width - 1)) + 2); + } else + result = malloc(strlen(text) * 2 + 2); + *resultPtr = result; + } + + memset(&ps,0,sizeof(mbstate_t)); + while (*text) { + end = strchr(text, '\n'); + if (!end) + end = text + strlen(text); + + while (*text && text <= end) { + int len; + + len = wstrlen(text, end - text); + if (len <= width) { + if (result) { + memcpy(result, text, end - text); + result += end - text; + *result++ = '\n'; + height++; + } + + if (len < (width / 2)) { +#ifdef DEBUG_WRAP + fprintf(stderr,"adding %d\n",((width / 2) - (len)) / 2); +#endif + howbad += ((width / 2) - (len)) / 2; + } + text = end; + if (*text) text++; + } else { + const char *spcptr = NULL; + int spc = 0, w2 = 0, x, w; + + chptr = text; + i = 0; + while (1) { + if ((x=mbrtowc(&tmp,chptr,end-chptr,&ps))<=0) + break; + if (spc && !iswspace(tmp)) + spc = 0; + else if (!spc && iswspace(tmp)) { + spc = 1; + spcptr = chptr; + w2 = i; + } + w = wcwidth(tmp); + if (w < 0) + w = 0; + if (i && w + i > width) + break; + chptr += x; + i += w; + } + howbad += width - w2 + 1; +#ifdef DEBUG_WRAP + fprintf(stderr,"adding %d\n",width - w2 + 1, chptr); +#endif + if (spcptr) chptr = spcptr; + if (result) { + memcpy(result, text, chptr - text); + result += chptr - text; + *result++ = '\n'; + height++; + } + + text = chptr; + while (1) { + if ((x=mbrtowc(&tmp,text,end-text,NULL))<=0) + break; + if (!iswspace(tmp)) break; + text += x; + } + } + } + } + + if (result) + *result = '\0'; + + if (badness) *badness = howbad; + if (heightPtr) *heightPtr = height; +#ifdef DEBUG_WRAP + fprintf(stderr, "width %d, badness %d, height %d\n",width, howbad, height); +#endif +} + +char * newtReflowText(char * text, int width, int flexDown, int flexUp, + int * actualWidth, int * actualHeight) { + int min, max; + int i; + char * result; + int minbad, minbadwidth, howbad; + char * expandedText; + + if (width < 1) + width = 1; + + expandedText = expandTabs(text); + + if (flexDown || flexUp) { + min = width - flexDown; + max = width + flexUp; + + minbad = -1; + minbadwidth = width; + + for (i = min; i >= 1 && i <= max; i++) { + doReflow(expandedText, NULL, i, &howbad, NULL); + + if (minbad == -1 || howbad < minbad) { + minbad = howbad; + minbadwidth = i; + } + } + + width = minbadwidth; + } + + doReflow(expandedText, &result, width, NULL, actualHeight); + free(expandedText); + if (actualWidth) *actualWidth = width; + return result; +} + +void newtTextboxSetText(newtComponent co, const char * text) { + const char * start, * end; + struct textbox * tb = co->data; + char * reflowed, * expanded; + int badness, height; + + if (tb->lines) { + int i; + + for (i = 0; i < tb->numLines; i++) + free(tb->lines[i]); + free(tb->lines); + tb->linesAlloced = tb->numLines = tb->topLine = 0; + } + + expanded = expandTabs(text); + + if (tb->doWrap) { + doReflow(expanded, &reflowed, tb->textWidth, &badness, &height); + free(expanded); + expanded = reflowed; + } + + for (start = expanded; *start; start++) + if (*start == '\n') tb->linesAlloced++; + + /* This ++ leaves room for an ending line w/o a \n */ + tb->linesAlloced++; + tb->lines = malloc(sizeof(char *) * tb->linesAlloced); + + start = expanded; + while ((end = strchr(start, '\n'))) { + addLine(co, start, end - start); + start = end + 1; + } + + if (*start) + addLine(co, start, strlen(start)); + + free(expanded); + + textboxDraw(co); + + newtTrashScreen(); +} + +/* This assumes the buffer is allocated properly! */ +static void addLine(newtComponent co, const char * s, int len) { + struct textbox * tb = co->data; + + while (wstrlen(s,len) > tb->textWidth) { + len--; + } + tb->lines[tb->numLines] = malloc(len + 1); + memcpy(tb->lines[tb->numLines], s, len); + tb->lines[tb->numLines++][len] = '\0'; +} + +static void textboxDraw(newtComponent c) { + int i; + struct textbox * tb = c->data; + int size; + + if (!c->isMapped) + return; + + if (tb->sb) { + size = tb->numLines - c->height; + newtScrollbarSet(tb->sb, tb->topLine, size ? size : 0); + newtScrollbarSetColors(tb->sb, tb->isActive ? tb->csActive : + tb->cs, tb->cs); + } + + SLsmg_set_color(tb->cs); + + for (i = 0; (i + tb->topLine) < tb->numLines && i < c->height; i++) { + newtGotorc(c->top + i, c->left); + SLsmg_write_nstring(tb->lines[i + tb->topLine], tb->textWidth); + } + /* put cursor at beginning of text for better accessibility */ + newtGotorc(c->top, c->left); +} + +static struct eventResult textboxEvent(newtComponent co, + struct event ev) { + struct textbox * tb = co->data; + struct eventResult er; + + er.result = ER_IGNORED; + + if (!tb->sb || ev.when == EV_EARLY || ev.when == EV_LATE) + return er; + + switch(ev.event) { + case EV_KEYPRESS: + newtTrashScreen(); + switch (ev.u.key) { + case NEWT_KEY_UP: + if (tb->topLine) tb->topLine--; + textboxDraw(co); + er.result = ER_SWALLOWED; + break; + + case NEWT_KEY_DOWN: + if (tb->topLine < (tb->numLines - co->height)) tb->topLine++; + textboxDraw(co); + er.result = ER_SWALLOWED; + break; + + case NEWT_KEY_PGDN: + tb->topLine += co->height; + if (tb->topLine > (tb->numLines - co->height)) { + tb->topLine = tb->numLines - co->height; + if (tb->topLine < 0) tb->topLine = 0; + } + textboxDraw(co); + er.result = ER_SWALLOWED; + break; + + case NEWT_KEY_PGUP: + tb->topLine -= co->height; + if (tb->topLine < 0) tb->topLine = 0; + textboxDraw(co); + er.result = ER_SWALLOWED; + break; + } + break; + case EV_MOUSE: + /* Top scroll arrow */ + if (ev.u.mouse.x == co->width && ev.u.mouse.y == co->top) { + if (tb->topLine) tb->topLine--; + textboxDraw(co); + + er.result = ER_SWALLOWED; + } + /* Bottom scroll arrow */ + if (ev.u.mouse.x == co->width && + ev.u.mouse.y == co->top + co->height - 1) { + if (tb->topLine < (tb->numLines - co->height)) tb->topLine++; + textboxDraw(co); + + er.result = ER_SWALLOWED; + } + break; + case EV_FOCUS: + tb->isActive = 1; + textboxDraw(co); + er.result = ER_SWALLOWED; + break; + case EV_UNFOCUS: + tb->isActive = 0; + textboxDraw(co); + er.result = ER_SWALLOWED; + break; + } + return er; +} + +static void textboxDestroy(newtComponent co) { + int i; + struct textbox * tb = co->data; + + if (tb->sb) + tb->sb->ops->destroy(tb->sb); + for (i = 0; i < tb->numLines; i++) + free(tb->lines[i]); + free(tb->lines); + free(tb); + free(co); +} diff --git a/tutorial.sgml b/tutorial.sgml new file mode 100644 index 0000000..e15a338 --- /dev/null +++ b/tutorial.sgml @@ -0,0 +1,1483 @@ + + +
+ + +Writing Programs Using <literal remap="tt">newt</literal> + +Erik Troan, <ewt@redhat.com> + + +v0.31, 2003-Jan-06 + + + + +The newt windowing system is a terminal-based window and widget +library designed for writing applications with a simple, but user-friendly, +interface. While newt is not intended to provide the rich feature +set advanced applications may require, it has proven to be flexible enough +for a wide range of applications (most notably, Red Hat's installation +process). This tutorial explains the design philosophy behind newt and +how to use newt from your programs. + + + + + + + +Introduction + + +Newt has a definite design philosophy behind it, and knowing that design +makes it significantly easier to craft robust newt applications. This +tutorial documents newt 0.30 --- older versions of newt had +annoying inconsistencies in it (which writing this tutorial pointed out), +which were removed while this tutorial was written. The latest version of +newt is always available from Red Hat. + +Background + + +Newt was originally designed for use in the install code for +Red Hat Linux. As this install code runs in an environment with limited +resources (most importantly limited filesystem space), newt's size +was immediately an issue. To help minimize its size, the following design +decisions were made early in its implementation: + + + + + + + newt does not use an event-driven architecture. + + + + + newt is written in C, not C++. While there has been interest +in constructing C++ wrapper classes around the newt API, nothing has +yet come of those ideas. + + + + + Windows must be created and destroyed as a stack (in other words, all +newt windows behave as modal dialogs). This is probably +the greatest functionality restriction of newt. + + + + The tty keyboard is the only supported input device. + + + + + Many behaviours, such as widget traversal order, are difficult +or impossible to change. + + + + + +While newt provides a complete API, it does not handle the low-level +screen drawing itself. Instead, newt is layered on top of the screen +management capabilities of John E. Davis's +S-Lang library. + + +Designing <literal remap="tt">newt</literal> applications + +As newt is not event driven and forces modal windows (forcing window +order to behave like a stack), newt applications tend to look quite like +other text-mode programs. It is quite straightforward to convert a command +line program which uses simple user prompts into a newt application. +Some of the programs run as part of the Red Hat installation process +(such as Xconfigurator and mouseconfig) were originally written +as simple terminal mode programs which used line-oriented menus to get +input from the user and were later converted into newt applications +(through a process affectionately known as newtering). Such a conversion +does not require changes to the control flow of most applications. + +Programming newt is dramatically different from writing programs for +most other windowing systems as newt's API is not event driven. This +means that newt applications look dramatically different from programs +written for event-driven architectures such as Motif, gtk, or even +Borland's old TurboVision libraries. + +When you're designing your newt program, keep this differentiation +in mind. As long as you plan your application to call a function to +get input and then continue (rather then having your program called +when input is ready), programming with the newt libraries should be +simple. + + +Components + + +Displayable items in newt are known as components, which are +analogous to the widgets provided by most Unix widget sets. There are +two main types of components in newt, forms and everything else. +Forms logically group components into functional sets. When an application +is ready to get input from a user, it ``runs a form'', which makes the +form active and lets the user enter information into the components the +form contains. A form may contain any other component, including other +forms. Using subforms in this manner lets the application change the details +of how the user tabs between components on the form, scroll regions of the +screen, and control background colors for portions of windows. + +Every component is of type newtComponent, which is an opaque type. It's +guaranteed to be a pointer though, which lets applications move it through +void pointers if the need arises. Variables of type newtComponent should +never be directly manipulated -- they should only be passed to newt +functions. As newtComponent variables are pointers, remember that +they are always passed by value -- if you pass a newtComponent to +a function which manipulates it, that component is manipulated everywhere, +not just inside of that function (which is nearly always the behaviour +you want). + + +Conventions + + +Newt uses a number of conventions to make it easier for programmers +to use. + + + + + + + All functions which manipulate data structures take the data +structure being modified as their first parameter. For example, all +of the functions which manipulate forms expect the newtComponent +for that form to be the first parameter. + + + + As newt is loosely typed (forcing all of the components into +a single variable makes coding easier, but nullifies the value of type +checking), newt functions include the name of the type they are +manipulating. An example of this is newtFormAddComponent(), which +adds a component to a form. Note that the first parameter to this function +is a form, as the name would suggest. + + + + When screen coordinates are passed into a function, the +x location precedes the y location. To help keep this clear, +we'll use the words ``left'' and ``top'' to describe those indicators (with +left corresponding to the x position). + + + + When box sizes are passed, the horizontal width precedes the vertical +width. + + + + When both a screen location and a box size are being passed, the +screen location precedes the box size. + + + + When any component other then a form is created, the first two +parameters are always the (left, right) location. + + + + Many functions take a set of flags as the final parameter. These +flags may be logically ORed together to pass more then one flag at a time. + + + + Newt uses callback functions to convey certain events to +the application. While callbacks differ slightly in their parameters, most +of them allow the application to specify an arbitrary argument to be passed +to the callback when the callback is invoked. This argument is always a +void *, which allows the application great flexibility. + + + + + + + +Basic <literal remap="tt">Newt</literal> Functions + + +While most newt functions are concerned with widgets or groups +of widgets (called grids and forms), some parts of the newt API +deal with more global issues, such as initializing newt or writing +to the root window. + + +Starting and Ending <literal remap="tt">newt</literal> Services + + +There are three functions which nearly every newt application use. The +first two are used to initialize the system. + + + +int newtInit(void); +void newtCls(void); + + + +newtInit() should be the first function called by every newt +program. It initializes internal data structures and places the terminal +in raw mode. Most applications invoke newtCls() immediately after +newtInit(), which causes the screen to be cleared. It's not +necessary to call newtCls() to use any of newt's features, but +doing so will normally give a much neater appearance. + +When a newt program is ready to exit, it should call newtFinished(). + + + +int newtFinished(void); + + + +newtFinished() restores the terminal to its appearance when +newtInit() was called (if possible -- on some terminals the cursor will +be moved to the bottom, but it won't be possible to remember the original +terminal contents) and places the terminal in its original input state. +If this function isn't called, the terminal will probably need to be +reset with the reset command before it can be used easily. + + +Handling Keyboard Input + + +Normally, newt programs don't read input directly from the +user. Instead, they let newt read the input and hand it to the +program in a semi-digested form. Newt does provide a couple of simple +functions which give programs (a bit of) control over the terminal. + + + +void newtWaitForKey(void); +void newtClearKeyBuffer(void); + + + + + +The first of these, newtWaitForKey(), doesn't return until a key +has been pressed. The keystroke is then ignored. If a key is already in +the terminal's buffer, newtWaitForKey() discards a keystroke and +returns immediately. + +newtClearKeyBuffer() discards the contents of the terminal's input +buffer without waiting for additional input. + + +Drawing on the Root Window + + +The background of the terminal's display (the part without any windows +covering it) is known as the root window (it's the parent of all +windows, just like the system's root directory is the parent of all +subdirectories). Normally, applications don't use the root window, instead +drawing all of their text inside of windows (newt doesn't require +this though -- widgets may be placed directly on the root window without +difficulty). It is often desirable to display some text, such as a +program's name or copyright information, on the root window, however. +Newt provides two ways of displaying text on the root window. These +functions may be called at any time. They are the only newt functions +which are meant to write outside of the current window. + + + +void newtDrawRootText(int left, int top, const char * text); + + + + + +This function is straightforward. It displays the string text at +the position indicated. If either the left or top is +negative, the position is measured from the opposite side of the +screen. The final measurement will seem to be off by one though. For +example, a top of -1 indicates the last line on the screen, and +one of -2 is the line above that. + +As it's common to use the last line on the screen to display help information, +newt includes special support for doing exactly that. The last +line on the display is known as the help line, and is treated as a +stack. As the value of the help line normally relates to the window +currently displayed, using the same structure for window order and the +help line is very natural. Two functions are provided to manipulate the +help line. + + + +void newtPushHelpLine(const char * text); +void newtPopHelpLine(void); + + + +The first function, newtPushHelpLine(), saves the current help line +on a stack (which is independent of the window stack) and displays the +new line. If text is NULL, newt's default help line is +displayed (which provides basic instructions on using newt). If +text is a string of length 0, the help line is cleared. For all +other values of text, the passed string is displayed at the bottom, +left-hand corner of the display. The space between the end of the displayed +string the the right-hand edge of the terminal is cleared. + +newtPopHelpLine() replaces the current help line with the one it +replaced. It's important not to call tt/newtPopHelpLine()/ more then +newtPushHelpLine()! + +Suspending Newt Applications + +By default, newt programs cannot be suspended by the user (compare +this to most Unix programs which can be suspended by pressing the suspend +key (normally ^Z). Instead, programs can specify a callback +function which gets invoked when the user presses the suspend key. + + + +typedef void (*newtSuspendCallback)(void); + +void newtSetSuspendCallback(newtSuspendCallback cb); + + + +The suspend function neither expects nor returns any value, and can +do whatever it likes to when it is invoked. If no suspend callback +is registered, the suspend keystroke is ignored. + +If the application should suspend and continue like most user applications, +the suspend callback needs two other newt functions. + + + +void newtSuspend(void); +void newtResume(void); + + + +newtSuspend() tells newt to return the terminal to its initial +state. Once this is done, the application can suspend itself (by +sending itself a SIGTSTP, fork a child program, or do whatever +else it likes. When it wants to resume using the newt interface, +it must call newtResume before doing so. + +Note that suspend callbacks are not signal handlers. When newtInit() +takes over the terminal, it disables the part of the terminal interface +which sends the suspend signal. Instead, if newt sees the suspend +keystroke during normal input processing, it immediately calls the suspend +callback if one has been set. This means that suspending newt applications +is not asynchronous. + + +Refreshing the Screen + + +To increase performance, S-Lang only updates the display when it needs +to, not when the program tells S-Lang to write to the terminal. ``When it +needs to'' is implemented as ``right before the we wait for the user to +press a key''. While this allows for optimized screen displays most of +the time, this optimization makes things difficult for programs which +want to display progress messages without forcing the user to input +characters. Applications can force S-Lang to immediately update modified +portions of the screen by calling newtRefresh. + + + + + + +The program wants to display a progress message, without forcing +for the user to enter any characters. + + + +A misfeature of the program causes part of the screen to be +corrupted. Ideally, the program would be fixed, but that may not +always be practical. + + + + + + +Other Miscellaneous Functions + + +As always, some function defy characterization. Two of newt's general +function fit this oddball category. + + + +void newtBell(void); +void newtGetScreenSize(int * cols, int * rows); + + + +The first sends a beep to the terminal. Depending on the terminal's +settings, this been may or may not be audible. The second function, +newtGetScreenSize(), fills in the passed pointers with the +current size of the terminal. + + +Basic <literal remap="tt">newt</literal> Example + + +To help illustrate the functions presented in this section here is a short +sample newt program which uses many of them. While it doesn't do +anything interesting, it does show the basic structure of newt programs. + + + +#include <newt.h> +#include <stdlib.h> + +int main(void) { + newtInit(); + newtCls(); + + newtDrawRootText(0, 0, "Some root text"); + newtDrawRootText(-25, -2, "Root text in the other corner"); + + newtPushHelpLine(NULL); + newtRefresh(); + sleep(1); + + newtPushHelpLine("A help line"); + newtRefresh(); + sleep(1); + + newtPopHelpLine(); + newtRefresh(); + sleep(1); + + newtFinished(); +} + + + + +Windows + + +While most newt applications do use windows, newt's window +support is actually extremely limited. Windows must be destroyed in the +opposite of the order they were created, and only the topmost window may be +active. Corollaries to this are: + + + + + + +The user may not switch between windows. + + + +Only the top window may be destroyed. + + + +While this is quite a severe limitation, adopting it greatly simplifies +both writing newt applications and developing newt itself, as it +separates newt from the world of event-driven programming. However, +this tradeoff between function and simplicity may make newt +unsuitable for some tasks. + + +Creating Windows + + +There are two main ways of opening newt windows: with or without +explicit sizings. When grids (which will be introduced later in this +tutorial) are used, a window may be made to just fit the grid. When +grids are not used, explicit sizing must be given. + + + +int newtCenteredWindow(int width, int height, const char * title); +int newtOpenWindow(int left, int top, int width, int height, + const char * title); + + + +The first of these functions open a centered window of the specified +size. The title is optional -- if it is NULL, then no title +is used. newtOpenWindow*( is similar, but it requires a specific +location for the upper left-hand corner of the window. + + +Destroying Windows + + +All windows are destroyed in the same manner, no matter how the windows +were originally created. + + + +void newtPopWindow(void); + + + +This function removes the top window from the display, and redraws the +display areas which the window overwrote. + + +Components + + +Components are the basic user interface element newt provides. A +single component may be (for example) a listbox, push button checkbox, +a collection of other components. Most components are used to display +information in a window, provide a place for the user to enter data, or a +combination of these two functions. + +Forms, however, are a component whose primary purpose is not noticed by +the user at all. Forms are collections of components (a form may contain +another form) which logically relate the components to one another. Once +a form is created and had all of its constituent components added to it, +applications normally then run the form. This gives control of the +application to the form, which then lets the user enter data onto the +form. When the user is done (a number of different events qualify as +``done''), the form returns control to the part of the application which +invoked it. The application may then read the information the user provided +and continue appropriately. + +All newt components are stored in a common data type, a +newtComponent (some of the particulars of newtComponents have +already been mentioned. While this makes it easy for programmers to pass +components around, it does force them to make sure they don't pass +entry boxes to routines expecting push buttons, as the compiler can't +ensure that for them. + +We start off with a brief introduction to forms. While not terribly +complete, this introduction is enough to let us illustrate the rest of +the components with some sample code. We'll then discuss the remainder of +the components, and end this section with a more exhaustive description of +forms. + + +Introduction to Forms + + +As we've mentioned, forms are simply collections of components. As only one +form can be active (or running) at a time, every component which the user +should be able to access must be on the running form (or on a subform of +the running form). A form is itself a component, which means forms are +stored in newtComponent data structures. + + + +newtComponent newtForm(newtComponent vertBar, const char * help, int flags); + + + +To create a form, call newtForm(). The first parameter is a vertical +scrollbar which should be associated with the form. For now, that should +always be NULL (we'll discuss how to create scrolling forms later in +this section). The second parameter, help, is currently unused and +should always be NULL. The flags is normally 0, and other values +it can take will be discussed later. Now that we've waved away the +complexity of this function, creating a form boils down to simply: + + + +newtComponent myForm; + +myForm = newtForm(NULL, NULL, 0); + + + +After a form is created, components need to be added to it --- after all, +an empty form isn't terribly useful. There are two functions which add +components to a form. + + + +void newtFormAddComponent(newtComponent form, newtComponent co); +void newtFormAddComponents(newtComponent form, ...); + + + +The first function, newtFormAddComponent(), adds a single component +to the form which is passed as the first parameter. The second function +is simply a convenience function. After passing the form to +newtFormAddComponents(), an arbitrary number of components is then +passed, followed by NULL. Every component passed is added to the form. + +Once a form has been created and components have been added to it, it's +time to run the form. + + + +newtComponent newtRunForm(newtComponent form); + + + +This function runs the form passed to it, and returns the component which +caused the form to stop running. For now, we'll ignore the return value +completely. + +Notice that this function doesn't fit in with newt's normal +naming convention. It is an older interface which will not work for all +forms. It was left in newt only for legacy applications. It is a +simpler interface than the new newtFormRun() though, and is still used +quite often as a result. + +When an application is done with a form, it destroys the form and +all of the components the form contains. + + + +void newtFormDestroy(newtComponent form); + + + +This function frees the memory resources used by the form and all of the +components which have been added to the form (including those components +which are on subforms). Once a form has been destroyed, none of the form's +components can be used. + + +Components + + +Non-form components are the most important user-interface component for +users. They determine how users interact with newt and how information +is presented to them. + + +General Component Manipulation + + +There are a couple of functions which work on more then one type of +components. The description of each component indicates which (if any) +of these functions are valid for that particular component. + + + +typedef void (*newtCallback)(newtComponent, void *); + +void newtComponentAddCallback(newtComponent co, newtCallback f, void * data); +void newtComponentTakesFocus(newtComponent co, int val); + + + +The first registers a callback function for that component. A callback +function is a function the application provides which newt calls for a +particular component. Exactly when (if ever) the callback is invoked +depends on the type of component the callback is attached to, and will be +discussed for the components which support callbacks. + +newtComponentTakesFocus() works on all components. It allows the +application to change which components the user is allowed to select as the +current component, and hence provide input to. Components which do not +take focus are skipped over during form traversal, but they are displayed +on the terminal. Some components should never be set to take focus, such +as those which display static text. + + +Buttons + + +Nearly all forms contain at least one button. Newt buttons come in two +flavors, full buttons and compact buttons. Full buttons take up quit a bit +of screen space, but look much better then the single-row compact buttons. +Other then their size, both button styles behave identically. Different +functions are used to create the two types of buttons. + + + +newtComponent newtButton(int left, int top, const char * text); +newtComponent newtCompactButton(int left, int top, const char * text); + + + +Both functions take identical parameters. The first two parameters are the +location of the upper left corner of the button, and the final parameter is +the text which should be displayed in the button (such as ``Ok'' or +``Cancel''). + + +Button Example + + +Here is a simple example of both full and compact buttons. It also +illustrates opening and closing windows, as well a simple form. + + + +#include <newt.h> +#include <stdlib.h> + +void main(void) { + newtComponent form, b1, b2; + newtInit(); + newtCls(); + + newtOpenWindow(10, 5, 40, 6, "Button Sample"); + + b1 = newtButton(10, 1, "Ok"); + b2 = newtCompactButton(22, 2, "Cancel"); + form = newtForm(NULL, NULL, 0); + newtFormAddComponents(form, b1, b2, NULL); + + newtRunForm(form); + + newtFormDestroy(form); + newtFinished(); +} + + + + +Labels + + +Labels are newt's simplest component. They display some given text and +don't allow any user input. + + + +newtComponent newtLabel(int left, int top, const char * text); +void newtLabelSetText(newtComponent co, const char * text); + + + +Creating a label is just like creating a button; just pass the location of +the label and the text it should display. Unlike buttons, labels do let the +application change the text in the label with newtLabelSetText. When +the label's text is changed, the label automatically redraws itself. It +does not clear out any old text which may be leftover from the previous +time is was displayed, however, so be sure that the new text is at least +as long as the old text. + + +Entry Boxes + + +Entry boxes allow the user to enter a text string into the form which the +application can later retrieve. + + + +typedef int (*newtEntryFilter)(newtComponent entry, void * data, int ch, + int cursor); + +newtComponent newtEntry(int left, int top, const char * initialValue, int width, + char ** resultPtr, int flags); +void newtEntrySet(newtComponent co, const char * value, int cursorAtEnd); +char * newtEntryGetValue(newtComponent co); +void newtEntrySetFilter(newtComponent co, newtEntryFilter filter, void * data); + + + + + +newtEntry() creates a new entry box. After the location of the entry +box, the initial value for the entry box is passed, which may be NULL +if the box should start off empty. Next, the width of the physical box is +given. This width may or may not limit the length of the string the user is +allowed to enter; that depends on the flags. The resultPtr must +be the address of a char *. Until the entry box is destroyed by +newtFormDestroy(), that char * will point to the current value +of the entry box. It's important that applications make a copy of that +value before destroying the form if they need to use it later. The +resultPtr may be NULL, in which case the user must use the +newtEntryGetValue() function to get the value of the entry box. + +Entry boxes support a number of flags: + + + + +NEWT_ENTRY_SCROLL + +If this flag is not specified, the user cannot +enter text into the entry box which is wider then the entry box itself. +This flag removes this limitation, and lets the user enter data of an +arbitrary length. + + +NEWT_FLAG_HIDDEN + +If this flag is specified, the value of the entry box +is not displayed. This is useful when the application needs to read a +password, for example. + + +NEWT_FLAG_RETURNEXIT + +When this flag is given, the entry box will cause +the form to stop running if the user pressed return inside of the entry +box. This can provide a nice shortcut for users. + + + + + +After an entry box has been created, its contents can be set by +newtEntrySet(). After the entry box itself, the new string to place +in the entry box is passed. The final parameter, cursorAtEnd, controls +where the cursor will appear in the entry box. If it is zero, the cursor +remains at its present location; a nonzero value moves the cursor to the +end of the entry box's new value. + +While the simplest way to find the value of an entry box is by using a +resultPtr, doing so complicates some applications. +newtEntryGetValue() returns a pointer to the string which the entry +box currently contains. The returned pointer may not be valid once the +user further modifies the entry box, and will not be valid after the +entry box has been destroyed, so be sure to save its value in a more +permanent location if necessary. + +Entry boxes allow applications to filter characters as they are entered. +This allows programs to ignore characters which are invalid (such as +entering a ^ in the middle of a phone number) and provide intelligent aids +to the user (such as automatically adding a '.' after the user has typed in +the first three numbers in an IP address). + +When a filter is registered through newtEntrySetFilter(), both the +filter itself and an arbitrary void *, which passed to the filter +whenever it is invoked, are recorded. This data pointer isn't used for any +other purpose, and may be NULL. Entry filters take four arguments. + + + + + + +The entry box which had data entered into it + + + +The data pointer which was registered along with the filter + + + +The new character which newt is considering inserting into the +entry box + + + +The current cursor position (0 is the leftmost position) + + + + +The filter returns 0 if the character should be ignored, or the value of +the character which should be inserted into the entry box. Filter functions +which want to do complex manipulations of the string should use +newtEntrySet() to update the entry box and then return 0 to prevent +the new character from being inserted. + +When a callback is attached to a entry box, the callback is invoked +whenever the user moves off of the callback and on to another component. + +Here is a sample program which illustrates the use of both labels and +entry boxes. + + + +#include <newt.h> +#include <stdlib.h> +#include <stdio.h> + +void main(void) { + newtComponent form, label, entry, button; + char * entryValue; + + newtInit(); + newtCls(); + + newtOpenWindow(10, 5, 40, 8, "Entry and Label Sample"); + + label = newtLabel(1, 1, "Enter a string"); + entry = newtEntry(16, 1, "sample", 20, &entryValue, + NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT); + button = newtButton(17, 3, "Ok"); + form = newtForm(NULL, NULL, 0); + newtFormAddComponents(form, label, entry, button, NULL); + + newtRunForm(form); + + newtFinished(); + + printf("Final string was: %s\n", entryValue); + + /* We cannot destroy the form until after we've used the value + from the entry widget. */ + newtFormDestroy(form); +} + + + + +Checkboxes + + +Most widget sets include checkboxes which toggle between two value (checked +or not checked). Newt checkboxes are more flexible. When the user +presses the space bar on a checkbox, the checkbox's value changes to the +next value in an arbitrary sequence (which wraps). Most checkboxes have +two items in that sequence, checked or not, but newt allows an +arbitrary number of value. This is useful when the user must pick from a +limited number of choices. + +Each item in the sequence is a single character, and the sequence itself is +represented as a string. The checkbox components displays the character +which currently represents its value the left of a text label, and returns +the same character as its current value. The default sequence for +checkboxes is " *", with ' ' indicating false and '*' true. + + + +newtComponent newtCheckbox(int left, int top, const char * text, char defValue, + const char * seq, char * result); +char newtCheckboxGetValue(newtComponent co); + + + + + +Like most components, the position of the checkbox is the first thing +passed to the function that creates one. The next parameter, text, is +the text which is displayed to the right of the area which is checked. The +defValue is the initial value for the checkbox, and seq is the +sequence which the checkbox should go through (defValue must be +in seq. seq may be NULL, in which case " *" is used. +The final parameter, result, should point to a character which the +checkbox should always record its current value in. If result is +NULL, newtCheckboxGetValue() must be used to get the current +value of the checkbox. + +newtCheckboxGetValue() is straightforward, returning the character +in the sequence which indicates the current value of the checkbox + +If a callback is attached to a checkbox, the callback is invoked whenever +the checkbox responds to a user's keystroke. The entry box may respond by +taking focus or giving up focus, as well as by changing its current value. + + +Radio Buttons + + +Radio buttons look very similar to checkboxes. The key difference between +the two is that radio buttons are grouped into sets, and exactly one radio +button in that set may be turned on. If another radio button is selected, +the button which was selected is automatically deselected. + + + + +newtComponent newtRadiobutton(int left, int top, const char * text, + int isDefault, newtComponent prevButton); +newtComponent newtRadioGetCurrent(newtComponent setMember); + + + +Each radio button is created by calling newtRadiobutton(). After +the position of the radio button, the text displayed with the button +is passed. isDefault should be nonzero if the radio button is to +be turned on by default. The final parameter, prevMember is used +to group radio buttons into sets. If prevMember is NULL, the +radio button is assigned to a new set. If the radio button should belong +to a preexisting set, prevMember must be the previous radio button +added to that set. + +Discovering which radio button in a set is currently selected necessitates +newtRadioGetCurrent(). It may be passed any radio button in the set +you're interested in, and it returns the radio button component currently +selected. + +Here is an example of both checkboxes and radio buttons. + + + +#include <newt.h> +#include <stdlib.h> +#include <stdio.h> + +void main(void) { + newtComponent form, checkbox, rb[3], button; + char cbValue; + int i; + + newtInit(); + newtCls(); + + newtOpenWindow(10, 5, 40, 11, "Checkboxes and Radio buttons"); + + checkbox = newtCheckbox(1, 1, "A checkbox", ' ', " *X", &cbValue); + + rb[0] = newtRadiobutton(1, 3, "Choice 1", 1, NULL); + rb[1] = newtRadiobutton(1, 4, "Choice 2", 0, rb[0]); + rb[2] = newtRadiobutton(1, 5, "Choice 3", 0, rb[1]); + + button = newtButton(1, 7, "Ok"); + + form = newtForm(NULL, NULL, 0); + newtFormAddComponent(form, checkbox); + for (i = 0; i < 3; i++) + newtFormAddComponent(form, rb[i]); + newtFormAddComponent(form, button); + + newtRunForm(form); + newtFinished(); + + /* We cannot destroy the form until after we've found the current + radio button */ + + for (i = 0; i < 3; i++) + if (newtRadioGetCurrent(rb[0]) == rb[i]) + printf("radio button picked: %d\n", i); + newtFormDestroy(form); + + /* But the checkbox's value is stored locally */ + printf("checkbox value: '%c'\n", cbValue); +} + + + + +Scales + + +It's common for programs to need to display a progress meter on the +terminal while it performs some length operation (it behaves like an +anesthetic). The scale component is a simple way of doing this. It +displays a horizontal bar graph which the application can update as the +operation continues. + + + +newtComponent newtScale(int left, int top, int width, long long fullValue); +void newtScaleSet(newtComponent co, unsigned long long amount); + + + +When the scale is created with newtScale, it is given the width of the +scale itself as well as the value which means that the scale should be +drawn as full. When the position of the scale is set with +newtScaleSet(), the scale is told the amount of the scale which should +be filled in relative to the fullAmount. For example, if the +application is copying a file, fullValue could be the number of bytes +in the file, and when the scale is updated newtScaleSet() would be +passed the number of bytes which have been copied so far. + + +Textboxes + + +Textboxes display a block of text on the terminal, and is appropriate for +display large amounts of text. + + + +newtComponent newtTextbox(int left, int top, int width, int height, int flags); +void newtTextboxSetText(newtComponent co, const char * text); + + + +newtTextbox() creates a new textbox, but does not fill it with data. +The function is passed the location for the textbox on the screen, the +width and height of the textbox (in characters), and zero or more of the +following flags: + + + + +NEWT_FLAG_WRAP + +All text in the textbox should be wrapped to fit +the width of the textbox. If this flag is not specified, each newline +delimited line in the text is truncated if it is too long to fit. + +When newt wraps text, it tries not to break lines on spaces or tabs. +Literal newline characters are respected, and may be used to force line +breaks. + + + +NEWT_FLAG_SCROLL + +The text box should be scrollable. When this option +is used, the scrollbar which is added increases the width of the area used +by the textbox by 2 characters; that is the textbox is 2 characters wider +then the width passed to newtTextbox(). + + + + + + + +After a textbox has been created, text may be added to it through +newtTextboxSetText(), which takes only the textbox and the new text as +parameters. If the textbox already contained text, that text is replaced by +the new text. The textbox makes its own copy of the passed text, so these +is no need to keep the original around unless it's convenient. + + +Reflowing Text + + +When applications need to display large amounts of text, it's common not to +know exactly where the linebreaks should go. While textboxes are quite +willing to scroll the text, the programmer still must know what width the +text will look ``best'' at (where ``best'' means most exactly rectangular; +no lines much shorter or much longer then the rest). This common is +especially prevalent in internationalized programs, which need to make a +wide variety of message string look god on a screen. + +To help with this, newt provides routines to reformat text to look +good. It tries different widths to figure out which one will look ``best'' +to the user. As these commons are almost always used to format text for +textbox components, newt makes it easy to construct a textbox with +reflowed text. + + + +char * newtReflowText(char * text, int width, int flexDown, int flexUp, + int * actualWidth, int * actualHeight); +newtComponent newtTextboxReflowed(int left, int top, char * text, int width, + int flexDown, int flexUp, int flags); +int newtTextboxGetNumLines(newtComponent co); + + + + + +newtReflowText() reflows the text to a target width of +width. The actual width of the longest line in the returned string is +between width - flexDown and width + flexUp; the actual maximum +line length is chosen to make the displayed check look rectangular. +The ints pointed to by actualWidth and actualHeight are set +to the width of the longest line and the number of lines in in the +returned text, respectively. Either one may be NULL. The return +value points to the reflowed text, and is allocated through malloc(). + +When the reflowed text is being placed in a textbox it may be easier to use +newtTextboxReflowed(), which creates a textbox, reflows the text, and +places the reflowed text in the listbox. It's parameters consist of the +position of the final textbox, the width and flex values for the text +(which are identical to the parameters passed to newtReflowText(), +and the flags for the textbox (which are the same as the flags for +newtTextbox(). This function does not let you limit the height of the +textbox, however, making limiting it's use to constructing textboxes which +don't need to scroll. + +To find out how tall the textbox created by newtTextboxReflowed() is, +use newtTextboxGetNumLines(), which returns the number of lines in the +textbox. For textboxes created by newtTextboxReflowed(), this is +always the same as the height of the textbox. + +Here's a simple program which uses a textbox to display a message. + + + +#include <newt.h> +#include <stdlib.h> + +char message[] = "This is a pretty long message. It will be displayed " + "in a newt textbox, and illustrates how to construct " + "a textbox from arbitrary text which may not have " + "very good line breaks.\n\n" + "Notice how literal \\n characters are respected, and " + "may be used to force line breaks and blank lines."; + +void main(void) { + newtComponent form, text, button; + + newtInit(); + newtCls(); + + text = newtTextboxReflowed(1, 1, message, 30, 5, 5, 0); + button = newtButton(12, newtTextboxGetNumLines(text) + 2, "Ok"); + + newtOpenWindow(10, 5, 37, + newtTextboxGetNumLines(text) + 7, "Textboxes"); + + form = newtForm(NULL, NULL, 0); + newtFormAddComponents(form, text, button, NULL); + + newtRunForm(form); + newtFormDestroy(form); + newtFinished(); +} + + + + +Scrollbars + + +Scrollbars (which, currently, are always vertical in newt), may be +attached to forms to let them contain more data then they have space for. +While the actual process of making scrolling forms is discussed at the end +of this section, we'll go ahead and introduce scrollbars now so you'll be +ready. + + + +newtComponent newtVerticalScrollbar(int left, int top, int height, + int normalColorset, int thumbColorset); + + + +When a scrollbar is created, it is given a position on the screen, a +height, and two colors. The first color is the color used for drawing the +scrollbar, and the second color is used for drawing the thumb. This is the +only place in newt where an application specifically sets colors for a +component. It's done here to let the colors a scrollbar use match the +colors of the component the scrollbar is mated too. When a scrollbar is +being used with a form, normalColorset is often +NEWT_COLORSET_WINDOW and thumbColorset +NEWT_COLORSET_ACTCHECKBOX. Of course, feel free to peruse +<newt.h> and pick your own colors. + +As the scrollbar is normally updated by the component it is mated with, +there is no public interface for moving the thumb. + + +Listboxes + +Listboxes are the most complicated components +newt provides. They can +allow a single selection or multiple selection, and are easy to update. +Unfortunately, their API is also the least consistent of newt's +components. Each entry in a listbox is a ordered pair of the text which should be +displayed for that item and a key, which is a void * that +uniquely identifies that listbox item. Many applications pass integers in +as keys, but using arbitrary pointers makes many applications significantly +easier to code. + +Basic Listboxes + + +Let's start off by looking at the most important listbox functions. + + + +newtComponent newtListbox(int left, int top, int height, int flags); +int newtListboxAppendEntry(newtComponent co, const char * text, + const void * data); +void * newtListboxGetCurrent(newtComponent co); +void newtListboxSetWidth(newtComponent co, int width); +void newtListboxSetCurrent(newtComponent co, int num); +void newtListboxSetCurrentByKey(newtComponent co, void * key); + + + + + +A listbox is created at a certain position and a given height. The +height is used for two things. First of all, it is the minimum +height the listbox will use. If there are less items in the listbox then +the height, suggests the listbox will still take up that minimum amount +of space. Secondly, if the listbox is set to be scrollable (by setting +the NEWT_FLAG_SCROLL flag, the height is also the maximum height +of the listbox. If the listbox may not scroll, it increases its height to +display all of its items. + +The following flags may be used when creating a listbox: + + + + +NEWT_FLAG_SCROLL + +The listbox should scroll to display all of the +items it contains. + + +NEWT_FLAG_RETURNEXIT + +When the user presses return on an item in the +list, the form should return. + + +NEWT_FLAG_BORDER + +A frame is drawn around the listbox, which can make +it easier to see which listbox has the focus when a form contains multiple +listboxes. + + +NEWT_FLAG_MULTIPLE + +By default, a listbox only lets the user select +one item in the list at a time. When this flag is specified, they may +select multiple items from the list. + + + + +Once a listbox has been created, items are added to it by invoking +newtListboxAppendEntry(), which adds new items to the end of the list. +In addition to the listbox component, newtListboxAppendEntry() needs +both elements of the (text, key) ordered pair. + +For lists which only allow a single selection, newtListboxGetCurrent() +should be used to find out which listbox item is currently selected. It +returns the key of the currently selected item. + +Normally, a listbox is as wide as its widest element, plus space for a +scrollbar if the listbox is supposed to have one. To make the listbox +any larger then that, use newtListboxSetWidth(), which overrides the +natural list of the listbox. Once the width has been set, it's fixed. The +listbox will no longer grow to accommodate new entries, so bad things may +happen! + +An application can change the current position of the listbox (where the +selection bar is displayed) by calling newtListboxSetCurrent() or +newtListboxSetCurrentByKey(). The first sets the current position to the +entry number which is passed as the second argument, with 0 indicating +the first entry. newtListboxSetCurrentByKey() sets the current position +to the entry whose key is passed into the function. + + +Manipulating Listbox Contents + + +While the contents of many listboxes never need to change, some applications +need to change the contents of listboxes regularly. Newt includes +complete support for updating listboxes. These new functions are in +addition to newtListboxAppendEntry(), which was already discussed. + + + +void newtListboxSetEntry(newtComponent co, void * key, const char * text); +int newtListboxInsertEntry(newtComponent co, const char * text, + const void * data, void * key); +int newtListboxDeleteEntry(newtComponent co, void * key); +void newtListboxClear(newtComponent co); + + + + + +The first of these, newtListboxSetEntry(), updates the text for a +key which is already in the listbox. The key specifies which listbox +entry should be modified, and text becomes the new text for that entry +in the listbox. + +newtListboxInsertEntry() inserts a new listbox entry after an +already existing entry, which is specified by the key parameter. +The text and data parameters specify the new entry which should +be added. + +Already-existing entries are removed from a listbox with +newtListboxDeleteEntry(). It removes the listbox entry with the +specified key. If you want to remove all of the entries from a +listbox, use newtListboxClear(). + + +Multiple Selections + + +When a listbox is created with NEWT_FLAG_MULTIPLE, the user can select +multiple items from the list. When this option is used, a different set of +functions must be used to manipulate the listbox selection. + + + +void newtListboxClearSelection(newtComponent co); +void **newtListboxGetSelection(newtComponent co, int *numitems); +void newtListboxSelectItem(newtComponent co, const void * key, + enum newtFlagsSense sense); + + + +The simplest of these is newtListboxClearSelection(), which deselects +all of the items in the list (listboxes which allow multiple selections +also allow zero selections). newtListboxGetSelection() returns a +pointer to an array which contains the keys for all of the items in the +listbox currently selected. The int pointed to by numitems is +set to the number of items currently selected (and hence the number of +items in the returned array). The returned array is dynamically allocated, +and must be released through free(). + +newtListboxSelectItem() lets the program select and deselect specific +listbox entries. The key of the listbox entry is being affected is +passed, and sense is one of NEWT_FLAGS_RESET, which deselects +the entry, NEWT_FLAGS_SET, which selects the entry, or +NEWT_FLAGS_TOGGLE, which reverses the current selection status. + + + +Advanced Forms + + +Forms, which tie components together, are quite important in the world of +newt. While we've already discussed the basics of forms, we've omitted +many of the details. + + +Exiting From Forms + + +Forms return control to the application for a number of reasons: + + + + + + +A component can force the form to exit. Buttons do this whenever they +are pushed, and other components exit when NEWT_FLAG_RETURNEXIT has +been specified. + + + +Applications can setup hot keys which cause the form to exit when +they are pressed. + + + +Newt can exit when file descriptors are ready to be read or +ready to be written to. + + + +By default, newt forms exit when the F12 key is pressed (F12 is setup +as a hot key by default). Newt applications should treat F12 as an +``Ok'' button. If applications don't want F12 to exit the form, they can +specify NEWT_FLAG_NOF12 as flag when creating the form with +newtForm. + + + +void newtFormAddHotKey(newtComponent co, int key); +void newtFormWatchFd(newtComponent form, int fd, int fdFlags); + + + + + +void newtDrawForm(newtComponent form); +newtComponent newtFormGetCurrent(newtComponent co); +void newtFormSetCurrent(newtComponent co, newtComponent subco); +void newtFormRun(newtComponent co, struct newtExitStruct * es); + + + + + +newtComponent newtForm(newtComponent vertBar, const char * help, int flags); +void newtFormSetBackground(newtComponent co, int color); +void newtFormSetHeight(newtComponent co, int height); +void newtFormSetWidth(newtComponent co, int width); + + + + + +
+ diff --git a/whiptail.1 b/whiptail.1 new file mode 100644 index 0000000..ea212a8 --- /dev/null +++ b/whiptail.1 @@ -0,0 +1,316 @@ +.TH WHIPTAIL 1 "31 January 2007" "Whiptail Version 0.52.5" +.SH NAME +whiptail \- display dialog boxes from shell scripts +.SH SYNOPSIS +.B whiptail +[ +.B \-\-title +.I title +] +[ +.B \-\-backtitle +.I backtitle +] +[ +.B \-\-clear +] +[ +.B \-\-default\-item +.I string +] +[ +.B \-\-defaultno +] +[ +.B \-\-fb +] +[ +.B \-\-nocancel +] +[ +.B \-\-yes\-button +.I text +] +[ +.B \-\-no\-button +.I text +] +[ +.B \-\-ok\-button +.I text +] +[ +.B \-\-cancel\-button +.I text +] +[ +.B \-\-noitem +[ +] +.B \-\-output\-fd +.I fd +] +[ +.B \-\-separate\-output +] +[ +.B \-\-scrolltext +] +[ +.B \-\-topleft +] +.B box-options +.SH DESCRIPTION +.B whiptail +is a program that will let you present a variety of questions or +display messages using dialog boxes from a shell script. Currently, +these types of dialog boxes are implemented: +.LP +.BR yes/no " box," " menu" " box," " input" " box," +.BR message " box," " text" " box," " info" " box," +.BR checklist " box," " radiolist" " box" " gauge" " box, and" +.BR password " box." +.SH OPTIONS +.TP +.B \-\-clear +The screen will be cleared to the +.BR "screen attribute" " on exit." +This doesn't work in an xterm (and descendants) if alternate screen +switching is enabled, because in that case slang writes to (and clears) +an alternate screen. +.TP +.B \-\-defaultno +The dialog box will open with the cursor over the +.BR No " button." +.TP +.BI \-\-default\-item " string" +Set the default item in a menu box. +Normally the first item in the box is the default. +.TP +\fB\-\-fb\fR, \fB\-\-fullbuttons\fR +Use full buttons. (By default, +.B whiptail +uses compact buttons). +.TP +.B \-\-nocancel +The dialog box won't have a +.BR Cancel " button". +.TP +.BI \-\-yes\-button " text" +Set the text of the +.BR Yes " button." +.TP +.BI \-\-no\-button " text" +Set the text of the +.BR No " button." +.TP +.BI \-\-ok\-button " text" +Set the text of the +.BR Ok " button." +.TP +.BI \-\-cancel\-button " text" +Set the text of the +.BR Cancel " button." +.TP +.B \-\-noitem +The menu, checklist and radiolist widgets will display tags only, not +the item strings. The menu widget still needs some items specified, +but checklist and radiolist expect only tag and status. +.TP +.B \-\-notags +Don't display tags in the menu, checklist and radiolist widgets. +.TP +.BI \-\-separate\-output +For checklist widgets, output result one line at a time, with no +quoting. This facilitates parsing by another program. +.TP +.BI \-\-output\-fd " fd" +Direct output to the given file descriptor. Most +.B whiptail +scripts +write to standard error, but error messages may also be +written there, depending on your script. +.TP +.BI \-\-title " title" +Specifies a +.I title +string to be displayed at the top of the dialog box. +.TP +.BI \-\-backtitle " backtitle" +Specifies a +.I backtitle +string to be displayed on the backdrop, at the top of the screen. +.TP +.BI \-\-scrolltext +Force the display of a vertical scrollbar. +.TP +.BI \-\-topleft +Put window in top-left corner. +.TP +\fB\-h\fR, \fB\-\-help\fR +Print a help message and exit. +.TP +\fB\-v\fR, \fB\-\-version\fR +Print version information and exit. +.TP +.B Box Options +.TP +.BI \-\-yesno " text height width" +.RB A " yes/no" " dialog box of size" +.I height +rows by +.I width +columns will be displayed. The string specified by +.I text +is displayed inside the dialog box. If this string is too long to be fit +in one line, it will be automatically divided into multiple lines at +appropriate places. The +.I text +string may also contain the sub-string +.I +"\en" +or newline characters +.I `\en' +to control line breaking explicitly. This dialog box is useful for +asking questions that require the user to answer either yes or no. +.RB "The dialog box has a" " Yes" " button and a " No +button, in which the user can switch between by pressing the +.IR TAB " key." +.TP +.BI \-\-msgbox " text height width" +.RB A " message" " box is very similar to a" " yes/no" " box." +The only difference between a +.B message +box and a +.B yes/no +box is that a +.B message +box has only a single +.B OK +button. You can use this dialog box to display any message you like. +After reading the message, the user can press the +.I ENTER +key so that +.B whiptail +will exit and the calling shell script can continue its operation. +.TP +.BI \-\-infobox " text height width" +.RB An " info" " box is basically a" " message" " box." +However, in this case, +.B whiptail +will exit immediately after displaying the message to the user. The +screen is not cleared when +.B whiptail +exits, so that the message will remain on the screen until the calling +shell script clears it later. This is useful when you want to inform +the user that some operations are carrying on that may require some +time to finish. +.TP +.BI \-\-inputbox " text height width [init]" +.RB "An " input " box is useful when you want to ask questions that" +require the user to input a string as the answer. If init is supplied +it is used to initialize the input string. +When inputing the +string, the +.I BACKSPACE +key can be used to correct typing errors. If the input string is longer than +the width of the dialog box, the input field will be scrolled. On exit, +the input string will be printed on +.IR stderr "." +.TP +.BI \-\-passwordbox " text height width [init]" +.RB "A " password " box is similar to an input box, except the text the user" +enters is not displayed. This is useful when prompting for passwords or other +sensitive information. Be aware that if anything is passed in "init", it +will be visible in the system's process table to casual snoopers. Also, it +is very confusing to the user to provide them with a default password they +cannot see. For these reasons, using "init" is highly discouraged. +.TP +.BI \-\-textbox " file height width" +.RB A " text" " box lets you display the contents of a text file in a" +dialog box. It is like a simple text file viewer. The user can move +through the file by using the +.IR UP/DOWN ", " PGUP/PGDN +.RI and " HOME/END" " keys available on most keyboards." +If the lines are too long to be displayed in the box, the +.I LEFT/RIGHT +keys can be used to scroll the text region horizontally. For more +convenience, forward and backward searching functions are also provided. +.IP "\fB\-\-menu \fItext height width menu-height \fR[ \fItag item \fR] \fI..." +As its name suggests, a +.B menu +box is a dialog box that can be used to present a list of choices in +the form of a menu for the user to choose. Each menu entry consists of a +.IR tag " string and an " item " string. The" +.I tag +gives the entry a name to distinguish it from the other entries in the +menu. The +.I item +is a short description of the option that the entry represents. The +user can move between the menu entries by pressing the +.I UP/DOWN +keys, the first letter of the +.I tag +as a hot-key. There are +.I menu-height +entries displayed in the menu at one time, but the menu will be +scrolled if there are more entries than that. When +.B whiptail +exits, the +.I tag +of the chosen menu entry will be printed on +.IR stderr "." +.IP "\fB\-\-checklist \fItext height width list-height \fR[ \fItag item status \fR] \fI..." +.RB "A " checklist " box is similar to a " menu " box in that there are" +multiple entries presented in the form of a menu. +You can select and deselect items using the SPACE key. +The initial on/off state of each entry is specified by +.IR status "." +On exit, a list of the +.I tag +strings of those entries that are turned on will be printed on +.IR stderr "." + +.IP "\fB\-\-radiolist \fItext height width list-height \fR [ \fItag item status \fR] \fI..." +.RB "A " radiolist " box is similar to a " menu " box. The only difference is" +that you can indicate which entry is currently selected, by setting its +.IR status " to " on "." + +.IP "\fB\-\-gauge \fItext height width percent\fR" +.RB "A " gauge " box displays a meter along the bottom of the box. +The meter indicates a percentage. New percentages are read from +standard input, one integer per line. The meter is updated +to reflect each new percentage. If stdin is XXX, the first following line is +a percentage and subsequent lines up to another XXX are used for a new prompt. +The gauge exits when EOF is reached on stdin. + +.SH NOTES +whiptail interprets arguments starting with a dash "\-" as being arguments. +To avoid this, and start some text in, for example, a menubox item, with a +dash, whiptail honours the getopt convention of accepting the special +argument "\-\-" which means that all following arguments with dashes are to +be treated verbatim and not parsed as options. +.SH DIAGNOSTICS +Exit status is 0 if +.BR whiptail " is exited by pressing the " Yes " or " OK +button, and 1 if the +.BR No " or " Cancel +button is pressed. Otherwise, if errors occur inside +.B whiptail +or +.B whiptail +is exited by pressing the +.I ESC +key, the exit status is -1. +.SH AUTHOR +Based on the man page for dialog(1) by: +.LP +Savio Lam (lam836@cs.cuhk.hk) - version 0.3 +.LP +Stuart Herbert (S.Herbert@sheffield.ac.uk) - patch for version 0.4 +.LP +Modifications for whiptail by: +.LP +Enrique Zanardi (ezanard@debian.org) +.LP +Alastair McKinstry (mckinstry@debian.org) diff --git a/whiptail.c b/whiptail.c new file mode 100644 index 0000000..7932d8b --- /dev/null +++ b/whiptail.c @@ -0,0 +1,631 @@ +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nls.h" +#include "dialogboxes.h" +#include "newt.h" +#include "newt_pr.h" + +enum { NO_ERROR = 0, WAS_ERROR = 1 }; + +enum mode { MODE_NONE, MODE_INFOBOX, MODE_MSGBOX, MODE_YESNO, MODE_CHECKLIST, + MODE_INPUTBOX, MODE_RADIOLIST, MODE_MENU, MODE_GAUGE , + MODE_TEXTBOX, MODE_PASSWORDBOX}; + +#define OPT_MSGBOX 1000 +#define OPT_CHECKLIST 1001 +#define OPT_YESNO 1002 +#define OPT_INPUTBOX 1003 +#define OPT_FULLBUTTONS 1004 +#define OPT_MENU 1005 +#define OPT_RADIOLIST 1006 +#define OPT_GAUGE 1007 +#define OPT_INFOBOX 1008 +#define OPT_TEXTBOX 1009 +#define OPT_PASSWORDBOX 1010 + +static void usage(int err) { + newtFinished(); + fprintf (err ? stderr : stdout, + _("Box options: \n" + "\t--msgbox \n" + "\t--yesno \n" + "\t--infobox \n" + "\t--inputbox [init] \n" + "\t--passwordbox [init] \n" + "\t--textbox \n" + "\t--menu [tag item] ...\n" + "\t--checklist [tag item status]...\n" + "\t--radiolist [tag item status]...\n" + "\t--gauge \n" + "Options: (depend on box-option)\n" + "\t--clear clear screen on exit\n" + "\t--defaultno default no button\n" + "\t--default-item set default string\n" + "\t--fb, --fullbuttons use full buttons\n" + "\t--nocancel no cancel button\n" + "\t--yes-button set text of yes button\n" + "\t--no-button set text of no button\n" + "\t--ok-button set text of ok button\n" + "\t--cancel-button set text of cancel button\n" + "\t--noitem don't display items\n" + "\t--notags don't display tags\n" + "\t--separate-output output one line at a time\n" + "\t--output-fd output to fd, not stdout\n" + "\t--title display title\n" + "\t--backtitle <backtitle> display backtitle\n" + "\t--scrolltext force vertical scrollbars\n" + "\t--topleft put window in top-left corner\n" + "\t-h, --help print this message\n" + "\t-v, --version print version information\n\n")); + exit(err ? DLG_ERROR : 0 ); +} + +static void print_version(void) { + fprintf (stdout, _("whiptail (newt): %s\n"), VERSION); +} + +#if 0 +/* FIXME Copied from newt.c + * Place somewhere better -- dialogboxes? -- amck + */ +int wstrlen(const char *str, int len) { + mbstate_t ps; + wchar_t tmp; + int nchars = 0; + + if (!str) return 0; + if (!len) return 0; + if (len < 0) len = strlen(str); + memset(&ps,0,sizeof(mbstate_t)); + while (len > 0) { + int x,y; + + x = mbrtowc(&tmp,str,len,&ps); + if (x >0) { + str += x; + len -= x; + y = wcwidth(tmp); + if (y>0) + nchars+=y; + } else break; + } + return nchars; +} +#endif + +/* + * The value of *width is increased if it is not as large as the width of + * the line. + */ +static const char * lineWidth(int * width, const char * line, int *chrs) +{ + const char * s = line; + + if ( line == NULL ) + return 0; + + while ( *s != '\0' && *s != '\n' ) + s++; + + if ( *s == '\n' ) + s++; + + *chrs = _newt_wstrlen (line, s - line ); + *width = max(*width, *chrs); + + return s; +} + + +/* + * cleanNewlines + * Handle newlines in text. Hack. + */ +void cleanNewlines (char *text) +{ + char *p, *q; + + for (p = q = text; *p; p++, q++) + if (*p == '\\' && p[1] == 'n') { + p++; + *q = '\n'; + } else + *q = *p; + *q = '\0'; +} + +/* + * The height of a text string is added to height, and width is increased + * if it is not big enough to store the text string. + */ +static const char * textSize(int * height, int * width, + int maxWidth, + const char * text) +{ + int h = 0; + int w = 0; + int chrs = 0; + + + if ( text == NULL ) + return 0; + + while ( *text != '\0' ) { + h++; + text = lineWidth(width, text, &chrs); + /* Allow for text overflowing. May overestimate a bit */ + h += chrs / maxWidth; + } + + h += 2; + w += 2; + + *height += h; + *width += w; + + *width = min(*width, maxWidth); + return text; +} + +/* + * Add space for buttons. + * NOTE: when this is internationalized, the button width might change. + */ +static void spaceForButtons(int * height, int * width, int count, int full) { + /* Make space for the buttons */ + if ( full ) { + *height += 4; + if ( count == 1 ) + *width = max(*width, 7); + else + *width = max(*width, 20); + } + else { + *height += 2; + if ( count == 1 ) + *width = max(*width, 7); + else + *width = max(*width, 19); + } +} + +static int menuSize(int * height, int * width, enum mode mode, + poptContext options) { + const char ** argv = poptGetArgs(options); + const char ** items = argv; + int h = 0; + int tagWidth = 0; + int descriptionWidth = 0; + int overhead = 10; + static char buf[20]; + + if ( argv == 0 || *argv == 0 ) + return 0; + + argv++; + if ( mode == MODE_MENU ) + overhead = 5; + + while ( argv[0] != 0 && argv[1] ) { + tagWidth = max(tagWidth, strlen(argv[0])); + descriptionWidth = max(descriptionWidth, strlen(argv[1])); + + if ( mode == MODE_MENU ) + argv += 2; + else + argv += 3; + h++; + } + + *width = max(*width, tagWidth + descriptionWidth + overhead); + *width = min(*width, SLtt_Screen_Cols); + + h = min(h, SLtt_Screen_Rows - *height - 4); + *height = *height + h + 1; + sprintf(buf, "%d", h); + *items = buf; + return 0; +} + +/* + * Guess the size of a window, given what will be displayed within it. + */ +static void guessSize(int * height, int * width, enum mode mode, + int * flags, int fullButtons, + const char * title, const char * text, + poptContext options) { + + int w = 0, h = 0, chrs = 0; + + textSize(&h, &w, SLtt_Screen_Cols -4 , text); /* Width and height for text */ + lineWidth(&w, title, &chrs); /* Width for title */ + + if ( w > 0 ) + w += 4; + + switch ( mode ) { + case MODE_CHECKLIST: + case MODE_RADIOLIST: + case MODE_MENU: + spaceForButtons(&h, &w, *flags & FLAG_NOCANCEL ? 1 : 2, + fullButtons); + menuSize(&h, &w, mode, options); + break; + case MODE_YESNO: + case MODE_MSGBOX: + spaceForButtons(&h, &w, 1, fullButtons); + break; + case MODE_INPUTBOX: + spaceForButtons(&h, &w, *flags & FLAG_NOCANCEL ? 1 : 2, + fullButtons); + h += 1; + break; + case MODE_GAUGE: + h += 2; + break; + case MODE_NONE: + break; + default: + break; + }; + + /* + * Fixed window-border overhead. + * NOTE: This will change if we add a way to turn off drop-shadow and/or + * box borders. That would be desirable for display-sized screens. + */ + w += 2; + h += 2; + + if ( h > SLtt_Screen_Rows - 1 ) { + h = SLtt_Screen_Rows - 1; + *flags |= FLAG_SCROLL_TEXT; + w += 2; /* Add width of slider - is this right? */ + } + + *width = min(max(*width, w), SLtt_Screen_Cols); + *height = max(*height, h); +} + +char * +readTextFile(const char * filename) +{ + int fd = open(filename, O_RDONLY, 0); + struct stat s; + char * buf; + + if ( fd < 0 || fstat(fd, &s) != 0 ) { + perror(filename); + exit(DLG_ERROR); + } + + if ( (buf = malloc(s.st_size + 1)) == 0 ) { + fprintf(stderr, _("%s: too large to display.\n"), filename); + exit(DLG_ERROR); + } + + if ( read(fd, buf, s.st_size) != s.st_size ) { + perror(filename); + exit(DLG_ERROR); + } + close(fd); + buf[s.st_size] = '\0'; + return buf; +} + +int main(int argc, const char ** argv) { + enum mode mode = MODE_NONE; + poptContext optCon; + int arg; + char * text; + const char * nextArg; + char * end; + int height; + int width; + int fd = -1; + int needSpace = 0; + int noCancel = 0; + int noTags = 0; + int noItem = 0; + int clear = 0; + int scrollText = 0; + int rc = DLG_CANCEL; + int flags = 0; + int defaultNo = 0; + int separateOutput = 0; + int fullButtons = 0; + int outputfd = 2; + int topLeft = 0; + FILE *output = stderr; + char * result; + char ** selections, ** next; + char * title = NULL; + char *default_item = NULL; + char * backtitle = NULL; + char * yes_button = NULL; + char * no_button = NULL; + char * ok_button = NULL; + char * cancel_button = NULL; + int help = 0, version = 0; + struct poptOption optionsTable[] = { + { "backtitle", '\0', POPT_ARG_STRING, &backtitle, 0 }, + { "checklist", '\0', 0, 0, OPT_CHECKLIST }, + { "clear", '\0', 0, &clear, 0 }, + { "defaultno", '\0', 0, &defaultNo, 0 }, + { "inputbox", '\0', 0, 0, OPT_INPUTBOX }, + { "fb", '\0', 0, 0, OPT_FULLBUTTONS }, + { "fullbuttons", '\0', 0, 0, OPT_FULLBUTTONS }, + { "gauge", '\0', 0, 0, OPT_GAUGE }, + { "infobox", '\0', 0, 0, OPT_INFOBOX }, + { "menu", '\0', 0, 0, OPT_MENU }, + { "msgbox", '\0', 0, 0, OPT_MSGBOX }, + { "nocancel", '\0', 0, &noCancel, 0 }, + { "noitem", '\0', 0, &noItem, 0 }, + { "default-item", '\0', POPT_ARG_STRING, &default_item, 0}, + { "notags", '\0', 0, &noTags, 0 }, + { "radiolist", '\0', 0, 0, OPT_RADIOLIST }, + { "scrolltext", '\0', 0, &scrollText, 0 }, + { "separate-output", '\0', 0, &separateOutput, 0 }, + { "title", '\0', POPT_ARG_STRING, &title, 0 }, + { "textbox", '\0', 0, 0, OPT_TEXTBOX }, + { "topleft", '\0', 0, &topLeft, 0 }, + { "yesno", '\0', 0, 0, OPT_YESNO }, + { "passwordbox", '\0', 0, 0, OPT_PASSWORDBOX }, + { "output-fd", '\0', POPT_ARG_INT, &outputfd, 0 }, + { "yes-button", '\0', POPT_ARG_STRING, &yes_button, 0}, + { "no-button", '\0', POPT_ARG_STRING, &no_button, 0}, + { "ok-button", '\0', POPT_ARG_STRING, &ok_button, 0}, + { "cancel-button", '\0', POPT_ARG_STRING, &cancel_button, 0}, + { "help", 'h', 0, &help, 0, NULL, NULL }, + { "version", 'v', 0, &version, 0, NULL, NULL }, + { 0, 0, 0, 0, 0 } + }; + +#ifdef ENABLE_NLS + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); +#endif + + optCon = poptGetContext("whiptail", argc, argv, optionsTable, 0); + + while ((arg = poptGetNextOpt(optCon)) > 0) { + switch (arg) { + case OPT_INFOBOX: + if (mode != MODE_NONE) usage(WAS_ERROR); + mode = MODE_INFOBOX; + break; + + case OPT_MENU: + if (mode != MODE_NONE) usage(WAS_ERROR); + mode = MODE_MENU; + break; + + case OPT_MSGBOX: + if (mode != MODE_NONE) usage(WAS_ERROR); + mode = MODE_MSGBOX; + break; + + case OPT_TEXTBOX: + if (mode != MODE_NONE) usage(WAS_ERROR); + mode = MODE_TEXTBOX; + break; + + case OPT_PASSWORDBOX: + if (mode != MODE_NONE) usage(WAS_ERROR); + mode = MODE_PASSWORDBOX; + break; + + case OPT_RADIOLIST: + if (mode != MODE_NONE) usage(WAS_ERROR); + mode = MODE_RADIOLIST; + break; + + case OPT_CHECKLIST: + if (mode != MODE_NONE) usage(WAS_ERROR); + mode = MODE_CHECKLIST; + break; + + case OPT_FULLBUTTONS: + fullButtons = 1; + useFullButtons(1); + break; + + case OPT_YESNO: + if (mode != MODE_NONE) usage(WAS_ERROR); + mode = MODE_YESNO; + break; + + case OPT_GAUGE: + if (mode != MODE_NONE) usage(WAS_ERROR); + mode = MODE_GAUGE; + break; + + case OPT_INPUTBOX: + if (mode != MODE_NONE) usage(WAS_ERROR); + mode = MODE_INPUTBOX; + break; + } + } + + if (help) { + usage(NO_ERROR); + exit(0); + } + if (version) { + print_version(); + exit(0); + } + + if (arg < -1) { + fprintf(stderr, "%s: %s\n", + poptBadOption(optCon, POPT_BADOPTION_NOALIAS), + poptStrerror(arg)); + exit(1); + } + + output = fdopen (outputfd, "w"); + if (output == NULL ) { + perror ("Cannot open output-fd\n"); + exit (DLG_ERROR); + } + + if (mode == MODE_NONE) usage(WAS_ERROR); + + if (!(nextArg = poptGetArg(optCon))) usage(WAS_ERROR); + text = strdup(nextArg); + + if (mode == MODE_TEXTBOX) { + char *t = text; + text = readTextFile(t); + free(t); + } + + if (!(nextArg = poptGetArg(optCon))) usage(WAS_ERROR); + height = strtoul(nextArg, &end, 10); + if (*end) usage(WAS_ERROR); + + if (!(nextArg = poptGetArg(optCon))) usage(WAS_ERROR); + width = strtoul(nextArg, &end, 10); + if (*end) usage(WAS_ERROR); + + if (mode == MODE_GAUGE) { + fd = dup(0); + if (fd < 0 || close(0) < 0) { + perror("dup/close stdin"); + exit(DLG_ERROR); + } + if (open("/dev/tty", O_RDWR) != 0) { + perror("open /dev/tty"); + exit(DLG_ERROR); + } + } + + newtInit(); + newtCls(); + + cleanNewlines(text); + + if ( height <= 0 || width <= 0 ) + guessSize(&height, &width, mode, &flags, fullButtons, title, text, + optCon); + + width -= 2; + height -= 2; + + newtOpenWindow(topLeft ? 1 : (SLtt_Screen_Cols - width) / 2, + topLeft ? 1 : (SLtt_Screen_Rows - height) / 2, width, height, title); + if (backtitle) + newtDrawRootText(0, 0, backtitle); + + if (ok_button) + setButtonText(ok_button, BUTTON_OK); + if (cancel_button) + setButtonText(cancel_button, BUTTON_CANCEL); + if (yes_button) + setButtonText(yes_button, BUTTON_YES); + if (no_button) + setButtonText(no_button, BUTTON_NO); + + if (noCancel) flags |= FLAG_NOCANCEL; + if (noItem) flags |= FLAG_NOITEM; + if (noTags) flags |= FLAG_NOTAGS; + if (scrollText) flags |= FLAG_SCROLL_TEXT; + if (defaultNo) flags |= FLAG_DEFAULT_NO; + + switch (mode) { + case MODE_MSGBOX: + case MODE_TEXTBOX: + rc = messageBox(text, height, width, MSGBOX_MSG, flags); + break; + + case MODE_INFOBOX: + rc = messageBox(text, height, width, MSGBOX_INFO, flags); + break; + + case MODE_YESNO: + rc = messageBox(text, height, width, MSGBOX_YESNO, flags); + break; + + case MODE_INPUTBOX: + rc = inputBox(text, height, width, optCon, flags, &result); + if (rc == DLG_OKAY) { + fprintf(output, "%s", result); + free(result); + } + break; + + case MODE_PASSWORDBOX: + rc = inputBox(text, height, width, optCon, flags | FLAG_PASSWORD, + &result); + if (rc == DLG_OKAY) { + fprintf (output, "%s", result); + free(result); + } + break; + + case MODE_MENU: + rc = listBox(text, height, width, optCon, flags, default_item, &result); + if (rc == DLG_OKAY) { + fprintf(output, "%s", result); + free(result); + } + break; + + case MODE_RADIOLIST: + rc = checkList(text, height, width, optCon, 1, flags, &selections); + if (rc == DLG_OKAY && selections[0]) { + fprintf(output, "%s", selections[0]); + free(selections[0]); + free(selections); + } + break; + + case MODE_CHECKLIST: + rc = checkList(text, height, width, optCon, 0, flags, &selections); + + if (!rc) { + for (next = selections; *next; next++) { + if (!separateOutput) { + if (needSpace) putc(' ', output); + fprintf(output, "\"%s\"", *next); + needSpace = 1; + } else { + fprintf(output, "%s\n", *next); + } + free(*next); + } + + free(selections); + } + break; + + case MODE_GAUGE: + rc = gauge(text, height, width, optCon, fd, flags); + break; + + default: + usage(WAS_ERROR); + } + + if (rc == DLG_ERROR) usage(WAS_ERROR); + + if (clear) + newtPopWindow(); + newtFinished(); + + free(text); + poptFreeContext(optCon); + + return ( rc == DLG_ESCAPE ) ? -1 : rc; +} diff --git a/whiptcl.c b/whiptcl.c new file mode 100644 index 0000000..8688780 --- /dev/null +++ b/whiptcl.c @@ -0,0 +1,313 @@ +#include "config.h" +#include <string.h> +#include <stdlib.h> + +#include "nls.h" +#include "dialogboxes.h" +#include "newt.h" +#include <popt.h> +#include <tcl.h> + +enum mode { MODE_NONE, MODE_MSGBOX, MODE_YESNO, MODE_CHECKLIST, MODE_INPUTBOX, + MODE_RADIOLIST, MODE_MENU }; + +#define OPT_MSGBOX 1000 +#define OPT_CHECKLIST 1001 +#define OPT_YESNO 1002 +#define OPT_INPUTBOX 1003 +#define OPT_MENU 1005 +#define OPT_RADIOLIST 1006 + +static char * setBacktext(ClientData data, Tcl_Interp * interp, + const char * name1, const char * name2, int flags); +static char * setHelptext(ClientData data, Tcl_Interp * interp, + const char * name1, const char * name2, int flags); +static char * setFullButtons(ClientData data, Tcl_Interp * interp, + const char * name1, const char * name2, int flags); + +static int wtFinish(ClientData clientData, Tcl_Interp * interp, int argc, + const char ** argv) { + newtFinished(); + + return TCL_OK; +} + +static int wtInit(ClientData clientData, Tcl_Interp * interp, int argc, + const char ** argv) { + newtInit(); + newtCls(); + + newtPushHelpLine(""); + + Tcl_TraceVar(interp, "whiptcl_backtext", + TCL_TRACE_WRITES | TCL_GLOBAL_ONLY, setBacktext, NULL); + Tcl_TraceVar(interp, "whiptcl_helpline", + TCL_TRACE_WRITES | TCL_TRACE_UNSETS | TCL_GLOBAL_ONLY, + setHelptext, NULL); + Tcl_TraceVar(interp, "whiptcl_fullbuttons", + TCL_TRACE_WRITES | TCL_TRACE_UNSETS | TCL_GLOBAL_ONLY, + setFullButtons, NULL); + + Tcl_SetVar(interp, "whiptcl_helpline", "", TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, "whiptcl_fullbuttons", "1", TCL_GLOBAL_ONLY); + + return TCL_OK; +} + +static int wtCmd(ClientData clientData, Tcl_Interp * interp, int argc, + const char ** argv) { + enum mode mode = MODE_NONE; + poptContext optCon; + int arg; + const char * optArg; + const char * text; + const char * nextArg; + char * end; + int height; + int width; + int noCancel = 0; + int noItem = 0; + int scrollText = 0; + int rc = 0; + int flags = 0; + int defaultNo = 0; + char * result; + char ** selections, ** next; + char * title = NULL; + char *default_item = NULL; + struct poptOption optionsTable[] = { + { "checklist", '\0', 0, 0, OPT_CHECKLIST }, + { "defaultno", '\0', 0, &defaultNo, 0 }, + { "inputbox", '\0', 0, 0, OPT_INPUTBOX }, + { "menu", '\0', 0, 0, OPT_MENU }, + { "msgbox", '\0', 0, 0, OPT_MSGBOX }, + { "nocancel", '\0', 0, &noCancel, 0 }, + { "noitem", '\0', 0, &noItem, 0 }, + { "radiolist", '\0', 0, 0, OPT_RADIOLIST }, + { "scrolltext", '\0', 0, &scrollText, 0 }, + { "title", '\0', POPT_ARG_STRING, &title, 0 }, + { "default-item", '\0', POPT_ARG_STRING, &default_item, 0 }, + { "yesno", '\0', 0, 0, OPT_YESNO }, + { 0, 0, 0, 0, 0 } + }; + +#ifdef ENABLE_NLS + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); +#endif + + optCon = poptGetContext("whiptcl", argc, argv, optionsTable, 0); + + while ((arg = poptGetNextOpt(optCon)) > 0) { + optArg = poptGetOptArg(optCon); + + switch (arg) { + case OPT_MENU: + if (mode != MODE_NONE) rc = -1; + mode = MODE_MENU; + break; + + case OPT_MSGBOX: + if (mode != MODE_NONE) rc = -1; + mode = MODE_MSGBOX; + break; + + case OPT_RADIOLIST: + if (mode != MODE_NONE) rc = -1; + mode = MODE_RADIOLIST; + break; + + case OPT_CHECKLIST: + if (mode != MODE_NONE) rc = -1; + mode = MODE_CHECKLIST; + break; + + case OPT_YESNO: + if (mode != MODE_NONE) rc = -1; + mode = MODE_YESNO; + break; + + case OPT_INPUTBOX: + if (mode != MODE_NONE) rc = -1; + mode = MODE_INPUTBOX; + break; + } + } + + if (arg < -1) { + /* this could buffer oveflow, bug we're not setuid so I don't care */ + interp->result = malloc(200); + interp->freeProc = TCL_DYNAMIC; + sprintf(interp->result, "%s: %s\n", + poptBadOption(optCon, POPT_BADOPTION_NOALIAS), + poptStrerror(arg)); + + return TCL_ERROR; + } + + if (mode == MODE_NONE) { + interp->result = "no dialog mode was specified"; + return TCL_ERROR; + } else if (rc) { + interp->result = "multiple modes were specified"; + return TCL_ERROR; + } + + if (!(text = poptGetArg(optCon))) { + interp->result = "missing text parameter"; + return TCL_ERROR; + } + + if (!(nextArg = poptGetArg(optCon))) { + interp->result = "height missing"; + return TCL_ERROR; + } + height = strtoul(nextArg, &end, 10); + if (*end) { + interp->result = "height is not a number"; + return TCL_ERROR; + } + + if (!(nextArg = poptGetArg(optCon))) { + interp->result = "width missing"; + return TCL_ERROR; + } + width = strtoul(nextArg, &end, 10); + if (*end) { + interp->result = "width is not a number"; + return TCL_ERROR; + } + + width -= 2; + height -= 2; + newtOpenWindow((80 - width) / 2, (24 - height) / 2, width, height, title); + + if (noCancel) flags |= FLAG_NOCANCEL; + if (noItem) flags |= FLAG_NOITEM; + if (scrollText) flags |= FLAG_SCROLL_TEXT; + if (defaultNo) flags |= FLAG_DEFAULT_NO; + + switch (mode) { + case MODE_MSGBOX: + rc = messageBox(text, height, width, MSGBOX_MSG, flags); + break; + + case MODE_YESNO: + rc = messageBox(text, height, width, MSGBOX_YESNO, flags); + if (rc == DLG_OKAY) + interp->result = "yes"; + else + interp->result = "no"; + if (rc == DLG_ERROR) rc = 0; + break; + + case MODE_INPUTBOX: + rc = inputBox(text, height, width, optCon, flags, &result); + if (rc ==DLG_OKAY) { + interp->result = result; + interp->freeProc = TCL_DYNAMIC; + } + break; + + case MODE_MENU: + rc = listBox(text, height, width, optCon, flags, default_item, &result); + if (rc==DLG_OKAY) { + interp->result = result; + interp->freeProc = TCL_DYNAMIC; + } + break; + + case MODE_RADIOLIST: + rc = checkList(text, height, width, optCon, 1, flags, &selections); + if (rc==DLG_OKAY) { + interp->result = selections[0]; + interp->freeProc = TCL_DYNAMIC; + + free(selections); + } + break; + + case MODE_CHECKLIST: + rc = checkList(text, height, width, optCon, 0, flags, &selections); + + if (rc==DLG_OKAY) { + for (next = selections; *next; next++) + Tcl_AppendElement(interp, *next); + + free(selections); + } + break; + + case MODE_NONE: + ; /* this can't happen */ + break; + } + + newtPopWindow(); + + if (rc == DLG_ERROR) { + interp->result = "bad paramter for whiptcl dialog box"; + return TCL_ERROR; + } + + Tcl_SetVar(interp, "whiptcl_canceled", (rc == DLG_CANCEL) ? "1" : "0", + 0); + Tcl_SetVar(interp, "whiptcl_escaped", (rc == DLG_ESCAPE) ? "1" : "0", + 0); + + return TCL_OK; +} + +static char * setBacktext(ClientData data, Tcl_Interp * interp, + const char * name1, const char * name2, int flags) { + static char blankLine[81] = " " + " "; + + newtDrawRootText(0, 0, blankLine); + newtDrawRootText(0, 0, Tcl_GetVar(interp, "whiptcl_backtext", + TCL_GLOBAL_ONLY)); + + return NULL; +} + +static char * setHelptext(ClientData data, Tcl_Interp * interp, + const char * name1, const char * name2, int flags) { + const char * text = Tcl_GetVar(interp, "whiptcl_helpline", TCL_GLOBAL_ONLY); + + if (!text) + text = ""; + else if (!strlen(text)) + text = NULL; + + newtPopHelpLine(); + newtPushHelpLine(text); + + return NULL; +} + +static char * setFullButtons(ClientData data, Tcl_Interp * interp, + const char * name1, const char * name2, int flags) { + const char * val = Tcl_GetVar(interp, "whiptcl_fullbuttons", TCL_GLOBAL_ONLY); + int rc; + int state; + + if ((rc = Tcl_ExprBoolean(interp, val, &state))) { + Tcl_FreeResult(interp); + return "whiptcl_fullbuttons may only contain a boolean value"; + } + + useFullButtons(state); + + return NULL; +} + +int Whiptcl_Init(Tcl_Interp * interp) { + Tcl_CreateCommand(interp, "whiptcl_finish", wtFinish, NULL, NULL); + Tcl_CreateCommand(interp, "whiptcl_init", wtInit, NULL, NULL); + Tcl_CreateCommand(interp, "whiptcl_cmd", (Tcl_CmdProc *) wtCmd, NULL, NULL); + + Tcl_PkgProvide(interp, "Whip", VERSION); + + return TCL_OK; +} diff --git a/windows.c b/windows.c new file mode 100644 index 0000000..f1381ae --- /dev/null +++ b/windows.c @@ -0,0 +1,282 @@ +#include <errno.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "errno.h" +#include "newt.h" + +static void * newtvwindow(char * title, char * button1, char * button2, + char * button3, char * message, va_list args) { + newtComponent b1, b2 = NULL, b3 = NULL, t, f, answer; + char * buf = NULL; + int size = 0; + int i = 0; + int scroll = 0; + int width, height; + char * flowedText; + newtGrid grid, buttonGrid; + + do { + va_list argscopy; + + va_copy(argscopy, args); + size += 1000; + if (buf) free(buf); + buf = malloc(size); + i = vsnprintf(buf, size, message, argscopy); + va_end(argscopy); + } while (i >= size || i == -1); + + flowedText = newtReflowText(buf, 35, 5, 5, &width, &height); + if (height > 6) { + free(flowedText); + flowedText = newtReflowText(buf, 60, 5, 5, &width, &height); + } + free(buf); + + if (height > 12) { + height = 12; + scroll = NEWT_FLAG_SCROLL; + } + t = newtTextbox(-1, -1, width, height, NEWT_TEXTBOX_WRAP | scroll); + newtTextboxSetText(t, flowedText); + free(flowedText); + + if (button3) { + buttonGrid = newtButtonBar(button1, &b1, button2, &b2, + button3, &b3, NULL); + } else if (button2) { + buttonGrid = newtButtonBar(button1, &b1, button2, &b2, NULL); + } else { + buttonGrid = newtButtonBar(button1, &b1, NULL); + } + + newtGridSetField(buttonGrid, 0, 0, NEWT_GRID_COMPONENT, b1, + 0, 0, button2 ? 1 : 0, 0, 0, 0); + + grid = newtCreateGrid(1, 2); + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, t, 0, 0, 0, 0, 0, 0); + newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, buttonGrid, + 0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX); + newtGridWrappedWindow(grid, title); + + f = newtForm(NULL, NULL, 0); + newtFormAddComponents(f, t, b1, NULL); + + if (button2) + newtFormAddComponent(f, b2); + if (button3) + newtFormAddComponent(f, b3); + + answer = newtRunForm(f); + newtGridFree(grid, 1); + + newtFormDestroy(f); + newtPopWindow(); + + if (answer == f) + return NULL; + else if (answer == b1) + return button1; + else if (answer == b2) + return button2; + + return button3; +} + +int newtWinChoice(char * title, char * button1, char * button2, + char * message, ...) { + va_list args; + void * rc; + + va_start(args, message); + rc = newtvwindow(title, button1, button2, NULL, message, args); + va_end(args); + + if (rc == button1) + return 1; + else if (rc == button2) + return 2; + + return 0; +} + +void newtWinMessage(char * title, char * buttonText, char * text, ...) { + va_list args; + + va_start(args, text); + newtvwindow(title, buttonText, NULL, NULL, text, args); + va_end(args); +} + +void newtWinMessagev(char * title, char * buttonText, char * text, + va_list argv) { + newtvwindow(title, buttonText, NULL, NULL, text, argv); +} + +int newtWinTernary(char * title, char * button1, char * button2, + char * button3, char * message, ...) { + va_list args; + void * rc; + + va_start(args, message); + rc = newtvwindow(title, button1, button2, button3, message, args); + va_end(args); + + if (rc == button1) + return 1; + else if (rc == button2) + return 2; + else if (rc == button3) + return 3; + + return 0; +} + +int newtWinMenu(char * title, char * text, int suggestedWidth, int flexDown, + int flexUp, int maxListHeight, char ** items, int * listItem, + char * button1, ...) { + newtComponent textbox, listbox, result, form; + va_list args; + newtComponent *buttons = NULL; + newtGrid grid, buttonBar; + size_t totalButtons = 0, numButtons = 0; + int i, rc; + int needScroll; + char * buttonName; + + textbox = newtTextboxReflowed(-1, -1, text, suggestedWidth, flexDown, + flexUp, 0); + + for (i = 0; items[i]; i++) ; + if (i < maxListHeight) maxListHeight = i; + needScroll = i > maxListHeight; + + listbox = newtListbox(-1, -1, maxListHeight, + (needScroll ? NEWT_FLAG_SCROLL : 0) | NEWT_FLAG_RETURNEXIT); + for (i = 0; items[i]; i++) { + newtListboxAddEntry(listbox, items[i], (void *)(long) i); + } + + newtListboxSetCurrent(listbox, *listItem); + + va_start(args, button1); + for (buttonName = button1; buttonName; buttonName = va_arg(args, char *)) + ++totalButtons; + va_end(args); + + buttons = (newtComponent *)alloca(sizeof(newtComponent)*(totalButtons)); + va_start(args, button1); + for (buttonName = button1; buttonName; buttonName = va_arg(args, char *)) + buttons[numButtons++] = newtButton(-1, -1, buttonName); + va_end(args); + + buttonBar = newtCreateGrid(numButtons ? numButtons : 1, 1); + for (i = 0; i < numButtons; i++) { + newtGridSetField(buttonBar, i, 0, NEWT_GRID_COMPONENT, + buttons[i], + i ? 1 : 0, 0, 0, 0, 0, 0); + } + + grid = newtGridSimpleWindow(textbox, listbox, buttonBar); + newtGridWrappedWindow(grid, title); + + form = newtForm(NULL, 0, 0); + newtGridAddComponentsToForm(grid, form, 1); + newtGridFree(grid, 1); + + result = newtRunForm(form); + + *listItem = ((long) newtListboxGetCurrent(listbox)); + + for (rc = 0; rc < numButtons && result != buttons[rc]; rc++) + ; + if (rc == numButtons) + rc = 0; /* F12 or return-on-exit (which are the same for us) */ + else + rc++; + + newtFormDestroy(form); + newtPopWindow(); + + return rc; +} + +int newtWinEntries(char * title, char * text, int suggestedWidth, int flexDown, + int flexUp, int dataWidth, + struct newtWinEntry * items, char * button1, ...) { + newtComponent *buttons, result, form, textw; + newtGrid grid, buttonBar, subgrid; + int numItems; + int rc, i; + size_t numButtons = 0, totalButtons = 0; + char * buttonName; + va_list args; + + textw = newtTextboxReflowed(-1, -1, text, suggestedWidth, flexDown, + flexUp, 0); + + for (numItems = 0; items[numItems].text; numItems++); + + buttonName = button1; + va_start(args, button1); + for (buttonName = button1; buttonName; buttonName = va_arg(args, char *)) + ++totalButtons; + va_end(args); + + buttons = (newtComponent *)alloca(sizeof(newtComponent)*(totalButtons)); + va_start(args, button1); + for (buttonName = button1; buttonName; buttonName = va_arg(args, char *)) + buttons[numButtons++] = newtButton(-1, -1, buttonName); + va_end(args); + + buttonBar = newtCreateGrid(numButtons ? numButtons : 1, 1); + for (i = 0; i < numButtons; i++) { + newtGridSetField(buttonBar, i, 0, NEWT_GRID_COMPONENT, + buttons[i], + i ? 1 : 0, 0, 0, 0, 0, 0); + } + + subgrid = newtCreateGrid(2, numItems ? numItems : 1); + for (i = 0; i < numItems; i++) { + newtGridSetField(subgrid, 0, i, NEWT_GRID_COMPONENT, + newtLabel(-1, -1, items[i].text), + 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); + newtGridSetField(subgrid, 1, i, NEWT_GRID_COMPONENT, + newtEntry(-1, -1, items[i].value ? + *items[i].value : NULL, dataWidth, + (const char **)items[i].value, items[i].flags), + 1, 0, 0, 0, 0, 0); + } + + grid = newtCreateGrid(1, 3); + form = newtForm(NULL, 0, 0); + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, textw, + 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); + newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, subgrid, + 0, 1, 0, 0, 0, 0); + newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttonBar, + 0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX); + newtGridAddComponentsToForm(grid, form, 1); + newtGridWrappedWindow(grid, title); + newtGridFree(grid, 1); + + result = newtRunForm(form); + + for (rc = 0; rc < numItems; rc++) + *items[rc].value = strdup(*items[rc].value); + + for (rc = 0; rc < numButtons && result != buttons[rc]; rc++) + ; + if (rc == numButtons) + rc = 0; /* F12 */ + else + rc++; + + newtFormDestroy(form); + newtPopWindow(); + + return rc; +}