70 #include <sys/select.h>
71 #include <sys/types.h>
85 static struct termios console_oldtermios;
86 static struct termios console_curtermios;
89 static struct termios console_slave_tios;
90 static int console_slave_outputd;
92 static int console_initialized = 0;
93 static struct settings *console_settings = NULL;
94 static int console_stdout_pending;
96 #define CONSOLE_FIFO_LEN 4096
98 static int console_mouse_x;
99 static int console_mouse_y;
100 static int console_mouse_fb_nr;
102 static int console_mouse_buttons;
104 static int allow_slaves = 0;
125 #define NOT_USING_XTERM 0
126 #define USING_XTERM_BUT_NOT_YET_OPEN 1
127 #define USING_XTERM 2
131 static int n_console_handles = 0;
141 if (!console_initialized)
144 tcsetattr(STDIN_FILENO, TCSANOW, &console_oldtermios);
146 console_initialized = 0;
161 if (!console_initialized)
165 tcsetattr(STDIN_FILENO, TCSANOW, &console_curtermios);
181 static void start_xterm(
int handle)
192 printf(
"[ start_xterm(): pipe(): %i ]\n", errno);
196 res = pipe(filedesB);
198 printf(
"[ start_xterm(): pipe(): %i ]\n", errno);
208 a[0] = getenv(
"XTERM");
210 a[0] = strdup(
"xterm");
211 a[1] = strdup(
"-geometry");
212 a[2] = strdup(
"80x25");
213 a[3] = strdup(
"-title");
217 snprintf(a[4], mlen,
"GXemul: %s %s",
219 console_handles[handle].
name);
223 snprintf(a[7], 80,
"-WW@S%i,%i", filedes[0], filedesB[1]);
228 printf(
"[ start_xterm(): ERROR while trying to "
229 "fork(): %i ]\n", errno);
237 printf(
"[ start_xterm(): ERROR while trying "
238 "to do a setsid(): %i ]\n", errno);
240 res = execvp(a[0], a);
241 printf(
"[ start_xterm(): ERROR while trying to "
243 while (a[0] != NULL) {
249 printf(
"\"): %i ]\n", errno);
251 printf(
"[ Most probably you don't have xterm"
252 " in your PATH. Try again. ]\n");
277 static int d_avail(
int d)
286 return select(d+1, &rfds, NULL, NULL, &tv);
298 console_handles[handle].
fifo[
303 if (console_handles[handle].fifo_head ==
304 console_handles[handle].fifo_tail)
305 fatal(
"[ WARNING: console fifo overrun, handle %i ]\n", handle);
315 static int console_stdin_avail(
int handle)
317 if (!console_handles[handle].in_use_for_input)
321 return d_avail(STDIN_FILENO);
323 if (console_handles[handle].using_xterm ==
327 return d_avail(console_handles[handle].r_descriptor);
331 static int console_room_left_in_fifo(
int handle)
333 int roomLeftInFIFO = console_handles[handle].
fifo_tail
335 if (roomLeftInFIFO <= 0)
338 return roomLeftInFIFO;
349 while (console_stdin_avail(handle)) {
350 unsigned char ch[100];
356 int roomLeftInFIFO = console_room_left_in_fifo(handle);
357 if (roomLeftInFIFO < (
int)
sizeof(ch) + 1)
365 len = read(d, ch,
sizeof(ch));
367 for (i=0; i<len; i++) {
397 ch = console_handles[handle].
fifo[console_handles[handle].
fifo_tail];
414 if (!console_handles[handle].in_use_for_input &&
415 !console_handles[handle].outputonly)
424 console_stdout_pending = 0;
426 console_stdout_pending = 1;
431 if (!console_handles[handle].in_use) {
432 printf(
"[ console_putchar(): handle %i not in"
433 " use! ]\n", handle);
437 if (console_handles[handle].using_xterm ==
442 if (write(console_handles[handle].w_descriptor, buf, 1) != 1)
443 perror(
"error writing to console handle");
454 if (console_stdout_pending)
457 console_stdout_pending = 0;
474 console_mouse_fb_nr = fb_nr;
487 int mask = 1 << (3-button);
490 console_mouse_buttons |= mask;
492 console_mouse_buttons &= ~mask;
504 *x = console_mouse_x;
505 *y = console_mouse_y;
506 *buttons = console_mouse_buttons;
507 *fb_nr = console_mouse_fb_nr;
514 static void console_slave_sigint(
int x)
520 if (write(console_slave_outputd, buf,
sizeof(buf)) !=
sizeof(buf))
521 perror(
"error writing to console handle");
524 signal(SIGINT, console_slave_sigint);
533 static void console_slave_sigcont(
int x)
536 tcsetattr(STDIN_FILENO, TCSANOW, &console_slave_tios);
539 signal(SIGCONT, console_slave_sigcont);
560 p = strchr(arg,
',');
562 printf(
"console_slave(): bad arg '%s'\n", arg);
566 console_slave_outputd = atoi(p+1);
569 tcgetattr(STDIN_FILENO, &console_slave_tios);
571 console_slave_tios.c_lflag &= ~ICANON;
572 console_slave_tios.c_cc[VTIME] = 0;
573 console_slave_tios.c_cc[VMIN] = 1;
574 console_slave_tios.c_lflag &= ~ECHO;
575 console_slave_tios.c_iflag &= ~ICRNL;
576 tcsetattr(STDIN_FILENO, TCSANOW, &console_slave_tios);
578 signal(SIGINT, console_slave_sigint);
579 signal(SIGCONT, console_slave_sigcont);
584 if (d_avail(inputd)) {
585 len = read(inputd, buf,
sizeof(buf) - 1);
593 if (d_avail(STDIN_FILENO)) {
594 len = read(STDIN_FILENO, buf,
sizeof(buf));
597 if (write(console_slave_outputd, buf, len) != len)
598 perror(
"error writing to console handle");
616 int i, n, found_free = -1;
619 n = n_console_handles;
621 if (!console_handles[i].
in_use) {
626 if (found_free == -1) {
630 realloc(console_handles,
sizeof(
632 found_free = n_console_handles;
633 n_console_handles ++;
636 chp = &console_handles[found_free];
643 *handlep = found_free;
679 if (
machine == NULL || consolename == NULL) {
680 printf(
"console_start_slave(): NULL ptr\n");
684 chp = console_new_handle(consolename, &handle);
725 if (
machine == NULL || consolename == NULL) {
726 printf(
"console_start_slave(): NULL ptr\n");
730 chp = console_new_handle(consolename, &handle);
756 if (handle < 0 || handle >= n_console_handles) {
757 fatal(
"console_change_inputability(): bad handle %i\n",
765 if (inputability != 0) {
769 fatal(
"%%\n%% WARNING! Input to console ha"
770 "ndle \"%s\" wasn't enabled,\n%% because "
771 "it", console_handles[handle].
name);
772 fatal(
" would interfere with other inputs,\n"
773 "%% and you did not use the -x command "
774 "line option!\n%%\n");
794 if (console_initialized)
797 tcgetattr(STDIN_FILENO, &console_oldtermios);
798 memcpy(&console_curtermios, &console_oldtermios,
799 sizeof (
struct termios));
801 console_curtermios.c_lflag &= ~ICANON;
802 console_curtermios.c_cc[VTIME] = 0;
803 console_curtermios.c_cc[VMIN] = 1;
805 console_curtermios.c_lflag &= ~ECHO;
821 console_curtermios.c_iflag &= ~ICRNL;
823 tcsetattr(STDIN_FILENO, TCSANOW, &console_curtermios);
825 console_stdout_pending = 1;
831 console_mouse_buttons = 0;
833 console_initialized = 1;
849 debug(
"console slaves (xterms): %s\n", allow_slaves?
852 debug(
"console handles:\n");
855 for (i=0; i<n_console_handles; i++) {
856 if (!console_handles[i].
in_use)
858 debug(
"%i: \"%s\"", i, console_handles[i].
name);
862 debug(
" [inputonly]");
864 debug(
" [outputonly]");
866 debug(
" [MAIN CONSOLE]");
875 fatal(
"WARNING! no main console handle?\n");
887 allow_slaves = allow;
925 if (console_handles[i].
in_use &&
932 fatal(
"#\n# ERROR! More than one console input is "
933 "in use,\n# but xterm slaves are not enabled.\n"
935 fatal(
"# Use -x to enable slave xterms.)\n#\n");
937 if (console_handles[i].
in_use &&
940 fatal(
"# console handle %i: '%s'\n",
941 i, console_handles[i].
name);
971 chp = console_new_handle(
"MAIN", &handle);
973 printf(
"console_init(): fatal error: could not create"
974 " console 0: handle = %i\n", handle);