diff options
Diffstat (limited to '')
-rw-r--r-- | scripts/kconfig/libcurses/getch.c | 591 |
1 files changed, 591 insertions, 0 deletions
diff --git a/scripts/kconfig/libcurses/getch.c b/scripts/kconfig/libcurses/getch.c new file mode 100644 index 000000000..9d771ec0e --- /dev/null +++ b/scripts/kconfig/libcurses/getch.c | |||
@@ -0,0 +1,591 @@ | |||
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 | |||
79 | Function | X/Open | ncurses | NetBSD | ||
80 | :---------------------|:------:|:-------:|:------: | ||
81 | getch | Y | Y | Y | ||
82 | wgetch | Y | Y | Y | ||
83 | mvgetch | Y | Y | Y | ||
84 | mvwgetch | Y | Y | Y | ||
85 | ungetch | Y | Y | Y | ||
86 | flushinp | Y | Y | Y | ||
87 | get_wch | Y | Y | Y | ||
88 | wget_wch | Y | Y | Y | ||
89 | mvget_wch | Y | Y | Y | ||
90 | mvwget_wch | Y | Y | Y | ||
91 | unget_wch | Y | Y | Y | ||
92 | PDC_get_key_modifiers | - | - | - | ||
93 | |||
94 | **man-end****************************************************************/ | ||
95 | |||
96 | #include <stdlib.h> | ||
97 | |||
98 | static int _get_box(int *y_start, int *y_end, int *x_start, int *x_end) | ||
99 | { | ||
100 | int start, end; | ||
101 | |||
102 | if (SP->sel_start < SP->sel_end) | ||
103 | { | ||
104 | start = SP->sel_start; | ||
105 | end = SP->sel_end; | ||
106 | } | ||
107 | else | ||
108 | { | ||
109 | start = SP->sel_end; | ||
110 | end = SP->sel_start; | ||
111 | } | ||
112 | |||
113 | *y_start = start / COLS; | ||
114 | *x_start = start % COLS; | ||
115 | |||
116 | *y_end = end / COLS; | ||
117 | *x_end = end % COLS; | ||
118 | |||
119 | return (end - start) + (*y_end - *y_start); | ||
120 | } | ||
121 | |||
122 | static void _highlight(void) | ||
123 | { | ||
124 | int i, j, y_start, y_end, x_start, x_end; | ||
125 | |||
126 | if (-1 == SP->sel_start) | ||
127 | return; | ||
128 | |||
129 | _get_box(&y_start, &y_end, &x_start, &x_end); | ||
130 | |||
131 | for (j = y_start; j <= y_end; j++) | ||
132 | for (i = (j == y_start ? x_start : 0); | ||
133 | i < (j == y_end ? x_end : COLS); i++) | ||
134 | curscr->_y[j][i] ^= A_REVERSE; | ||
135 | |||
136 | wrefresh(curscr); | ||
137 | } | ||
138 | |||
139 | static void _copy(void) | ||
140 | { | ||
141 | #ifdef PDC_WIDE | ||
142 | wchar_t *wtmp; | ||
143 | # define TMP wtmp | ||
144 | # define MASK A_CHARTEXT | ||
145 | #else | ||
146 | # define TMP tmp | ||
147 | # define MASK 0xff | ||
148 | #endif | ||
149 | char *tmp; | ||
150 | long pos; | ||
151 | int i, j, y_start, y_end, x_start, x_end, len; | ||
152 | |||
153 | if (-1 == SP->sel_start) | ||
154 | return; | ||
155 | |||
156 | len = _get_box(&y_start, &y_end, &x_start, &x_end); | ||
157 | |||
158 | if (!len) | ||
159 | return; | ||
160 | |||
161 | #ifdef PDC_WIDE | ||
162 | wtmp = malloc((len + 1) * sizeof(wchar_t)); | ||
163 | len *= 4; | ||
164 | #endif | ||
165 | tmp = malloc(len + 1); | ||
166 | |||
167 | for (j = y_start, pos = 0; j <= y_end; j++) | ||
168 | { | ||
169 | for (i = (j == y_start ? x_start : 0); | ||
170 | i < (j == y_end ? x_end : COLS); i++) | ||
171 | TMP[pos++] = curscr->_y[j][i] & MASK; | ||
172 | |||
173 | while (y_start != y_end && pos > 0 && TMP[pos - 1] == 32) | ||
174 | pos--; | ||
175 | |||
176 | if (j < y_end) | ||
177 | TMP[pos++] = 10; | ||
178 | } | ||
179 | TMP[pos] = 0; | ||
180 | |||
181 | #ifdef PDC_WIDE | ||
182 | pos = PDC_wcstombs(tmp, wtmp, len); | ||
183 | #endif | ||
184 | |||
185 | PDC_setclipboard(tmp, pos); | ||
186 | free(tmp); | ||
187 | #ifdef PDC_WIDE | ||
188 | free(wtmp); | ||
189 | #endif | ||
190 | } | ||
191 | |||
192 | static int _paste(void) | ||
193 | { | ||
194 | #ifdef PDC_WIDE | ||
195 | wchar_t *wpaste; | ||
196 | # define PASTE wpaste | ||
197 | #else | ||
198 | # define PASTE paste | ||
199 | #endif | ||
200 | char *paste; | ||
201 | long len, newmax; | ||
202 | int key; | ||
203 | |||
204 | key = PDC_getclipboard(&paste, &len); | ||
205 | if (PDC_CLIP_SUCCESS != key || !len) | ||
206 | return -1; | ||
207 | |||
208 | #ifdef PDC_WIDE | ||
209 | wpaste = malloc(len * sizeof(wchar_t)); | ||
210 | len = PDC_mbstowcs(wpaste, paste, len); | ||
211 | #endif | ||
212 | newmax = len + SP->c_ungind; | ||
213 | if (newmax > SP->c_ungmax) | ||
214 | { | ||
215 | SP->c_ungch = realloc(SP->c_ungch, newmax * sizeof(int)); | ||
216 | if (!SP->c_ungch) | ||
217 | return -1; | ||
218 | SP->c_ungmax = newmax; | ||
219 | } | ||
220 | while (len > 1) | ||
221 | PDC_ungetch(PASTE[--len]); | ||
222 | key = *PASTE; | ||
223 | #ifdef PDC_WIDE | ||
224 | free(wpaste); | ||
225 | #endif | ||
226 | PDC_freeclipboard(paste); | ||
227 | SP->key_modifiers = 0; | ||
228 | |||
229 | return key; | ||
230 | } | ||
231 | |||
232 | static int _mouse_key(void) | ||
233 | { | ||
234 | int i, key = KEY_MOUSE, changes = SP->mouse_status.changes; | ||
235 | unsigned long mbe = SP->_trap_mbe; | ||
236 | |||
237 | /* Selection highlighting? */ | ||
238 | |||
239 | if ((!mbe || SP->mouse_status.button[0] & BUTTON_SHIFT) && changes & 1) | ||
240 | { | ||
241 | i = SP->mouse_status.y * COLS + SP->mouse_status.x; | ||
242 | switch (SP->mouse_status.button[0] & BUTTON_ACTION_MASK) | ||
243 | { | ||
244 | case BUTTON_PRESSED: | ||
245 | _highlight(); | ||
246 | SP->sel_start = SP->sel_end = i; | ||
247 | return -1; | ||
248 | case BUTTON_MOVED: | ||
249 | _highlight(); | ||
250 | SP->sel_end = i; | ||
251 | _highlight(); | ||
252 | return -1; | ||
253 | case BUTTON_RELEASED: | ||
254 | _copy(); | ||
255 | return -1; | ||
256 | } | ||
257 | } | ||
258 | else if ((!mbe || SP->mouse_status.button[1] & BUTTON_SHIFT) && | ||
259 | changes & 2 && (SP->mouse_status.button[1] & | ||
260 | BUTTON_ACTION_MASK) == BUTTON_CLICKED) | ||
261 | { | ||
262 | SP->key_code = FALSE; | ||
263 | return _paste(); | ||
264 | } | ||
265 | |||
266 | /* Filter unwanted mouse events */ | ||
267 | |||
268 | for (i = 0; i < 3; i++) | ||
269 | { | ||
270 | if (changes & (1 << i)) | ||
271 | { | ||
272 | int shf = i * 5; | ||
273 | short button = SP->mouse_status.button[i] & BUTTON_ACTION_MASK; | ||
274 | |||
275 | if ( (!(mbe & (BUTTON1_PRESSED << shf)) && | ||
276 | (button == BUTTON_PRESSED)) | ||
277 | |||
278 | || (!(mbe & (BUTTON1_CLICKED << shf)) && | ||
279 | (button == BUTTON_CLICKED)) | ||
280 | |||
281 | || (!(mbe & (BUTTON1_DOUBLE_CLICKED << shf)) && | ||
282 | (button == BUTTON_DOUBLE_CLICKED)) | ||
283 | |||
284 | || (!(mbe & (BUTTON1_MOVED << shf)) && | ||
285 | (button == BUTTON_MOVED)) | ||
286 | |||
287 | || (!(mbe & (BUTTON1_RELEASED << shf)) && | ||
288 | (button == BUTTON_RELEASED)) | ||
289 | ) | ||
290 | SP->mouse_status.changes ^= (1 << i); | ||
291 | } | ||
292 | } | ||
293 | |||
294 | if (changes & PDC_MOUSE_MOVED) | ||
295 | { | ||
296 | if (!(mbe & (BUTTON1_MOVED|BUTTON2_MOVED|BUTTON3_MOVED))) | ||
297 | SP->mouse_status.changes ^= PDC_MOUSE_MOVED; | ||
298 | } | ||
299 | |||
300 | if (changes & (PDC_MOUSE_WHEEL_UP|PDC_MOUSE_WHEEL_DOWN)) | ||
301 | { | ||
302 | if (!(mbe & MOUSE_WHEEL_SCROLL)) | ||
303 | SP->mouse_status.changes &= | ||
304 | ~(PDC_MOUSE_WHEEL_UP|PDC_MOUSE_WHEEL_DOWN); | ||
305 | } | ||
306 | |||
307 | if (!changes) | ||
308 | return -1; | ||
309 | |||
310 | /* Check for click in slk area */ | ||
311 | |||
312 | i = PDC_mouse_in_slk(SP->mouse_status.y, SP->mouse_status.x); | ||
313 | |||
314 | if (i) | ||
315 | { | ||
316 | if (SP->mouse_status.button[0] & (BUTTON_PRESSED|BUTTON_CLICKED)) | ||
317 | key = KEY_F(i); | ||
318 | else | ||
319 | key = -1; | ||
320 | } | ||
321 | |||
322 | return key; | ||
323 | } | ||
324 | |||
325 | int wgetch(WINDOW *win) | ||
326 | { | ||
327 | int key, waitcount; | ||
328 | |||
329 | PDC_LOG(("wgetch() - called\n")); | ||
330 | |||
331 | if (!win || !SP) | ||
332 | return ERR; | ||
333 | |||
334 | waitcount = 0; | ||
335 | |||
336 | /* set the number of 1/20th second napms() calls */ | ||
337 | |||
338 | if (SP->delaytenths) | ||
339 | waitcount = 2 * SP->delaytenths; | ||
340 | else | ||
341 | if (win->_delayms) | ||
342 | { | ||
343 | /* Can't really do millisecond intervals, so delay in | ||
344 | 1/20ths of a second (50ms) */ | ||
345 | |||
346 | waitcount = win->_delayms / 50; | ||
347 | if (!waitcount) | ||
348 | waitcount = 1; | ||
349 | } | ||
350 | |||
351 | /* refresh window when wgetch is called if there have been changes | ||
352 | to it and it is not a pad */ | ||
353 | |||
354 | if (!(win->_flags & _PAD) && ((!win->_leaveit && | ||
355 | (win->_begx + win->_curx != SP->curscol || | ||
356 | win->_begy + win->_cury != SP->cursrow)) || is_wintouched(win))) | ||
357 | wrefresh(win); | ||
358 | |||
359 | /* if ungotten char exists, remove and return it */ | ||
360 | |||
361 | if (SP->c_ungind) | ||
362 | return SP->c_ungch[--(SP->c_ungind)]; | ||
363 | |||
364 | /* if normal and data in buffer */ | ||
365 | |||
366 | if ((!SP->raw_inp && !SP->cbreak) && (SP->c_gindex < SP->c_pindex)) | ||
367 | return SP->c_buffer[SP->c_gindex++]; | ||
368 | |||
369 | /* prepare to buffer data */ | ||
370 | |||
371 | SP->c_pindex = 0; | ||
372 | SP->c_gindex = 0; | ||
373 | |||
374 | /* to get here, no keys are buffered. go and get one. */ | ||
375 | |||
376 | for (;;) /* loop for any buffering */ | ||
377 | { | ||
378 | /* is there a keystroke ready? */ | ||
379 | |||
380 | if (!PDC_check_key()) | ||
381 | { | ||
382 | /* if not, handle timeout() and halfdelay() */ | ||
383 | |||
384 | if (SP->delaytenths || win->_delayms) | ||
385 | { | ||
386 | if (!waitcount) | ||
387 | return ERR; | ||
388 | |||
389 | waitcount--; | ||
390 | } | ||
391 | else | ||
392 | if (win->_nodelay) | ||
393 | return ERR; | ||
394 | |||
395 | napms(50); /* sleep for 1/20th second */ | ||
396 | continue; /* then check again */ | ||
397 | } | ||
398 | |||
399 | /* if there is, fetch it */ | ||
400 | |||
401 | key = PDC_get_key(); | ||
402 | |||
403 | /* copy or paste? */ | ||
404 | |||
405 | if (SP->key_modifiers & PDC_KEY_MODIFIER_SHIFT) | ||
406 | { | ||
407 | if (0x03 == key) | ||
408 | { | ||
409 | _copy(); | ||
410 | continue; | ||
411 | } | ||
412 | else if (0x16 == key) | ||
413 | key = _paste(); | ||
414 | } | ||
415 | |||
416 | /* filter mouse events; translate mouse clicks in the slk | ||
417 | area to function keys */ | ||
418 | |||
419 | if (SP->key_code && key == KEY_MOUSE) | ||
420 | key = _mouse_key(); | ||
421 | |||
422 | /* filter special keys if not in keypad mode */ | ||
423 | |||
424 | if (SP->key_code && !win->_use_keypad) | ||
425 | key = -1; | ||
426 | |||
427 | /* unwanted key? loop back */ | ||
428 | |||
429 | if (key == -1) | ||
430 | continue; | ||
431 | |||
432 | _highlight(); | ||
433 | SP->sel_start = SP->sel_end = -1; | ||
434 | |||
435 | /* translate CR */ | ||
436 | |||
437 | if (key == '\r' && SP->autocr && !SP->raw_inp) | ||
438 | key = '\n'; | ||
439 | |||
440 | /* if echo is enabled */ | ||
441 | |||
442 | if (SP->echo && !SP->key_code) | ||
443 | { | ||
444 | waddch(win, key); | ||
445 | wrefresh(win); | ||
446 | } | ||
447 | |||
448 | /* if no buffering */ | ||
449 | |||
450 | if (SP->raw_inp || SP->cbreak) | ||
451 | return key; | ||
452 | |||
453 | /* if no overflow, put data in buffer */ | ||
454 | |||
455 | if (key == '\b') | ||
456 | { | ||
457 | if (SP->c_pindex > SP->c_gindex) | ||
458 | SP->c_pindex--; | ||
459 | } | ||
460 | else | ||
461 | if (SP->c_pindex < _INBUFSIZ - 2) | ||
462 | SP->c_buffer[SP->c_pindex++] = key; | ||
463 | |||
464 | /* if we got a line */ | ||
465 | |||
466 | if (key == '\n' || key == '\r') | ||
467 | return SP->c_buffer[SP->c_gindex++]; | ||
468 | } | ||
469 | } | ||
470 | |||
471 | int mvgetch(int y, int x) | ||
472 | { | ||
473 | PDC_LOG(("mvgetch() - called\n")); | ||
474 | |||
475 | if (move(y, x) == ERR) | ||
476 | return ERR; | ||
477 | |||
478 | return wgetch(stdscr); | ||
479 | } | ||
480 | |||
481 | int mvwgetch(WINDOW *win, int y, int x) | ||
482 | { | ||
483 | PDC_LOG(("mvwgetch() - called\n")); | ||
484 | |||
485 | if (wmove(win, y, x) == ERR) | ||
486 | return ERR; | ||
487 | |||
488 | return wgetch(win); | ||
489 | } | ||
490 | |||
491 | int PDC_ungetch(int ch) | ||
492 | { | ||
493 | PDC_LOG(("ungetch() - called\n")); | ||
494 | |||
495 | if (SP->c_ungind >= SP->c_ungmax) /* pushback stack full */ | ||
496 | return ERR; | ||
497 | |||
498 | SP->c_ungch[SP->c_ungind++] = ch; | ||
499 | |||
500 | return OK; | ||
501 | } | ||
502 | |||
503 | int flushinp(void) | ||
504 | { | ||
505 | PDC_LOG(("flushinp() - called\n")); | ||
506 | |||
507 | if (!SP) | ||
508 | return ERR; | ||
509 | |||
510 | PDC_flushinp(); | ||
511 | |||
512 | SP->c_gindex = 1; /* set indices to kill buffer */ | ||
513 | SP->c_pindex = 0; | ||
514 | SP->c_ungind = 0; /* clear SP->c_ungch array */ | ||
515 | |||
516 | return OK; | ||
517 | } | ||
518 | |||
519 | unsigned long PDC_get_key_modifiers(void) | ||
520 | { | ||
521 | PDC_LOG(("PDC_get_key_modifiers() - called\n")); | ||
522 | |||
523 | if (!SP) | ||
524 | return ERR; | ||
525 | |||
526 | return SP->key_modifiers; | ||
527 | } | ||
528 | |||
529 | int PDC_return_key_modifiers(bool flag) | ||
530 | { | ||
531 | PDC_LOG(("PDC_return_key_modifiers() - called\n")); | ||
532 | |||
533 | if (!SP) | ||
534 | return ERR; | ||
535 | |||
536 | SP->return_key_modifiers = flag; | ||
537 | return PDC_modifiers_set(); | ||
538 | } | ||
539 | |||
540 | #ifdef PDC_WIDE | ||
541 | int wget_wch(WINDOW *win, wint_t *wch) | ||
542 | { | ||
543 | int key; | ||
544 | |||
545 | PDC_LOG(("wget_wch() - called\n")); | ||
546 | |||
547 | if (!wch) | ||
548 | return ERR; | ||
549 | |||
550 | key = wgetch(win); | ||
551 | |||
552 | if (key == ERR) | ||
553 | return ERR; | ||
554 | |||
555 | *wch = key; | ||
556 | |||
557 | return SP->key_code ? KEY_CODE_YES : OK; | ||
558 | } | ||
559 | |||
560 | int get_wch(wint_t *wch) | ||
561 | { | ||
562 | PDC_LOG(("get_wch() - called\n")); | ||
563 | |||
564 | return wget_wch(stdscr, wch); | ||
565 | } | ||
566 | |||
567 | int mvget_wch(int y, int x, wint_t *wch) | ||
568 | { | ||
569 | PDC_LOG(("mvget_wch() - called\n")); | ||
570 | |||
571 | if (move(y, x) == ERR) | ||
572 | return ERR; | ||
573 | |||
574 | return wget_wch(stdscr, wch); | ||
575 | } | ||
576 | |||
577 | int mvwget_wch(WINDOW *win, int y, int x, wint_t *wch) | ||
578 | { | ||
579 | PDC_LOG(("mvwget_wch() - called\n")); | ||
580 | |||
581 | if (wmove(win, y, x) == ERR) | ||
582 | return ERR; | ||
583 | |||
584 | return wget_wch(win, wch); | ||
585 | } | ||
586 | |||
587 | int unget_wch(const wchar_t wch) | ||
588 | { | ||
589 | return PDC_ungetch(wch); | ||
590 | } | ||
591 | #endif | ||