diff options
Diffstat (limited to 'scripts/kconfig/libcurses/getch.c')
-rw-r--r-- | scripts/kconfig/libcurses/getch.c | 589 |
1 files changed, 589 insertions, 0 deletions
diff --git a/scripts/kconfig/libcurses/getch.c b/scripts/kconfig/libcurses/getch.c new file mode 100644 index 000000000..8719ca39c --- /dev/null +++ b/scripts/kconfig/libcurses/getch.c | |||
@@ -0,0 +1,589 @@ | |||
1 | /* PDCurses */ | ||
2 | |||
3 | #include "curspriv.h" | ||
4 | |||
5 | /*man-start************************************************************** | ||
6 | |||
7 | getch | ||
8 | ----- | ||
9 | |||
10 | ### Synopsis | ||
11 | |||
12 | int getch(void); | ||
13 | int wgetch(WINDOW *win); | ||
14 | int mvgetch(int y, int x); | ||
15 | int mvwgetch(WINDOW *win, int y, int x); | ||
16 | int ungetch(int ch); | ||
17 | int flushinp(void); | ||
18 | |||
19 | int get_wch(wint_t *wch); | ||
20 | int wget_wch(WINDOW *win, wint_t *wch); | ||
21 | int mvget_wch(int y, int x, wint_t *wch); | ||
22 | int mvwget_wch(WINDOW *win, int y, int x, wint_t *wch); | ||
23 | int unget_wch(const wchar_t wch); | ||
24 | |||
25 | unsigned long PDC_get_key_modifiers(void); | ||
26 | int PDC_return_key_modifiers(bool flag); | ||
27 | |||
28 | ### Description | ||
29 | |||
30 | With the getch(), wgetch(), mvgetch(), and mvwgetch() functions, a | ||
31 | character is read from the terminal associated with the window. In | ||
32 | nodelay mode, if there is no input waiting, the value ERR is | ||
33 | returned. In delay mode, the program will hang until the system | ||
34 | passes text through to the program. Depending on the setting of | ||
35 | cbreak(), this will be after one character or after the first | ||
36 | newline. Unless noecho() has been set, the character will also be | ||
37 | echoed into the designated window. | ||
38 | |||
39 | If keypad() is TRUE, and a function key is pressed, the token for | ||
40 | that function key will be returned instead of the raw characters. | ||
41 | Possible function keys are defined in "curses.h" with integers | ||
42 | beginning with 0401, whose names begin with KEY_. | ||
43 | |||
44 | If nodelay(win, TRUE) has been called on the window and no input is | ||
45 | waiting, the value ERR is returned. | ||
46 | |||
47 | ungetch() places ch back onto the input queue to be returned by the | ||
48 | next call to wgetch(). | ||
49 | |||
50 | flushinp() throws away any type-ahead that has been typed by the user | ||
51 | and has not yet been read by the program. | ||
52 | |||
53 | wget_wch() is the wide-character version of wgetch(), available when | ||
54 | PDCurses is built with the PDC_WIDE option. It takes a pointer to a | ||
55 | wint_t rather than returning the key as an int, and instead returns | ||
56 | KEY_CODE_YES if the key is a function key. Otherwise, it returns OK | ||
57 | or ERR. It's important to check for KEY_CODE_YES, since regular wide | ||
58 | characters can have the same values as function key codes. | ||
59 | |||
60 | unget_wch() puts a wide character on the input queue. | ||
61 | |||
62 | PDC_get_key_modifiers() returns the keyboard modifiers (shift, | ||
63 | control, alt, numlock) effective at the time of the last getch() | ||
64 | call. Use the macros PDC_KEY_MODIFIER_* to determine which | ||
65 | modifier(s) were set. PDC_return_key_modifiers() tells getch() to | ||
66 | return modifier keys pressed alone as keystrokes (KEY_ALT_L, etc.). | ||
67 | These may not work on all platforms. | ||
68 | |||
69 | NOTE: getch() and ungetch() are implemented as macros, to avoid | ||
70 | conflict with many DOS compiler's runtime libraries. | ||
71 | |||
72 | ### Return Value | ||
73 | |||
74 | These functions return ERR or the value of the character, meta | ||
75 | character or function key token. | ||
76 | |||
77 | ### Portability | ||
78 | X/Open ncurses NetBSD | ||
79 | getch Y Y Y | ||
80 | wgetch Y Y Y | ||
81 | mvgetch Y Y Y | ||
82 | mvwgetch Y Y Y | ||
83 | ungetch Y Y Y | ||
84 | flushinp Y Y Y | ||
85 | get_wch Y Y Y | ||
86 | wget_wch Y Y Y | ||
87 | mvget_wch Y Y Y | ||
88 | mvwget_wch Y Y Y | ||
89 | unget_wch Y Y Y | ||
90 | PDC_get_key_modifiers - - - | ||
91 | |||
92 | **man-end****************************************************************/ | ||
93 | |||
94 | #include <stdlib.h> | ||
95 | |||
96 | static int _get_box(int *y_start, int *y_end, int *x_start, int *x_end) | ||
97 | { | ||
98 | int start, end; | ||
99 | |||
100 | if (SP->sel_start < SP->sel_end) | ||
101 | { | ||
102 | start = SP->sel_start; | ||
103 | end = SP->sel_end; | ||
104 | } | ||
105 | else | ||
106 | { | ||
107 | start = SP->sel_end; | ||
108 | end = SP->sel_start; | ||
109 | } | ||
110 | |||
111 | *y_start = start / COLS; | ||
112 | *x_start = start % COLS; | ||
113 | |||
114 | *y_end = end / COLS; | ||
115 | *x_end = end % COLS; | ||
116 | |||
117 | return (end - start) + (*y_end - *y_start); | ||
118 | } | ||
119 | |||
120 | static void _highlight(void) | ||
121 | { | ||
122 | int i, j, y_start, y_end, x_start, x_end; | ||
123 | |||
124 | if (-1 == SP->sel_start) | ||
125 | return; | ||
126 | |||
127 | _get_box(&y_start, &y_end, &x_start, &x_end); | ||
128 | |||
129 | for (j = y_start; j <= y_end; j++) | ||
130 | for (i = (j == y_start ? x_start : 0); | ||
131 | i < (j == y_end ? x_end : COLS); i++) | ||
132 | curscr->_y[j][i] ^= A_REVERSE; | ||
133 | |||
134 | wrefresh(curscr); | ||
135 | } | ||
136 | |||
137 | static void _copy(void) | ||
138 | { | ||
139 | #ifdef PDC_WIDE | ||
140 | wchar_t *wtmp; | ||
141 | # define TMP wtmp | ||
142 | # define MASK A_CHARTEXT | ||
143 | #else | ||
144 | # define TMP tmp | ||
145 | # define MASK 0xff | ||
146 | #endif | ||
147 | char *tmp; | ||
148 | long pos; | ||
149 | int i, j, y_start, y_end, x_start, x_end, len; | ||
150 | |||
151 | if (-1 == SP->sel_start) | ||
152 | return; | ||
153 | |||
154 | len = _get_box(&y_start, &y_end, &x_start, &x_end); | ||
155 | |||
156 | if (!len) | ||
157 | return; | ||
158 | |||
159 | #ifdef PDC_WIDE | ||
160 | wtmp = malloc((len + 1) * sizeof(wchar_t)); | ||
161 | len *= 4; | ||
162 | #endif | ||
163 | tmp = malloc(len + 1); | ||
164 | |||
165 | for (j = y_start, pos = 0; j <= y_end; j++) | ||
166 | { | ||
167 | for (i = (j == y_start ? x_start : 0); | ||
168 | i < (j == y_end ? x_end : COLS); i++) | ||
169 | TMP[pos++] = curscr->_y[j][i] & MASK; | ||
170 | |||
171 | while (y_start != y_end && pos > 0 && TMP[pos - 1] == 32) | ||
172 | pos--; | ||
173 | |||
174 | if (j < y_end) | ||
175 | TMP[pos++] = 10; | ||
176 | } | ||
177 | TMP[pos] = 0; | ||
178 | |||
179 | #ifdef PDC_WIDE | ||
180 | pos = PDC_wcstombs(tmp, wtmp, len); | ||
181 | #endif | ||
182 | |||
183 | PDC_setclipboard(tmp, pos); | ||
184 | free(tmp); | ||
185 | #ifdef PDC_WIDE | ||
186 | free(wtmp); | ||
187 | #endif | ||
188 | } | ||
189 | |||
190 | static int _paste(void) | ||
191 | { | ||
192 | #ifdef PDC_WIDE | ||
193 | wchar_t *wpaste; | ||
194 | # define PASTE wpaste | ||
195 | #else | ||
196 | # define PASTE paste | ||
197 | #endif | ||
198 | char *paste; | ||
199 | long len, newmax; | ||
200 | int key; | ||
201 | |||
202 | key = PDC_getclipboard(&paste, &len); | ||
203 | if (PDC_CLIP_SUCCESS != key || !len) | ||
204 | return -1; | ||
205 | |||
206 | #ifdef PDC_WIDE | ||
207 | wpaste = malloc(len * sizeof(wchar_t)); | ||
208 | len = PDC_mbstowcs(wpaste, paste, len); | ||
209 | #endif | ||
210 | newmax = len + SP->c_ungind; | ||
211 | if (newmax > SP->c_ungmax) | ||
212 | { | ||
213 | SP->c_ungch = realloc(SP->c_ungch, newmax * sizeof(int)); | ||
214 | if (!SP->c_ungch) | ||
215 | return -1; | ||
216 | SP->c_ungmax = newmax; | ||
217 | } | ||
218 | while (len > 1) | ||
219 | PDC_ungetch(PASTE[--len]); | ||
220 | key = *PASTE; | ||
221 | #ifdef PDC_WIDE | ||
222 | free(wpaste); | ||
223 | #endif | ||
224 | PDC_freeclipboard(paste); | ||
225 | SP->key_modifiers = 0; | ||
226 | |||
227 | return key; | ||
228 | } | ||
229 | |||
230 | static int _mouse_key(void) | ||
231 | { | ||
232 | int i, key = KEY_MOUSE, changes = SP->mouse_status.changes; | ||
233 | unsigned long mbe = SP->_trap_mbe; | ||
234 | |||
235 | /* Selection highlighting? */ | ||
236 | |||
237 | if ((!mbe || SP->mouse_status.button[0] & BUTTON_SHIFT) && changes & 1) | ||
238 | { | ||
239 | i = SP->mouse_status.y * COLS + SP->mouse_status.x; | ||
240 | switch (SP->mouse_status.button[0] & BUTTON_ACTION_MASK) | ||
241 | { | ||
242 | case BUTTON_PRESSED: | ||
243 | _highlight(); | ||
244 | SP->sel_start = SP->sel_end = i; | ||
245 | return -1; | ||
246 | case BUTTON_MOVED: | ||
247 | _highlight(); | ||
248 | SP->sel_end = i; | ||
249 | _highlight(); | ||
250 | return -1; | ||
251 | case BUTTON_RELEASED: | ||
252 | _copy(); | ||
253 | return -1; | ||
254 | } | ||
255 | } | ||
256 | else if ((!mbe || SP->mouse_status.button[1] & BUTTON_SHIFT) && | ||
257 | changes & 2 && (SP->mouse_status.button[1] & | ||
258 | BUTTON_ACTION_MASK) == BUTTON_CLICKED) | ||
259 | { | ||
260 | SP->key_code = FALSE; | ||
261 | return _paste(); | ||
262 | } | ||
263 | |||
264 | /* Filter unwanted mouse events */ | ||
265 | |||
266 | for (i = 0; i < 3; i++) | ||
267 | { | ||
268 | if (changes & (1 << i)) | ||
269 | { | ||
270 | int shf = i * 5; | ||
271 | short button = SP->mouse_status.button[i] & BUTTON_ACTION_MASK; | ||
272 | |||
273 | if ( (!(mbe & (BUTTON1_PRESSED << shf)) && | ||
274 | (button == BUTTON_PRESSED)) | ||
275 | |||
276 | || (!(mbe & (BUTTON1_CLICKED << shf)) && | ||
277 | (button == BUTTON_CLICKED)) | ||
278 | |||
279 | || (!(mbe & (BUTTON1_DOUBLE_CLICKED << shf)) && | ||
280 | (button == BUTTON_DOUBLE_CLICKED)) | ||
281 | |||
282 | || (!(mbe & (BUTTON1_MOVED << shf)) && | ||
283 | (button == BUTTON_MOVED)) | ||
284 | |||
285 | || (!(mbe & (BUTTON1_RELEASED << shf)) && | ||
286 | (button == BUTTON_RELEASED)) | ||
287 | ) | ||
288 | SP->mouse_status.changes ^= (1 << i); | ||
289 | } | ||
290 | } | ||
291 | |||
292 | if (changes & PDC_MOUSE_MOVED) | ||
293 | { | ||
294 | if (!(mbe & (BUTTON1_MOVED|BUTTON2_MOVED|BUTTON3_MOVED))) | ||
295 | SP->mouse_status.changes ^= PDC_MOUSE_MOVED; | ||
296 | } | ||
297 | |||
298 | if (changes & (PDC_MOUSE_WHEEL_UP|PDC_MOUSE_WHEEL_DOWN)) | ||
299 | { | ||
300 | if (!(mbe & MOUSE_WHEEL_SCROLL)) | ||
301 | SP->mouse_status.changes &= | ||
302 | ~(PDC_MOUSE_WHEEL_UP|PDC_MOUSE_WHEEL_DOWN); | ||
303 | } | ||
304 | |||
305 | if (!changes) | ||
306 | return -1; | ||
307 | |||
308 | /* Check for click in slk area */ | ||
309 | |||
310 | i = PDC_mouse_in_slk(SP->mouse_status.y, SP->mouse_status.x); | ||
311 | |||
312 | if (i) | ||
313 | { | ||
314 | if (SP->mouse_status.button[0] & (BUTTON_PRESSED|BUTTON_CLICKED)) | ||
315 | key = KEY_F(i); | ||
316 | else | ||
317 | key = -1; | ||
318 | } | ||
319 | |||
320 | return key; | ||
321 | } | ||
322 | |||
323 | int wgetch(WINDOW *win) | ||
324 | { | ||
325 | int key, waitcount; | ||
326 | |||
327 | PDC_LOG(("wgetch() - called\n")); | ||
328 | |||
329 | if (!win || !SP) | ||
330 | return ERR; | ||
331 | |||
332 | waitcount = 0; | ||
333 | |||
334 | /* set the number of 1/20th second napms() calls */ | ||
335 | |||
336 | if (SP->delaytenths) | ||
337 | waitcount = 2 * SP->delaytenths; | ||
338 | else | ||
339 | if (win->_delayms) | ||
340 | { | ||
341 | /* Can't really do millisecond intervals, so delay in | ||
342 | 1/20ths of a second (50ms) */ | ||
343 | |||
344 | waitcount = win->_delayms / 50; | ||
345 | if (!waitcount) | ||
346 | waitcount = 1; | ||
347 | } | ||
348 | |||
349 | /* refresh window when wgetch is called if there have been changes | ||
350 | to it and it is not a pad */ | ||
351 | |||
352 | if (!(win->_flags & _PAD) && ((!win->_leaveit && | ||
353 | (win->_begx + win->_curx != SP->curscol || | ||
354 | win->_begy + win->_cury != SP->cursrow)) || is_wintouched(win))) | ||
355 | wrefresh(win); | ||
356 | |||
357 | /* if ungotten char exists, remove and return it */ | ||
358 | |||
359 | if (SP->c_ungind) | ||
360 | return SP->c_ungch[--(SP->c_ungind)]; | ||
361 | |||
362 | /* if normal and data in buffer */ | ||
363 | |||
364 | if ((!SP->raw_inp && !SP->cbreak) && (SP->c_gindex < SP->c_pindex)) | ||
365 | return SP->c_buffer[SP->c_gindex++]; | ||
366 | |||
367 | /* prepare to buffer data */ | ||
368 | |||
369 | SP->c_pindex = 0; | ||
370 | SP->c_gindex = 0; | ||
371 | |||
372 | /* to get here, no keys are buffered. go and get one. */ | ||
373 | |||
374 | for (;;) /* loop for any buffering */ | ||
375 | { | ||
376 | /* is there a keystroke ready? */ | ||
377 | |||
378 | if (!PDC_check_key()) | ||
379 | { | ||
380 | /* if not, handle timeout() and halfdelay() */ | ||
381 | |||
382 | if (SP->delaytenths || win->_delayms) | ||
383 | { | ||
384 | if (!waitcount) | ||
385 | return ERR; | ||
386 | |||
387 | waitcount--; | ||
388 | } | ||
389 | else | ||
390 | if (win->_nodelay) | ||
391 | return ERR; | ||
392 | |||
393 | napms(50); /* sleep for 1/20th second */ | ||
394 | continue; /* then check again */ | ||
395 | } | ||
396 | |||
397 | /* if there is, fetch it */ | ||
398 | |||
399 | key = PDC_get_key(); | ||
400 | |||
401 | /* copy or paste? */ | ||
402 | |||
403 | if (SP->key_modifiers & PDC_KEY_MODIFIER_SHIFT) | ||
404 | { | ||
405 | if (0x03 == key) | ||
406 | { | ||
407 | _copy(); | ||
408 | continue; | ||
409 | } | ||
410 | else if (0x16 == key) | ||
411 | key = _paste(); | ||
412 | } | ||
413 | |||
414 | /* filter mouse events; translate mouse clicks in the slk | ||
415 | area to function keys */ | ||
416 | |||
417 | if (SP->key_code && key == KEY_MOUSE) | ||
418 | key = _mouse_key(); | ||
419 | |||
420 | /* filter special keys if not in keypad mode */ | ||
421 | |||
422 | if (SP->key_code && !win->_use_keypad) | ||
423 | key = -1; | ||
424 | |||
425 | /* unwanted key? loop back */ | ||
426 | |||
427 | if (key == -1) | ||
428 | continue; | ||
429 | |||
430 | _highlight(); | ||
431 | SP->sel_start = SP->sel_end = -1; | ||
432 | |||
433 | /* translate CR */ | ||
434 | |||
435 | if (key == '\r' && SP->autocr && !SP->raw_inp) | ||
436 | key = '\n'; | ||
437 | |||
438 | /* if echo is enabled */ | ||
439 | |||
440 | if (SP->echo && !SP->key_code) | ||
441 | { | ||
442 | waddch(win, key); | ||
443 | wrefresh(win); | ||
444 | } | ||
445 | |||
446 | /* if no buffering */ | ||
447 | |||
448 | if (SP->raw_inp || SP->cbreak) | ||
449 | return key; | ||
450 | |||
451 | /* if no overflow, put data in buffer */ | ||
452 | |||
453 | if (key == '\b') | ||
454 | { | ||
455 | if (SP->c_pindex > SP->c_gindex) | ||
456 | SP->c_pindex--; | ||
457 | } | ||
458 | else | ||
459 | if (SP->c_pindex < _INBUFSIZ - 2) | ||
460 | SP->c_buffer[SP->c_pindex++] = key; | ||
461 | |||
462 | /* if we got a line */ | ||
463 | |||
464 | if (key == '\n' || key == '\r') | ||
465 | return SP->c_buffer[SP->c_gindex++]; | ||
466 | } | ||
467 | } | ||
468 | |||
469 | int mvgetch(int y, int x) | ||
470 | { | ||
471 | PDC_LOG(("mvgetch() - called\n")); | ||
472 | |||
473 | if (move(y, x) == ERR) | ||
474 | return ERR; | ||
475 | |||
476 | return wgetch(stdscr); | ||
477 | } | ||
478 | |||
479 | int mvwgetch(WINDOW *win, int y, int x) | ||
480 | { | ||
481 | PDC_LOG(("mvwgetch() - called\n")); | ||
482 | |||
483 | if (wmove(win, y, x) == ERR) | ||
484 | return ERR; | ||
485 | |||
486 | return wgetch(win); | ||
487 | } | ||
488 | |||
489 | int PDC_ungetch(int ch) | ||
490 | { | ||
491 | PDC_LOG(("ungetch() - called\n")); | ||
492 | |||
493 | if (SP->c_ungind >= SP->c_ungmax) /* pushback stack full */ | ||
494 | return ERR; | ||
495 | |||
496 | SP->c_ungch[SP->c_ungind++] = ch; | ||
497 | |||
498 | return OK; | ||
499 | } | ||
500 | |||
501 | int flushinp(void) | ||
502 | { | ||
503 | PDC_LOG(("flushinp() - called\n")); | ||
504 | |||
505 | if (!SP) | ||
506 | return ERR; | ||
507 | |||
508 | PDC_flushinp(); | ||
509 | |||
510 | SP->c_gindex = 1; /* set indices to kill buffer */ | ||
511 | SP->c_pindex = 0; | ||
512 | SP->c_ungind = 0; /* clear SP->c_ungch array */ | ||
513 | |||
514 | return OK; | ||
515 | } | ||
516 | |||
517 | unsigned long PDC_get_key_modifiers(void) | ||
518 | { | ||
519 | PDC_LOG(("PDC_get_key_modifiers() - called\n")); | ||
520 | |||
521 | if (!SP) | ||
522 | return ERR; | ||
523 | |||
524 | return SP->key_modifiers; | ||
525 | } | ||
526 | |||
527 | int PDC_return_key_modifiers(bool flag) | ||
528 | { | ||
529 | PDC_LOG(("PDC_return_key_modifiers() - called\n")); | ||
530 | |||
531 | if (!SP) | ||
532 | return ERR; | ||
533 | |||
534 | SP->return_key_modifiers = flag; | ||
535 | return PDC_modifiers_set(); | ||
536 | } | ||
537 | |||
538 | #ifdef PDC_WIDE | ||
539 | int wget_wch(WINDOW *win, wint_t *wch) | ||
540 | { | ||
541 | int key; | ||
542 | |||
543 | PDC_LOG(("wget_wch() - called\n")); | ||
544 | |||
545 | if (!wch) | ||
546 | return ERR; | ||
547 | |||
548 | key = wgetch(win); | ||
549 | |||
550 | if (key == ERR) | ||
551 | return ERR; | ||
552 | |||
553 | *wch = key; | ||
554 | |||
555 | return SP->key_code ? KEY_CODE_YES : OK; | ||
556 | } | ||
557 | |||
558 | int get_wch(wint_t *wch) | ||
559 | { | ||
560 | PDC_LOG(("get_wch() - called\n")); | ||
561 | |||
562 | return wget_wch(stdscr, wch); | ||
563 | } | ||
564 | |||
565 | int mvget_wch(int y, int x, wint_t *wch) | ||
566 | { | ||
567 | PDC_LOG(("mvget_wch() - called\n")); | ||
568 | |||
569 | if (move(y, x) == ERR) | ||
570 | return ERR; | ||
571 | |||
572 | return wget_wch(stdscr, wch); | ||
573 | } | ||
574 | |||
575 | int mvwget_wch(WINDOW *win, int y, int x, wint_t *wch) | ||
576 | { | ||
577 | PDC_LOG(("mvwget_wch() - called\n")); | ||
578 | |||
579 | if (wmove(win, y, x) == ERR) | ||
580 | return ERR; | ||
581 | |||
582 | return wget_wch(win, wch); | ||
583 | } | ||
584 | |||
585 | int unget_wch(const wchar_t wch) | ||
586 | { | ||
587 | return PDC_ungetch(wch); | ||
588 | } | ||
589 | #endif | ||