1 /* Public Domain Curses */
5 RCSID("$Id: pdcx11.c,v 1.96 2008/07/14 04:24:52 wmcbrine Exp $")
10 /*** Functions that are called by both processes ***/
12 unsigned char *Xcurscr
;
14 int XCursesProcess
= 1;
20 int XCursesLINES
= 24;
24 int xc_display_sockets
[2];
25 int xc_key_sockets
[2];
30 static void _dummy_function(void)
34 void XC_get_line_lock(int row
)
36 /* loop until we can write to the line -- Patch by:
37 Georg Fuchs, georg.fuchs@rz.uni-regensburg.de */
39 while (*(Xcurscr
+ XCURSCR_FLAG_OFF
+ row
))
42 *(Xcurscr
+ XCURSCR_FLAG_OFF
+ row
) = 1;
45 void XC_release_line_lock(int row
)
47 *(Xcurscr
+ XCURSCR_FLAG_OFF
+ row
) = 0;
50 int XC_write_socket(int sock_num
, const void *buf
, int len
)
54 PDC_LOG(("%s:XC_write_socket called: sock_num %d len %d\n",
55 XCLOGMSG
, sock_num
, len
));
58 if (sock_num
== xc_key_sock
)
59 printf("%s:XC_write_socket(key) len: %d\n", XCLOGMSG
, len
);
63 rc
= write(sock_num
, buf
+ start
, len
);
65 if (rc
< 0 || rc
== len
)
73 int XC_read_socket(int sock_num
, void *buf
, int len
)
75 int start
= 0, length
= len
, rc
;
77 PDC_LOG(("%s:XC_read_socket called: sock_num %d len %d\n",
78 XCLOGMSG
, sock_num
, len
));
82 rc
= read(sock_num
, buf
+ start
, length
);
85 if (sock_num
== xc_key_sock
)
86 printf("%s:XC_read_socket(key) rc %d errno %d "
87 "resized: %d\n", XCLOGMSG
, rc
, errno
, SP
->resized
);
89 if (rc
< 0 && sock_num
== xc_key_sock
&& errno
== EINTR
90 && SP
->resized
!= FALSE
)
92 MOUSE_LOG(("%s:continuing\n", XCLOGMSG
));
101 memcpy(buf
, &rc
, sizeof(int));
106 if (rc
<= 0 || rc
== length
)
114 int XC_write_display_socket_int(int x
)
116 return XC_write_socket(xc_display_sock
, &x
, sizeof(int));
120 void XC_say(const char *msg
)
122 PDC_LOG(("%s:%s", XCLOGMSG
, msg
));
126 /*** Functions that are called by the "curses" process ***/
128 int XCursesInstruct(int flag
)
130 PDC_LOG(("%s:XCursesInstruct() - called flag %d\n", XCLOGMSG
, flag
));
132 /* Send a request to X */
134 if (XC_write_display_socket_int(flag
) < 0)
135 XCursesExitCursesProcess(4, "exiting from XCursesInstruct");
140 int XCursesInstructAndWait(int flag
)
144 XC_LOG(("XCursesInstructAndWait() - called\n"));
146 /* tell X we want to do something */
148 XCursesInstruct(flag
);
150 /* wait for X to say the refresh has occurred*/
152 if (XC_read_socket(xc_display_sock
, &result
, sizeof(int)) < 0)
153 XCursesExitCursesProcess(5, "exiting from XCursesInstructAndWait");
155 if (result
!= CURSES_CONTINUE
)
156 XCursesExitCursesProcess(6, "exiting from XCursesInstructAndWait"
157 " - synchronization error");
162 static int _setup_curses(void)
166 XC_LOG(("_setup_curses called\n"));
168 close(xc_display_sockets
[1]);
169 close(xc_key_sockets
[1]);
171 xc_display_sock
= xc_display_sockets
[0];
172 xc_key_sock
= xc_key_sockets
[0];
174 FD_ZERO(&xc_readfds
);
176 XC_read_socket(xc_display_sock
, &wait_value
, sizeof(int));
178 if (wait_value
!= CURSES_CHILD
)
181 /* Set LINES and COLS now so that the size of the shared memory
182 segment can be allocated */
184 if ((shmidSP
= shmget(shmkeySP
, sizeof(SCREEN
) + XCURSESSHMMIN
, 0700)) < 0)
186 perror("Cannot allocate shared memory for SCREEN");
187 kill(xc_otherpid
, SIGKILL
);
191 SP
= (SCREEN
*)shmat(shmidSP
, 0, 0);
193 XCursesLINES
= SP
->lines
;
194 LINES
= XCursesLINES
- SP
->linesrippedoff
- SP
->slklines
;
195 XCursesCOLS
= COLS
= SP
->cols
;
197 if ((shmid_Xcurscr
= shmget(shmkey_Xcurscr
,
198 SP
->XcurscrSize
+ XCURSESSHMMIN
, 0700)) < 0)
200 perror("Cannot allocate shared memory for curscr");
201 kill(xc_otherpid
, SIGKILL
);
205 PDC_LOG(("%s:shmid_Xcurscr %d shmkey_Xcurscr %d LINES %d COLS %d\n",
206 XCLOGMSG
, shmid_Xcurscr
, shmkey_Xcurscr
, LINES
, COLS
));
208 Xcurscr
= (unsigned char *)shmat(shmid_Xcurscr
, 0, 0);
209 xc_atrtab
= (short *)(Xcurscr
+ XCURSCR_ATRTAB_OFF
);
211 XC_LOG(("cursesprocess exiting from Xinitscr\n"));
213 /* Always trap SIGWINCH if the C library supports SIGWINCH */
215 XCursesSetSignal(SIGWINCH
, XCursesSigwinchHandler
);
222 int XCursesInitscr(int argc
, char *argv
[])
226 XC_LOG(("XCursesInitscr() - called\n"));
230 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, xc_display_sockets
) < 0)
232 fprintf(stderr
, "ERROR: cannot create display socketpair\n");
236 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, xc_key_sockets
) < 0)
238 fprintf(stderr
, "ERROR: cannot create key socketpair\n");
247 fprintf(stderr
, "ERROR: cannot fork()\n");
252 shmkey_Xcurscr
= getpid();
255 rc
= _setup_curses();
258 xc_otherpid
= getppid();
259 rc
= XCursesSetupX(argc
, argv
);
263 default: /* parent */
264 shmkey_Xcurscr
= pid
;
268 rc
= XCursesSetupX(argc
, argv
);
271 rc
= _setup_curses();
278 static void _cleanup_curses_process(int rc
)
280 PDC_LOG(("%s:_cleanup_curses_process() - called: %d\n", XCLOGMSG
, rc
));
282 shutdown(xc_display_sock
, 2);
283 close(xc_display_sock
);
285 shutdown(xc_key_sock
, 2);
289 shmdt((char *)Xcurscr
);
295 void XCursesExitCursesProcess(int rc
, char *msg
)
297 PDC_LOG(("%s:XCursesExitCursesProcess() - called: %d %s\n",
301 _cleanup_curses_process(rc
);
304 void XCursesExit(void)
306 static bool called
= FALSE
;
308 XC_LOG(("XCursesExit() - called\n"));
312 XCursesInstruct(CURSES_EXIT
);
313 _cleanup_curses_process(0);