From: Thomas E. Dickey Date: Sun, 8 Dec 2013 01:49:22 +0000 (+0000) Subject: ncurses 5.9 - patch 20131207 X-Git-Tag: v6.0~78 X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=commitdiff_plain;h=02788b9c63ac2668473510a98fa151ecc0fb1e39;hp=7bffc4856038714ab0ce0999986d25bb8ca1b890 ncurses 5.9 - patch 20131207 + add form_driver_w() entrypoint to wide-character forms library, as well as test program form_driver_w (adapted from patch by Gaute Hope). --- diff --git a/NEWS b/NEWS index b7bf22bb..a75adbb1 100644 --- a/NEWS +++ b/NEWS @@ -25,7 +25,7 @@ -- sale, use or other dealings in this Software without prior written -- -- authorization. -- ------------------------------------------------------------------------------- --- $Id: NEWS,v 1.2143 2013/11/23 18:29:01 tom Exp $ +-- $Id: NEWS,v 1.2145 2013/12/07 18:26:50 tom Exp $ ------------------------------------------------------------------------------- This is a log of changes that ncurses has gone through since Zeyd started @@ -45,6 +45,11 @@ See the AUTHORS file for the corresponding full names. Changes through 1.9.9e did not credit all contributions; it is not possible to add this information. +20131207 + + add form_driver_w() entrypoint to wide-character forms library, as + well as test program form_driver_w (adapted from patch by Gaute + Hope). + 20131123 + minor fix for CF_GCC_WARNINGS to special-case options which are not recognized by clang. diff --git a/dist.mk b/dist.mk index 1578d910..eba8a7fe 100644 --- a/dist.mk +++ b/dist.mk @@ -25,7 +25,7 @@ # use or other dealings in this Software without prior written # # authorization. # ############################################################################## -# $Id: dist.mk,v 1.959 2013/11/23 18:02:48 tom Exp $ +# $Id: dist.mk,v 1.960 2013/12/07 15:21:58 tom Exp $ # Makefile for creating ncurses distributions. # # This only needs to be used directly as a makefile by developers, but @@ -37,7 +37,7 @@ SHELL = /bin/sh # These define the major/minor/patch versions of ncurses. NCURSES_MAJOR = 5 NCURSES_MINOR = 9 -NCURSES_PATCH = 20131123 +NCURSES_PATCH = 20131207 # We don't append the patch to the version, since this only applies to releases VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR) diff --git a/form/form.h b/form/form.h index f52893b9..f1a6635e 100644 --- a/form/form.h +++ b/form/form.h @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2004,2009 Free Software Foundation, Inc. * + * Copyright (c) 1998-2009,2013 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * @@ -30,7 +30,7 @@ * Author: Juergen Pfeifer, 1995,1997 * ****************************************************************************/ -/* $Id: form.h,v 0.21 2009/11/07 19:31:11 tom Exp $ */ +/* $Id: form.h,v 0.23 2013/12/07 17:57:32 tom Exp $ */ #ifndef FORM_H #define FORM_H @@ -396,6 +396,9 @@ extern NCURSES_EXPORT(int) post_form (FORM *); extern NCURSES_EXPORT(int) unpost_form (FORM *); extern NCURSES_EXPORT(int) pos_form_cursor (FORM *); extern NCURSES_EXPORT(int) form_driver (FORM *,int); +# if NCURSES_WIDECHAR +extern NCURSES_EXPORT(int) form_driver_w (FORM *,int,wchar_t); +# endif extern NCURSES_EXPORT(int) set_form_userptr (FORM *,void *); extern NCURSES_EXPORT(int) set_form_opts (FORM *,Form_Options); extern NCURSES_EXPORT(int) form_opts_on (FORM *,Form_Options); diff --git a/form/frm_driver.c b/form/frm_driver.c index d9204334..9c73125f 100644 --- a/form/frm_driver.c +++ b/form/frm_driver.c @@ -32,7 +32,7 @@ #include "form.priv.h" -MODULE_ID("$Id: frm_driver.c,v 1.106 2013/08/25 00:02:15 tom Exp $") +MODULE_ID("$Id: frm_driver.c,v 1.109 2013/12/08 01:06:41 tom Exp $") /*---------------------------------------------------------------------------- This is the core module of the form library. It contains the majority @@ -3982,6 +3982,94 @@ PN_Last_Page(FORM *form) Helper routines for the core form driver. --------------------------------------------------------------------------*/ +# if USE_WIDEC_SUPPORT +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int Data_Entry_w(FORM * form, wchar_t c) +| +| Description : Enter the wide character c into at the current +| position of the current field of the form. +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - driver could not process the request +| E_SYSTEM_ERROR - ++--------------------------------------------------------------------------*/ +static int +Data_Entry_w(FORM *form, wchar_t c) +{ + FIELD *field = form->current; + int result = E_REQUEST_DENIED; + + T((T_CALLED("Data_Entry(%p,%s)"), (void *)form, _tracechtype((chtype)c))); + if (((unsigned)field->opts & O_EDIT) +#if FIX_FORM_INACTIVE_BUG + && ((unsigned)field->opts & O_ACTIVE) +#endif + ) + { + wchar_t given[2]; + cchar_t temp_ch; + + given[0] = c; + given[1] = 1; + setcchar(&temp_ch, given, 0, 0, (void *)0); + if (((unsigned)field->opts & O_BLANK) && + First_Position_In_Current_Field(form) && + !(form->status & _FCHECK_REQUIRED) && + !(form->status & _WINDOW_MODIFIED)) + werase(form->w); + + if (form->status & _OVLMODE) + { + wadd_wch(form->w, &temp_ch); + } + else + /* no _OVLMODE */ + { + bool There_Is_Room = Is_There_Room_For_A_Char_In_Line(form); + + if (!(There_Is_Room || + ((Single_Line_Field(field) && Growable(field))))) + RETURN(E_REQUEST_DENIED); + + if (!There_Is_Room && !Field_Grown(field, 1)) + RETURN(E_SYSTEM_ERROR); + + wins_wch(form->w, &temp_ch); + } + + if ((result = Wrapping_Not_Necessary_Or_Wrapping_Ok(form)) == E_OK) + { + bool End_Of_Field = (((field->drows - 1) == form->currow) && + ((field->dcols - 1) == form->curcol)); + + form->status |= _WINDOW_MODIFIED; + if (End_Of_Field && !Growable(field) && ((unsigned)field->opts & O_AUTOSKIP)) + result = Inter_Field_Navigation(FN_Next_Field, form); + else + { + if (End_Of_Field && Growable(field) && !Field_Grown(field, 1)) + result = E_SYSTEM_ERROR; + else + { + /* + * We have just added a byte to the form field. It may have + * been part of a multibyte character. If it was, the + * addch_used field is nonzero and we should not try to move + * to a new column. + */ + if (WINDOW_EXT(form->w, addch_used) == 0) + IFN_Next_Character(form); + + result = E_OK; + } + } + } + } + RETURN(result); +} +# endif + /*--------------------------------------------------------------------------- | Facility : libnform | Function : static int Data_Entry(FORM * form,int c) @@ -4368,6 +4456,195 @@ form_driver(FORM *form, int c) RETURN(res); } +# if USE_WIDEC_SUPPORT +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int form_driver_w(FORM * form,int type,wchar_t c) +| +| Description : This is the workhorse of the forms system. +| +| Input is either a key code (request) or a wide char +| returned by e.g. get_wch (). The type must be passed +| as well,so that we are able to determine whether the char +| is a multibyte char or a request. + +| If it is a request, the form driver executes +| the request and returns the result. If it is data +| (printable character), it enters the data into the +| current position in the current field. If it is not +| recognized, the form driver assumes it is an application +| defined command and returns E_UNKNOWN_COMMAND. +| Application defined command should be defined relative +| to MAX_FORM_COMMAND, the maximum value of a request. +| +| Return Values : E_OK - success +| E_SYSTEM_ERROR - system error +| E_BAD_ARGUMENT - an argument is incorrect +| E_NOT_POSTED - form is not posted +| E_INVALID_FIELD - field contents are invalid +| E_BAD_STATE - called from inside a hook routine +| E_REQUEST_DENIED - request failed +| E_NOT_CONNECTED - no fields are connected to the form +| E_UNKNOWN_COMMAND - command not known ++--------------------------------------------------------------------------*/ +NCURSES_EXPORT(int) +form_driver_w(FORM *form, int type, wchar_t c) +{ + const Binding_Info *BI = (Binding_Info *) 0; + int res = E_UNKNOWN_COMMAND; + + T((T_CALLED("form_driver(%p,%d)"), (void *)form, c)); + + if (!form) + RETURN(E_BAD_ARGUMENT); + + if (!(form->field)) + RETURN(E_NOT_CONNECTED); + + assert(form->page); + + if (c == FIRST_ACTIVE_MAGIC) + { + form->current = _nc_First_Active_Field(form); + RETURN(E_OK); + } + + assert(form->current && + form->current->buf && + (form->current->form == form) + ); + + if (form->status & _IN_DRIVER) + RETURN(E_BAD_STATE); + + if (!(form->status & _POSTED)) + RETURN(E_NOT_POSTED); + + /* check if this is a keycode or a (wide) char */ + if (type == KEY_CODE_YES) + { + if ((c >= MIN_FORM_COMMAND && c <= MAX_FORM_COMMAND) && + ((bindings[c - MIN_FORM_COMMAND].keycode & Key_Mask) == c)) + BI = &(bindings[c - MIN_FORM_COMMAND]); + } + + if (BI) + { + typedef int (*Generic_Method) (int (*const) (FORM *), FORM *); + static const Generic_Method Generic_Methods[] = + { + Page_Navigation, /* overloaded to call field&form hooks */ + Inter_Field_Navigation, /* overloaded to call field hooks */ + NULL, /* Intra-Field is generic */ + Vertical_Scrolling, /* Overloaded to check multi-line */ + Horizontal_Scrolling, /* Overloaded to check single-line */ + Field_Editing, /* Overloaded to mark modification */ + NULL, /* Edit Mode is generic */ + NULL, /* Field Validation is generic */ + NULL /* Choice Request is generic */ + }; + size_t nMethods = (sizeof(Generic_Methods) / sizeof(Generic_Methods[0])); + size_t method = (size_t) (BI->keycode >> ID_Shft) & 0xffff; /* see ID_Mask */ + + if ((method >= nMethods) || !(BI->cmd)) + res = E_SYSTEM_ERROR; + else + { + Generic_Method fct = Generic_Methods[method]; + + if (fct) + res = fct(BI->cmd, form); + else + res = (BI->cmd) (form); + } + } +#ifdef NCURSES_MOUSE_VERSION + else if (KEY_MOUSE == c) + { + MEVENT event; + WINDOW *win = form->win ? form->win : StdScreen(Get_Form_Screen(form)); + WINDOW *sub = form->sub ? form->sub : win; + + getmouse(&event); + if ((event.bstate & (BUTTON1_CLICKED | + BUTTON1_DOUBLE_CLICKED | + BUTTON1_TRIPLE_CLICKED)) + && wenclose(win, event.y, event.x)) + { /* we react only if the click was in the userwin, that means + * inside the form display area or at the decoration window. + */ + int ry = event.y, rx = event.x; /* screen coordinates */ + + res = E_REQUEST_DENIED; + if (mouse_trafo(&ry, &rx, FALSE)) + { /* rx, ry are now "curses" coordinates */ + if (ry < sub->_begy) + { /* we clicked above the display region; this is + * interpreted as "scroll up" request + */ + if (event.bstate & BUTTON1_CLICKED) + res = form_driver(form, REQ_PREV_FIELD); + else if (event.bstate & BUTTON1_DOUBLE_CLICKED) + res = form_driver(form, REQ_PREV_PAGE); + else if (event.bstate & BUTTON1_TRIPLE_CLICKED) + res = form_driver(form, REQ_FIRST_FIELD); + } + else if (ry > sub->_begy + sub->_maxy) + { /* we clicked below the display region; this is + * interpreted as "scroll down" request + */ + if (event.bstate & BUTTON1_CLICKED) + res = form_driver(form, REQ_NEXT_FIELD); + else if (event.bstate & BUTTON1_DOUBLE_CLICKED) + res = form_driver(form, REQ_NEXT_PAGE); + else if (event.bstate & BUTTON1_TRIPLE_CLICKED) + res = form_driver(form, REQ_LAST_FIELD); + } + else if (wenclose(sub, event.y, event.x)) + { /* Inside the area we try to find the hit item */ + int i; + + ry = event.y; + rx = event.x; + if (wmouse_trafo(sub, &ry, &rx, FALSE)) + { + int min_field = form->page[form->curpage].pmin; + int max_field = form->page[form->curpage].pmax; + + for (i = min_field; i <= max_field; ++i) + { + FIELD *field = form->field[i]; + + if (Field_Is_Selectable(field) + && Field_encloses(field, ry, rx) == E_OK) + { + res = _nc_Set_Current_Field(form, field); + if (res == E_OK) + res = _nc_Position_Form_Cursor(form); + if (res == E_OK + && (event.bstate & BUTTON1_DOUBLE_CLICKED)) + res = E_UNKNOWN_COMMAND; + break; + } + } + } + } + } + } + else + res = E_REQUEST_DENIED; + } +#endif /* NCURSES_MOUSE_VERSION */ + else if (type == OK) + { + res = Data_Entry_w(form, c); + } + + _nc_Refresh_Current_Field(form); + RETURN(res); +} +# endif /* USE_WIDEC_SUPPORT */ + /*---------------------------------------------------------------------------- Field-Buffer manipulation routines. The effects of setting a buffer are tightly coupled to the core of the form diff --git a/package/debian-mingw/changelog b/package/debian-mingw/changelog index c3a616e5..d9a808db 100644 --- a/package/debian-mingw/changelog +++ b/package/debian-mingw/changelog @@ -1,8 +1,8 @@ -ncurses6 (5.9-20131123) unstable; urgency=low +ncurses6 (5.9-20131207) unstable; urgency=low * latest weekly patch - -- Thomas E. Dickey Sat, 23 Nov 2013 13:02:48 -0500 + -- Thomas E. Dickey Sat, 07 Dec 2013 10:21:58 -0500 ncurses6 (5.9-20131005) unstable; urgency=low diff --git a/package/debian-mingw64/changelog b/package/debian-mingw64/changelog index c3a616e5..d9a808db 100644 --- a/package/debian-mingw64/changelog +++ b/package/debian-mingw64/changelog @@ -1,8 +1,8 @@ -ncurses6 (5.9-20131123) unstable; urgency=low +ncurses6 (5.9-20131207) unstable; urgency=low * latest weekly patch - -- Thomas E. Dickey Sat, 23 Nov 2013 13:02:48 -0500 + -- Thomas E. Dickey Sat, 07 Dec 2013 10:21:58 -0500 ncurses6 (5.9-20131005) unstable; urgency=low diff --git a/package/debian/changelog b/package/debian/changelog index e48f4c04..d35fd446 100644 --- a/package/debian/changelog +++ b/package/debian/changelog @@ -1,8 +1,8 @@ -ncurses6 (5.9-20131123) unstable; urgency=low +ncurses6 (5.9-20131207) unstable; urgency=low * latest weekly patch - -- Thomas E. Dickey Sat, 23 Nov 2013 13:02:48 -0500 + -- Thomas E. Dickey Sat, 07 Dec 2013 10:21:58 -0500 ncurses6 (5.9-20120608) unstable; urgency=low diff --git a/package/mingw-ncurses.nsi b/package/mingw-ncurses.nsi index 645beefc..779d4bc8 100644 --- a/package/mingw-ncurses.nsi +++ b/package/mingw-ncurses.nsi @@ -1,4 +1,4 @@ -; $Id: mingw-ncurses.nsi,v 1.16 2013/11/23 18:02:48 tom Exp $ +; $Id: mingw-ncurses.nsi,v 1.17 2013/12/07 15:21:58 tom Exp $ ; TODO add examples ; TODO bump ABI to 6 @@ -10,7 +10,7 @@ !define VERSION_MAJOR "5" !define VERSION_MINOR "9" !define VERSION_YYYY "2013" -!define VERSION_MMDD "1123" +!define VERSION_MMDD "1207" !define VERSION_PATCH ${VERSION_YYYY}${VERSION_MMDD} !define MY_ABI "5" diff --git a/package/mingw-ncurses.spec b/package/mingw-ncurses.spec index 2931163c..14eb56d5 100644 --- a/package/mingw-ncurses.spec +++ b/package/mingw-ncurses.spec @@ -3,7 +3,7 @@ Summary: shared libraries for terminal handling Name: mingw32-ncurses6 Version: 5.9 -Release: 20131123 +Release: 20131207 License: X11 Group: Development/Libraries Source: ncurses-%{version}-%{release}.tgz diff --git a/package/ncurses.spec b/package/ncurses.spec index cbb61964..2b4c4180 100644 --- a/package/ncurses.spec +++ b/package/ncurses.spec @@ -1,7 +1,7 @@ Summary: shared libraries for terminal handling Name: ncurses6 Version: 5.9 -Release: 20131123 +Release: 20131207 License: X11 Group: Development/Libraries Source: ncurses-%{version}-%{release}.tgz diff --git a/test/form_driver_w.c b/test/form_driver_w.c new file mode 100644 index 00000000..276209f4 --- /dev/null +++ b/test/form_driver_w.c @@ -0,0 +1,155 @@ +/**************************************************************************** + * Copyright (c) 2013 Free Software Foundation, Inc. * + * * + * 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, distribute with modifications, 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 ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Gaute Hope, 2013 * + ****************************************************************************/ + +/* + * $Id: form_driver_w.c,v 1.9 2013/12/07 20:35:54 tom Exp $ + * + * Test form_driver_w (int, int, wchar_t), a wide char aware + * replacement of form_driver. + */ + +#include + +#include + +#if USE_WIDEC_SUPPORT && USE_LIBFORM + +#include + +int +main(void) +{ + FIELD *field[3]; + FORM *my_form; + bool done = FALSE; + + setlocale(LC_ALL, ""); + + /* Initialize curses */ + initscr(); + cbreak(); + noecho(); + keypad(stdscr, TRUE); + + /* Initialize the fields */ + field[0] = new_field(1, 10, 4, 18, 0, 0); + field[1] = new_field(1, 10, 6, 18, 0, 0); + field[2] = NULL; + + /* Set field options */ + set_field_back(field[0], A_UNDERLINE); /* Print a line for the option */ + field_opts_off(field[0], O_AUTOSKIP); /* Don't go to next field when this */ + /* Field is filled up */ + set_field_back(field[1], A_UNDERLINE); + field_opts_off(field[1], O_AUTOSKIP); + + /* Create the form and post it */ + my_form = new_form(field); + post_form(my_form); + refresh(); + + mvprintw(4, 10, "Value 1:"); + mvprintw(6, 10, "Value 2:"); + refresh(); + + /* Loop through to get user requests */ + while (!done) { + wint_t ch; + int ret = get_wch(&ch); + + mvprintw(8, 10, "Got %d (%#x), type: %s", ch, ch, + (ret == KEY_CODE_YES) + ? "KEY_CODE_YES" + : ((ret == OK) + ? "OK" + : ((ret == ERR) + ? "ERR" + : "?"))); + clrtoeol(); + + switch (ret) { + case KEY_CODE_YES: + switch (ch) { + case KEY_DOWN: + /* Go to next field */ + form_driver(my_form, REQ_NEXT_FIELD); + /* Go to the end of the present buffer */ + /* Leaves nicely at the last character */ + form_driver(my_form, REQ_END_LINE); + break; + case KEY_UP: + /* Go to previous field */ + form_driver(my_form, REQ_PREV_FIELD); + form_driver(my_form, REQ_END_LINE); + break; + default: +#if 0 + /* If this is a normal character, it gets printed */ + form_driver(my_form, ch); + wadd_wch(my_form->current->working, ch); +#endif + break; + } + break; + case OK: + switch (ch) { + case CTRL('D'): + case QUIT: + case ESCAPE: + done = TRUE; + break; + default: + form_driver_w(my_form, OK, ch); + break; + } + break; + } + } + + /* Un post form and free the memory */ + unpost_form(my_form); + free_form(my_form); + free_field(field[0]); + free_field(field[1]); + + endwin(); + ExitProgram(EXIT_SUCCESS); +} + +#else +int +main(void) +{ + printf("This program requires the wide-ncurses and forms library\n"); + ExitProgram(EXIT_FAILURE); +} +#endif /* USE_WIDEC_SUPPORT */ diff --git a/test/modules b/test/modules index 63e9636f..628335a9 100644 --- a/test/modules +++ b/test/modules @@ -1,4 +1,4 @@ -# $Id: modules,v 1.48 2013/06/08 16:34:15 tom Exp $ +# $Id: modules,v 1.50 2013/12/07 18:06:01 tom Exp $ ############################################################################## # Copyright (c) 1998-2012,2013 Free Software Foundation, Inc. # # # @@ -57,6 +57,7 @@ filter progs $(srcdir) $(HEADER_DEPS) firework progs $(srcdir) $(HEADER_DEPS) firstlast progs $(srcdir) $(HEADER_DEPS) foldkeys progs $(srcdir) $(HEADER_DEPS) +form_driver_w progs $(srcdir) $(HEADER_DEPS) gdc progs $(srcdir) $(HEADER_DEPS) hanoi progs $(srcdir) $(HEADER_DEPS) hashtest progs $(srcdir) $(HEADER_DEPS) diff --git a/test/programs b/test/programs index 759541b1..f307cc72 100644 --- a/test/programs +++ b/test/programs @@ -1,4 +1,4 @@ -# $Id: programs,v 1.22 2013/06/08 16:34:31 tom Exp $ +# $Id: programs,v 1.24 2013/12/07 18:06:24 tom Exp $ ############################################################################## # Copyright (c) 2006-2009,2013 Free Software Foundation, Inc. # # # @@ -54,6 +54,7 @@ filter $(LDFLAGS_CURSES) $(LOCAL_LIBS) filter firework $(LDFLAGS_CURSES) $(LOCAL_LIBS) firework firstlast $(LDFLAGS_DEFAULT) $(LOCAL_LIBS) firstlast foldkeys $(LDFLAGS_CURSES) $(LOCAL_LIBS) foldkeys +form_driver_w $(LDFLAGS_DEFAULT) $(LOCAL_LIBS) form_driver_w gdc $(LDFLAGS_CURSES) $(LOCAL_LIBS) gdc hanoi $(LDFLAGS_CURSES) $(LOCAL_LIBS) hanoi hashtest $(LDFLAGS_CURSES) $(LOCAL_LIBS) hashtest