1 #include <signal.h>
2 #include <string.h>
3 
4 #include "hsncurses-shim.h"
5 
6 #if NCURSES_VERSION_PATCH < 20081122
7 int _nc_has_mouse();
8 #endif
9 
hsncurses_has_mouse()10 int hsncurses_has_mouse()
11 {
12 #if NCURSES_VERSION_PATCH >= 20081122
13 	return has_mouse();
14 #else
15 	return _nc_has_mouse();
16 #endif
17 }
18 
hsncurses_wget_wch(WINDOW * w,wint_t * out)19 int hsncurses_wget_wch(WINDOW *w, wint_t *out) {
20 	/*
21 	Haskell's runtime system uses alarm signals to implement thread
22 	scheduling. These signals can interrupt system calls such as accept().
23 	ncurses doesn't handle interrupted system calls gracefully, so all
24 	the alarms can cause wget_wch() to return much earlier than expected.
25 
26 	As a workaround, we block alarms for the duration of wget_wch().
27 	*/
28 	int rc;
29 	sigset_t signal_alarm, old_mask;
30 
31 	sigemptyset(&signal_alarm);
32 	sigaddset(&signal_alarm, SIGALRM);
33 	sigaddset(&signal_alarm, SIGVTALRM);
34 
35 	pthread_sigmask(SIG_BLOCK, &signal_alarm, &old_mask);
36 	rc = wget_wch(w, out);
37 	pthread_sigmask(SIG_SETMASK, &old_mask, NULL);
38 	return rc;
39 }
40 
hsncurses_init_cchar_t(cchar_t * wch,attr_t attr,wchar_t * chars,size_t chars_len)41 void hsncurses_init_cchar_t(cchar_t *wch, attr_t attr, wchar_t *chars, size_t chars_len) {
42 	size_t ii;
43 	memset(wch, 0, sizeof(cchar_t));
44 	wch->attr = attr;
45 	for (ii = 0; ii < chars_len && ii < CCHARW_MAX; ii++) {
46 		wch->chars[ii] = chars[ii];
47 	}
48 }
49