aboutsummaryrefslogtreecommitdiff
path: root/payloads/libpayload/curses/PDCurses-3.4/x11/pdcx11.c
diff options
context:
space:
mode:
Diffstat (limited to 'payloads/libpayload/curses/PDCurses-3.4/x11/pdcx11.c')
-rw-r--r--payloads/libpayload/curses/PDCurses-3.4/x11/pdcx11.c317
1 files changed, 317 insertions, 0 deletions
diff --git a/payloads/libpayload/curses/PDCurses-3.4/x11/pdcx11.c b/payloads/libpayload/curses/PDCurses-3.4/x11/pdcx11.c
new file mode 100644
index 0000000000..1e8d0d163c
--- /dev/null
+++ b/payloads/libpayload/curses/PDCurses-3.4/x11/pdcx11.c
@@ -0,0 +1,317 @@
+/* Public Domain Curses */
+
+#include "pdcx11.h"
+
+RCSID("$Id: pdcx11.c,v 1.96 2008/07/14 04:24:52 wmcbrine Exp $")
+
+#include <errno.h>
+#include <stdlib.h>
+
+/*** Functions that are called by both processes ***/
+
+unsigned char *Xcurscr;
+
+int XCursesProcess = 1;
+int shmidSP;
+int shmid_Xcurscr;
+int shmkeySP;
+int shmkey_Xcurscr;
+int xc_otherpid;
+int XCursesLINES = 24;
+int XCursesCOLS = 80;
+int xc_display_sock;
+int xc_key_sock;
+int xc_display_sockets[2];
+int xc_key_sockets[2];
+int xc_exit_sock;
+
+fd_set xc_readfds;
+
+static void _dummy_function(void)
+{
+}
+
+void XC_get_line_lock(int row)
+{
+ /* loop until we can write to the line -- Patch by:
+ Georg Fuchs, georg.fuchs@rz.uni-regensburg.de */
+
+ while (*(Xcurscr + XCURSCR_FLAG_OFF + row))
+ _dummy_function();
+
+ *(Xcurscr + XCURSCR_FLAG_OFF + row) = 1;
+}
+
+void XC_release_line_lock(int row)
+{
+ *(Xcurscr + XCURSCR_FLAG_OFF + row) = 0;
+}
+
+int XC_write_socket(int sock_num, const void *buf, int len)
+{
+ int start = 0, rc;
+
+ PDC_LOG(("%s:XC_write_socket called: sock_num %d len %d\n",
+ XCLOGMSG, sock_num, len));
+
+#ifdef MOUSE_DEBUG
+ if (sock_num == xc_key_sock)
+ printf("%s:XC_write_socket(key) len: %d\n", XCLOGMSG, len);
+#endif
+ while (1)
+ {
+ rc = write(sock_num, buf + start, len);
+
+ if (rc < 0 || rc == len)
+ return rc;
+
+ len -= rc;
+ start = rc;
+ }
+}
+
+int XC_read_socket(int sock_num, void *buf, int len)
+{
+ int start = 0, length = len, rc;
+
+ PDC_LOG(("%s:XC_read_socket called: sock_num %d len %d\n",
+ XCLOGMSG, sock_num, len));
+
+ while (1)
+ {
+ rc = read(sock_num, buf + start, length);
+
+#ifdef MOUSE_DEBUG
+ if (sock_num == xc_key_sock)
+ printf("%s:XC_read_socket(key) rc %d errno %d "
+ "resized: %d\n", XCLOGMSG, rc, errno, SP->resized);
+#endif
+ if (rc < 0 && sock_num == xc_key_sock && errno == EINTR
+ && SP->resized != FALSE)
+ {
+ MOUSE_LOG(("%s:continuing\n", XCLOGMSG));
+
+ rc = 0;
+
+ if (SP->resized > 1)
+ SP->resized = TRUE;
+ else
+ SP->resized = FALSE;
+
+ memcpy(buf, &rc, sizeof(int));
+
+ return 0;
+ }
+
+ if (rc <= 0 || rc == length)
+ return rc;
+
+ length -= rc;
+ start = rc;
+ }
+}
+
+int XC_write_display_socket_int(int x)
+{
+ return XC_write_socket(xc_display_sock, &x, sizeof(int));
+}
+
+#ifdef PDCDEBUG
+void XC_say(const char *msg)
+{
+ PDC_LOG(("%s:%s", XCLOGMSG, msg));
+}
+#endif
+
+/*** Functions that are called by the "curses" process ***/
+
+int XCursesInstruct(int flag)
+{
+ PDC_LOG(("%s:XCursesInstruct() - called flag %d\n", XCLOGMSG, flag));
+
+ /* Send a request to X */
+
+ if (XC_write_display_socket_int(flag) < 0)
+ XCursesExitCursesProcess(4, "exiting from XCursesInstruct");
+
+ return OK;
+}
+
+int XCursesInstructAndWait(int flag)
+{
+ int result;
+
+ XC_LOG(("XCursesInstructAndWait() - called\n"));
+
+ /* tell X we want to do something */
+
+ XCursesInstruct(flag);
+
+ /* wait for X to say the refresh has occurred*/
+
+ if (XC_read_socket(xc_display_sock, &result, sizeof(int)) < 0)
+ XCursesExitCursesProcess(5, "exiting from XCursesInstructAndWait");
+
+ if (result != CURSES_CONTINUE)
+ XCursesExitCursesProcess(6, "exiting from XCursesInstructAndWait"
+ " - synchronization error");
+
+ return OK;
+}
+
+static int _setup_curses(void)
+{
+ int wait_value;
+
+ XC_LOG(("_setup_curses called\n"));
+
+ close(xc_display_sockets[1]);
+ close(xc_key_sockets[1]);
+
+ xc_display_sock = xc_display_sockets[0];
+ xc_key_sock = xc_key_sockets[0];
+
+ FD_ZERO(&xc_readfds);
+
+ XC_read_socket(xc_display_sock, &wait_value, sizeof(int));
+
+ if (wait_value != CURSES_CHILD)
+ return ERR;
+
+ /* Set LINES and COLS now so that the size of the shared memory
+ segment can be allocated */
+
+ if ((shmidSP = shmget(shmkeySP, sizeof(SCREEN) + XCURSESSHMMIN, 0700)) < 0)
+ {
+ perror("Cannot allocate shared memory for SCREEN");
+ kill(xc_otherpid, SIGKILL);
+ return ERR;
+ }
+
+ SP = (SCREEN*)shmat(shmidSP, 0, 0);
+
+ XCursesLINES = SP->lines;
+ LINES = XCursesLINES - SP->linesrippedoff - SP->slklines;
+ XCursesCOLS = COLS = SP->cols;
+
+ if ((shmid_Xcurscr = shmget(shmkey_Xcurscr,
+ SP->XcurscrSize + XCURSESSHMMIN, 0700)) < 0)
+ {
+ perror("Cannot allocate shared memory for curscr");
+ kill(xc_otherpid, SIGKILL);
+ return ERR;
+ }
+
+ PDC_LOG(("%s:shmid_Xcurscr %d shmkey_Xcurscr %d LINES %d COLS %d\n",
+ XCLOGMSG, shmid_Xcurscr, shmkey_Xcurscr, LINES, COLS));
+
+ Xcurscr = (unsigned char *)shmat(shmid_Xcurscr, 0, 0);
+ xc_atrtab = (short *)(Xcurscr + XCURSCR_ATRTAB_OFF);
+
+ XC_LOG(("cursesprocess exiting from Xinitscr\n"));
+
+ /* Always trap SIGWINCH if the C library supports SIGWINCH */
+
+ XCursesSetSignal(SIGWINCH, XCursesSigwinchHandler);
+
+ atexit(XCursesExit);
+
+ return OK;
+}
+
+int XCursesInitscr(int argc, char *argv[])
+{
+ int pid, rc;
+
+ XC_LOG(("XCursesInitscr() - called\n"));
+
+ shmkeySP = getpid();
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, xc_display_sockets) < 0)
+ {
+ fprintf(stderr, "ERROR: cannot create display socketpair\n");
+ return ERR;
+ }
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, xc_key_sockets) < 0)
+ {
+ fprintf(stderr, "ERROR: cannot create key socketpair\n");
+ return ERR;
+ }
+
+ pid = fork();
+
+ switch(pid)
+ {
+ case -1:
+ fprintf(stderr, "ERROR: cannot fork()\n");
+ return ERR;
+ break;
+
+ case 0: /* child */
+ shmkey_Xcurscr = getpid();
+#ifdef XISPARENT
+ XCursesProcess = 0;
+ rc = _setup_curses();
+#else
+ XCursesProcess = 1;
+ xc_otherpid = getppid();
+ rc = XCursesSetupX(argc, argv);
+#endif
+ break;
+
+ default: /* parent */
+ shmkey_Xcurscr = pid;
+#ifdef XISPARENT
+ XCursesProcess = 1;
+ xc_otherpid = pid;
+ rc = XCursesSetupX(argc, argv);
+#else
+ XCursesProcess = 0;
+ rc = _setup_curses();
+#endif
+ }
+
+ return rc;
+}
+
+static void _cleanup_curses_process(int rc)
+{
+ PDC_LOG(("%s:_cleanup_curses_process() - called: %d\n", XCLOGMSG, rc));
+
+ shutdown(xc_display_sock, 2);
+ close(xc_display_sock);
+
+ shutdown(xc_key_sock, 2);
+ close(xc_key_sock);
+
+ shmdt((char *)SP);
+ shmdt((char *)Xcurscr);
+
+ if (rc)
+ _exit(rc);
+}
+
+void XCursesExitCursesProcess(int rc, char *msg)
+{
+ PDC_LOG(("%s:XCursesExitCursesProcess() - called: %d %s\n",
+ XCLOGMSG, rc, msg));
+
+ endwin();
+ _cleanup_curses_process(rc);
+}
+
+void XCursesExit(void)
+{
+ static bool called = FALSE;
+
+ XC_LOG(("XCursesExit() - called\n"));
+
+ if (FALSE == called)
+ {
+ XCursesInstruct(CURSES_EXIT);
+ _cleanup_curses_process(0);
+
+ called = TRUE;
+ }
+}