libpayload: remove trailing whitespace and run dos2unix
[coreboot.git] / payloads / libpayload / curses / PDCurses-3.4 / x11 / pdcx11.c
1 /* Public Domain Curses */
2
3 #include "pdcx11.h"
4
5 RCSID("$Id: pdcx11.c,v 1.96 2008/07/14 04:24:52 wmcbrine Exp $")
6
7 #include <errno.h>
8 #include <stdlib.h>
9
10 /*** Functions that are called by both processes ***/
11
12 unsigned char *Xcurscr;
13
14 int XCursesProcess = 1;
15 int shmidSP;
16 int shmid_Xcurscr;
17 int shmkeySP;
18 int shmkey_Xcurscr;
19 int xc_otherpid;
20 int XCursesLINES = 24;
21 int XCursesCOLS = 80;
22 int xc_display_sock;
23 int xc_key_sock;
24 int xc_display_sockets[2];
25 int xc_key_sockets[2];
26 int xc_exit_sock;
27
28 fd_set xc_readfds;
29
30 static void _dummy_function(void)
31 {
32 }
33
34 void XC_get_line_lock(int row)
35 {
36     /* loop until we can write to the line -- Patch by:
37        Georg Fuchs, georg.fuchs@rz.uni-regensburg.de */
38
39     while (*(Xcurscr + XCURSCR_FLAG_OFF + row))
40         _dummy_function();
41
42     *(Xcurscr + XCURSCR_FLAG_OFF + row) = 1;
43 }
44
45 void XC_release_line_lock(int row)
46 {
47     *(Xcurscr + XCURSCR_FLAG_OFF + row) = 0;
48 }
49
50 int XC_write_socket(int sock_num, const void *buf, int len)
51 {
52     int start = 0, rc;
53
54     PDC_LOG(("%s:XC_write_socket called: sock_num %d len %d\n",
55              XCLOGMSG, sock_num, len));
56
57 #ifdef MOUSE_DEBUG
58     if (sock_num == xc_key_sock)
59         printf("%s:XC_write_socket(key) len: %d\n", XCLOGMSG, len);
60 #endif
61     while (1)
62     {
63         rc = write(sock_num, buf + start, len);
64
65         if (rc < 0 || rc == len)
66             return rc;
67
68         len -= rc;
69         start = rc;
70     }
71 }
72
73 int XC_read_socket(int sock_num, void *buf, int len)
74 {
75     int start = 0, length = len, rc;
76
77     PDC_LOG(("%s:XC_read_socket called: sock_num %d len %d\n",
78              XCLOGMSG, sock_num, len));
79
80     while (1)
81     {
82         rc = read(sock_num, buf + start, length);
83
84 #ifdef MOUSE_DEBUG
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);
88 #endif
89         if (rc < 0 && sock_num == xc_key_sock && errno == EINTR
90             && SP->resized != FALSE)
91         {
92             MOUSE_LOG(("%s:continuing\n", XCLOGMSG));
93
94             rc = 0;
95
96             if (SP->resized > 1)
97                 SP->resized = TRUE;
98             else
99                 SP->resized = FALSE;
100
101             memcpy(buf, &rc, sizeof(int));
102
103             return 0;
104         }
105
106         if (rc <= 0 || rc == length)
107             return rc;
108
109         length -= rc;
110         start = rc;
111     }
112 }
113
114 int XC_write_display_socket_int(int x)
115 {
116     return XC_write_socket(xc_display_sock, &x, sizeof(int));
117 }
118
119 #ifdef PDCDEBUG
120 void XC_say(const char *msg)
121 {
122     PDC_LOG(("%s:%s", XCLOGMSG, msg));
123 }
124 #endif
125
126 /*** Functions that are called by the "curses" process ***/
127
128 int XCursesInstruct(int flag)
129 {
130     PDC_LOG(("%s:XCursesInstruct() - called flag %d\n", XCLOGMSG, flag));
131
132     /* Send a request to X */
133
134     if (XC_write_display_socket_int(flag) < 0)
135         XCursesExitCursesProcess(4, "exiting from XCursesInstruct");
136
137     return OK;
138 }
139
140 int XCursesInstructAndWait(int flag)
141 {
142     int result;
143
144     XC_LOG(("XCursesInstructAndWait() - called\n"));
145
146     /* tell X we want to do something */
147
148     XCursesInstruct(flag);
149
150     /* wait for X to say the refresh has occurred*/
151
152     if (XC_read_socket(xc_display_sock, &result, sizeof(int)) < 0)
153         XCursesExitCursesProcess(5, "exiting from XCursesInstructAndWait");
154
155     if (result != CURSES_CONTINUE)
156         XCursesExitCursesProcess(6, "exiting from XCursesInstructAndWait"
157                                     " - synchronization error");
158
159     return OK;
160 }
161
162 static int _setup_curses(void)
163 {
164     int wait_value;
165
166     XC_LOG(("_setup_curses called\n"));
167
168     close(xc_display_sockets[1]);
169     close(xc_key_sockets[1]);
170
171     xc_display_sock = xc_display_sockets[0];
172     xc_key_sock = xc_key_sockets[0];
173
174     FD_ZERO(&xc_readfds);
175
176     XC_read_socket(xc_display_sock, &wait_value, sizeof(int));
177
178     if (wait_value != CURSES_CHILD)
179         return ERR;
180
181     /* Set LINES and COLS now so that the size of the shared memory
182        segment can be allocated */
183
184     if ((shmidSP = shmget(shmkeySP, sizeof(SCREEN) + XCURSESSHMMIN, 0700)) < 0)
185     {
186         perror("Cannot allocate shared memory for SCREEN");
187         kill(xc_otherpid, SIGKILL);
188         return ERR;
189     }
190
191     SP = (SCREEN*)shmat(shmidSP, 0, 0);
192
193     XCursesLINES = SP->lines;
194     LINES = XCursesLINES - SP->linesrippedoff - SP->slklines;
195     XCursesCOLS = COLS = SP->cols;
196
197     if ((shmid_Xcurscr = shmget(shmkey_Xcurscr,
198                                 SP->XcurscrSize + XCURSESSHMMIN, 0700)) < 0)
199     {
200         perror("Cannot allocate shared memory for curscr");
201         kill(xc_otherpid, SIGKILL);
202         return ERR;
203     }
204
205     PDC_LOG(("%s:shmid_Xcurscr %d shmkey_Xcurscr %d LINES %d COLS %d\n",
206              XCLOGMSG, shmid_Xcurscr, shmkey_Xcurscr, LINES, COLS));
207
208     Xcurscr = (unsigned char *)shmat(shmid_Xcurscr, 0, 0);
209     xc_atrtab = (short *)(Xcurscr + XCURSCR_ATRTAB_OFF);
210
211     XC_LOG(("cursesprocess exiting from Xinitscr\n"));
212
213     /* Always trap SIGWINCH if the C library supports SIGWINCH */
214
215     XCursesSetSignal(SIGWINCH, XCursesSigwinchHandler);
216
217     atexit(XCursesExit);
218
219     return OK;
220 }
221
222 int XCursesInitscr(int argc, char *argv[])
223 {
224     int pid, rc;
225
226     XC_LOG(("XCursesInitscr() - called\n"));
227
228     shmkeySP = getpid();
229
230     if (socketpair(AF_UNIX, SOCK_STREAM, 0, xc_display_sockets) < 0)
231     {
232         fprintf(stderr, "ERROR: cannot create display socketpair\n");
233         return ERR;
234     }
235
236     if (socketpair(AF_UNIX, SOCK_STREAM, 0, xc_key_sockets) < 0)
237     {
238         fprintf(stderr, "ERROR: cannot create key socketpair\n");
239         return ERR;
240     }
241
242     pid = fork();
243
244     switch(pid)
245     {
246     case -1:
247         fprintf(stderr, "ERROR: cannot fork()\n");
248         return ERR;
249         break;
250
251     case 0: /* child */
252         shmkey_Xcurscr = getpid();
253 #ifdef XISPARENT
254         XCursesProcess = 0;
255         rc = _setup_curses();
256 #else
257         XCursesProcess = 1;
258         xc_otherpid = getppid();
259         rc = XCursesSetupX(argc, argv);
260 #endif
261         break;
262
263     default:  /* parent */
264         shmkey_Xcurscr = pid;
265 #ifdef XISPARENT
266         XCursesProcess = 1;
267         xc_otherpid = pid;
268         rc = XCursesSetupX(argc, argv);
269 #else
270         XCursesProcess = 0;
271         rc = _setup_curses();
272 #endif
273     }
274
275     return rc;
276 }
277
278 static void _cleanup_curses_process(int rc)
279 {
280     PDC_LOG(("%s:_cleanup_curses_process() - called: %d\n", XCLOGMSG, rc));
281
282     shutdown(xc_display_sock, 2);
283     close(xc_display_sock);
284
285     shutdown(xc_key_sock, 2);
286     close(xc_key_sock);
287
288     shmdt((char *)SP);
289     shmdt((char *)Xcurscr);
290
291     if (rc)
292         _exit(rc);
293 }
294
295 void XCursesExitCursesProcess(int rc, char *msg)
296 {
297     PDC_LOG(("%s:XCursesExitCursesProcess() - called: %d %s\n",
298              XCLOGMSG, rc, msg));
299
300     endwin();
301     _cleanup_curses_process(rc);
302 }
303
304 void XCursesExit(void)
305 {
306     static bool called = FALSE;
307
308     XC_LOG(("XCursesExit() - called\n"));
309
310     if (FALSE == called)
311     {
312         XCursesInstruct(CURSES_EXIT);
313         _cleanup_curses_process(0);
314
315         called = TRUE;
316     }
317 }