lib_get_wch.c revision 97049
1/****************************************************************************
2 * Copyright (c) 2002 Free Software Foundation, Inc.                        *
3 *                                                                          *
4 * Permission is hereby granted, free of charge, to any person obtaining a  *
5 * copy of this software and associated documentation files (the            *
6 * "Software"), to deal in the Software without restriction, including      *
7 * without limitation the rights to use, copy, modify, merge, publish,      *
8 * distribute, distribute with modifications, sublicense, and/or sell       *
9 * copies of the Software, and to permit persons to whom the Software is    *
10 * furnished to do so, subject to the following conditions:                 *
11 *                                                                          *
12 * The above copyright notice and this permission notice shall be included  *
13 * in all copies or substantial portions of the Software.                   *
14 *                                                                          *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
22 *                                                                          *
23 * Except as contained in this notice, the name(s) of the above copyright   *
24 * holders shall not be used in advertising or otherwise to promote the     *
25 * sale, use or other dealings in this Software without prior written       *
26 * authorization.                                                           *
27 ****************************************************************************/
28
29/****************************************************************************
30 *  Author: Thomas E. Dickey 2002                                           *
31 ****************************************************************************/
32
33/*
34**	lib_get_wch.c
35**
36**	The routine get_wch().
37**
38*/
39
40#include <curses.priv.h>
41
42MODULE_ID("$Id: lib_get_wch.c,v 1.3 2002/03/17 16:14:45 tom Exp $")
43
44NCURSES_EXPORT(int)
45wget_wch(WINDOW *win, wint_t * result)
46{
47    int code;
48    char buffer[(MB_CUR_MAX * 9) + 1];	/* allow some redundant shifts */
49    int status;
50    mbstate_t state;
51    size_t count = 0;
52    unsigned long value;
53    wchar_t wch;
54
55    T((T_CALLED("wget_wch(%p)"), win));
56    /*
57     * We can get a stream of single-byte characters and KEY_xxx codes from
58     * _nc_wgetch(), while we want to return a wide character or KEY_xxx code.
59     */
60    for (;;) {
61	    T(("reading %d of %d", count + 1, sizeof(buffer)));
62	code = _nc_wgetch(win, &value, TRUE);
63	if (code == ERR) {
64	    break;
65	} else if (code == KEY_CODE_YES) {
66	    /*
67	     * If we were processing an incomplete multibyte character, return
68	     * an error since we have a KEY_xxx code which interrupts it.  For
69	     * some cases, we could improve this by writing a new version of
70	     * lib_getch.c(!), but it is not clear whether the improvement
71	     * would be worth the effort.
72	     */
73	    if (count != 0) {
74		ungetch(value);
75		code = ERR;
76	    }
77	    break;
78	} else if (count + 1 >= sizeof(buffer)) {
79	    ungetch(value);
80	    code = ERR;
81	    break;
82	} else {
83	    buffer[count++] = UChar(value);
84	    memset(&state, 0, sizeof(state));
85	    status = mbrlen(buffer, count, &state);
86	    if (status >= 0) {
87		memset(&state, 0, sizeof(state));
88		if ((int) mbrtowc(&wch, buffer, count, &state) != status) {
89		    code = ERR;	/* the two calls should match */
90		}
91		value = wch;
92		break;
93	    }
94	}
95    }
96    *result = value;
97    T(("result %#o", value));
98    returnCode(code);
99}
100