5 /*man-start**************************************************************
13 int wgetch(WINDOW *win);
14 int mvgetch(int y, int x);
15 int mvwgetch(WINDOW *win, int y, int x);
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);
25 unsigned long PDC_get_key_modifiers(void);
26 int PDC_return_key_modifiers(bool flag);
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.
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_.
44 If nodelay(win, TRUE) has been called on the window and no input is
45 waiting, the value ERR is returned.
47 ungetch() places ch back onto the input queue to be returned by the
48 next call to wgetch().
50 flushinp() throws away any type-ahead that has been typed by the user
51 and has not yet been read by the program.
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.
60 unget_wch() puts a wide character on the input queue.
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.
69 NOTE: getch() and ungetch() are implemented as macros, to avoid
70 conflict with many DOS compiler's runtime libraries.
74 These functions return ERR or the value of the character, meta
75 character or function key token.
90 PDC_get_key_modifiers - - -
92 **man-end****************************************************************/
96 static int _get_box(int *y_start
, int *y_end
, int *x_start
, int *x_end
)
100 if (SP
->sel_start
< SP
->sel_end
)
102 start
= SP
->sel_start
;
111 *y_start
= start
/ COLS
;
112 *x_start
= start
% COLS
;
117 return (end
- start
) + (*y_end
- *y_start
);
120 static void _highlight(void)
122 int i
, j
, y_start
, y_end
, x_start
, x_end
;
124 if (-1 == SP
->sel_start
)
127 _get_box(&y_start
, &y_end
, &x_start
, &x_end
);
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
;
137 static void _copy(void)
142 # define MASK A_CHARTEXT
149 int i
, j
, y_start
, y_end
, x_start
, x_end
, len
;
151 if (-1 == SP
->sel_start
)
154 len
= _get_box(&y_start
, &y_end
, &x_start
, &x_end
);
160 wtmp
= malloc((len
+ 1) * sizeof(wchar_t));
163 tmp
= malloc(len
+ 1);
165 for (j
= y_start
, pos
= 0; j
<= y_end
; j
++)
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
;
171 while (y_start
!= y_end
&& pos
> 0 && TMP
[pos
- 1] == 32)
180 pos
= PDC_wcstombs(tmp
, wtmp
, len
);
183 PDC_setclipboard(tmp
, pos
);
190 static int _paste(void)
194 # define PASTE wpaste
202 key
= PDC_getclipboard(&paste
, &len
);
203 if (PDC_CLIP_SUCCESS
!= key
|| !len
)
207 wpaste
= malloc(len
* sizeof(wchar_t));
208 len
= PDC_mbstowcs(wpaste
, paste
, len
);
210 newmax
= len
+ SP
->c_ungind
;
211 if (newmax
> SP
->c_ungmax
)
213 SP
->c_ungch
= realloc(SP
->c_ungch
, newmax
* sizeof(int));
216 SP
->c_ungmax
= newmax
;
219 PDC_ungetch(PASTE
[--len
]);
224 PDC_freeclipboard(paste
);
225 SP
->key_modifiers
= 0;
230 static int _mouse_key(void)
232 int i
, key
= KEY_MOUSE
, changes
= SP
->mouse_status
.changes
;
233 unsigned long mbe
= SP
->_trap_mbe
;
235 /* Selection highlighting? */
237 if ((!mbe
|| SP
->mouse_status
.button
[0] & BUTTON_SHIFT
) && changes
& 1)
239 i
= SP
->mouse_status
.y
* COLS
+ SP
->mouse_status
.x
;
240 switch (SP
->mouse_status
.button
[0] & BUTTON_ACTION_MASK
)
244 SP
->sel_start
= SP
->sel_end
= i
;
251 case BUTTON_RELEASED
:
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
)
260 SP
->key_code
= FALSE
;
264 /* Filter unwanted mouse events */
266 for (i
= 0; i
< 3; i
++)
268 if (changes
& (1 << i
))
271 short button
= SP
->mouse_status
.button
[i
] & BUTTON_ACTION_MASK
;
273 if ( (!(mbe
& (BUTTON1_PRESSED
<< shf
)) &&
274 (button
== BUTTON_PRESSED
))
276 || (!(mbe
& (BUTTON1_CLICKED
<< shf
)) &&
277 (button
== BUTTON_CLICKED
))
279 || (!(mbe
& (BUTTON1_DOUBLE_CLICKED
<< shf
)) &&
280 (button
== BUTTON_DOUBLE_CLICKED
))
282 || (!(mbe
& (BUTTON1_MOVED
<< shf
)) &&
283 (button
== BUTTON_MOVED
))
285 || (!(mbe
& (BUTTON1_RELEASED
<< shf
)) &&
286 (button
== BUTTON_RELEASED
))
288 SP
->mouse_status
.changes
^= (1 << i
);
292 if (changes
& PDC_MOUSE_MOVED
)
294 if (!(mbe
& (BUTTON1_MOVED
|BUTTON2_MOVED
|BUTTON3_MOVED
)))
295 SP
->mouse_status
.changes
^= PDC_MOUSE_MOVED
;
298 if (changes
& (PDC_MOUSE_WHEEL_UP
|PDC_MOUSE_WHEEL_DOWN
))
300 if (!(mbe
& MOUSE_WHEEL_SCROLL
))
301 SP
->mouse_status
.changes
&=
302 ~(PDC_MOUSE_WHEEL_UP
|PDC_MOUSE_WHEEL_DOWN
);
308 /* Check for click in slk area */
310 i
= PDC_mouse_in_slk(SP
->mouse_status
.y
, SP
->mouse_status
.x
);
314 if (SP
->mouse_status
.button
[0] & (BUTTON_PRESSED
|BUTTON_CLICKED
))
323 int wgetch(WINDOW
*win
)
327 PDC_LOG(("wgetch() - called\n"));
334 /* set the number of 1/20th second napms() calls */
337 waitcount
= 2 * SP
->delaytenths
;
341 /* Can't really do millisecond intervals, so delay in
342 1/20ths of a second (50ms) */
344 waitcount
= win
->_delayms
/ 50;
349 /* refresh window when wgetch is called if there have been changes
350 to it and it is not a pad */
352 if (!(win
->_flags
& _PAD
) && ((!win
->_leaveit
&&
353 (win
->_begx
+ win
->_curx
!= SP
->curscol
||
354 win
->_begy
+ win
->_cury
!= SP
->cursrow
)) || is_wintouched(win
)))
357 /* if ungotten char exists, remove and return it */
360 return SP
->c_ungch
[--(SP
->c_ungind
)];
362 /* if normal and data in buffer */
364 if ((!SP
->raw_inp
&& !SP
->cbreak
) && (SP
->c_gindex
< SP
->c_pindex
))
365 return SP
->c_buffer
[SP
->c_gindex
++];
367 /* prepare to buffer data */
372 /* to get here, no keys are buffered. go and get one. */
374 for (;;) /* loop for any buffering */
376 /* is there a keystroke ready? */
378 if (!PDC_check_key())
380 /* if not, handle timeout() and halfdelay() */
382 if (SP
->delaytenths
|| win
->_delayms
)
393 napms(50); /* sleep for 1/20th second */
394 continue; /* then check again */
397 /* if there is, fetch it */
403 if (SP
->key_modifiers
& PDC_KEY_MODIFIER_SHIFT
)
410 else if (0x16 == key
)
414 /* filter mouse events; translate mouse clicks in the slk
415 area to function keys */
417 if (SP
->key_code
&& key
== KEY_MOUSE
)
420 /* filter special keys if not in keypad mode */
422 if (SP
->key_code
&& !win
->_use_keypad
)
425 /* unwanted key? loop back */
431 SP
->sel_start
= SP
->sel_end
= -1;
435 if (key
== '\r' && SP
->autocr
&& !SP
->raw_inp
)
438 /* if echo is enabled */
440 if (SP
->echo
&& !SP
->key_code
)
446 /* if no buffering */
448 if (SP
->raw_inp
|| SP
->cbreak
)
451 /* if no overflow, put data in buffer */
455 if (SP
->c_pindex
> SP
->c_gindex
)
459 if (SP
->c_pindex
< _INBUFSIZ
- 2)
460 SP
->c_buffer
[SP
->c_pindex
++] = key
;
462 /* if we got a line */
464 if (key
== '\n' || key
== '\r')
465 return SP
->c_buffer
[SP
->c_gindex
++];
469 int mvgetch(int y
, int x
)
471 PDC_LOG(("mvgetch() - called\n"));
473 if (move(y
, x
) == ERR
)
476 return wgetch(stdscr
);
479 int mvwgetch(WINDOW
*win
, int y
, int x
)
481 PDC_LOG(("mvwgetch() - called\n"));
483 if (wmove(win
, y
, x
) == ERR
)
489 int PDC_ungetch(int ch
)
491 PDC_LOG(("ungetch() - called\n"));
493 if (SP
->c_ungind
>= SP
->c_ungmax
) /* pushback stack full */
496 SP
->c_ungch
[SP
->c_ungind
++] = ch
;
503 PDC_LOG(("flushinp() - called\n"));
510 SP
->c_gindex
= 1; /* set indices to kill buffer */
512 SP
->c_ungind
= 0; /* clear SP->c_ungch array */
517 unsigned long PDC_get_key_modifiers(void)
519 PDC_LOG(("PDC_get_key_modifiers() - called\n"));
524 return SP
->key_modifiers
;
527 int PDC_return_key_modifiers(bool flag
)
529 PDC_LOG(("PDC_return_key_modifiers() - called\n"));
534 SP
->return_key_modifiers
= flag
;
535 return PDC_modifiers_set();
539 int wget_wch(WINDOW
*win
, wint_t *wch
)
543 PDC_LOG(("wget_wch() - called\n"));
555 return SP
->key_code
? KEY_CODE_YES
: OK
;
558 int get_wch(wint_t *wch
)
560 PDC_LOG(("get_wch() - called\n"));
562 return wget_wch(stdscr
, wch
);
565 int mvget_wch(int y
, int x
, wint_t *wch
)
567 PDC_LOG(("mvget_wch() - called\n"));
569 if (move(y
, x
) == ERR
)
572 return wget_wch(stdscr
, wch
);
575 int mvwget_wch(WINDOW
*win
, int y
, int x
, wint_t *wch
)
577 PDC_LOG(("mvwget_wch() - called\n"));
579 if (wmove(win
, y
, x
) == ERR
)
582 return wget_wch(win
, wch
);
585 int unget_wch(const wchar_t wch
)
587 return PDC_ungetch(wch
);