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);
338 while (console_stdin_avail(handle)) {
339 unsigned char ch[100];
345 int roomLeftInFIFO = console_handles[handle].
fifo_tail - console_handles[handle].
fifo_head;
346 if (roomLeftInFIFO <= 0)
348 if (roomLeftInFIFO < (
int)
sizeof(ch) + 1)
356 len = read(d, ch,
sizeof(ch));
358 for (i=0; i<len; i++) {
372 if (console_handles[handle].fifo_head ==
373 console_handles[handle].fifo_tail)
392 ch = console_handles[handle].
fifo[console_handles[handle].
fifo_tail];
409 if (!console_handles[handle].in_use_for_input &&
410 !console_handles[handle].outputonly)
419 console_stdout_pending = 0;
421 console_stdout_pending = 1;
426 if (!console_handles[handle].in_use) {
427 printf(
"[ console_putchar(): handle %i not in"
428 " use! ]\n", handle);
432 if (console_handles[handle].using_xterm ==
437 if (write(console_handles[handle].w_descriptor, buf, 1) != 1)
438 perror(
"error writing to console handle");
449 if (console_stdout_pending)
452 console_stdout_pending = 0;
469 console_mouse_fb_nr = fb_nr;
482 int mask = 1 << (3-button);
485 console_mouse_buttons |= mask;
487 console_mouse_buttons &= ~mask;
499 *x = console_mouse_x;
500 *y = console_mouse_y;
501 *buttons = console_mouse_buttons;
502 *fb_nr = console_mouse_fb_nr;
509 static void console_slave_sigint(
int x)
515 if (write(console_slave_outputd, buf,
sizeof(buf)) !=
sizeof(buf))
516 perror(
"error writing to console handle");
519 signal(SIGINT, console_slave_sigint);
528 static void console_slave_sigcont(
int x)
531 tcsetattr(STDIN_FILENO, TCSANOW, &console_slave_tios);
534 signal(SIGCONT, console_slave_sigcont);
555 p = strchr(arg,
',');
557 printf(
"console_slave(): bad arg '%s'\n", arg);
561 console_slave_outputd = atoi(p+1);
564 tcgetattr(STDIN_FILENO, &console_slave_tios);
566 console_slave_tios.c_lflag &= ~ICANON;
567 console_slave_tios.c_cc[VTIME] = 0;
568 console_slave_tios.c_cc[VMIN] = 1;
569 console_slave_tios.c_lflag &= ~ECHO;
570 console_slave_tios.c_iflag &= ~ICRNL;
571 tcsetattr(STDIN_FILENO, TCSANOW, &console_slave_tios);
573 signal(SIGINT, console_slave_sigint);
574 signal(SIGCONT, console_slave_sigcont);
579 if (d_avail(inputd)) {
580 len = read(inputd, buf,
sizeof(buf) - 1);
588 if (d_avail(STDIN_FILENO)) {
589 len = read(STDIN_FILENO, buf,
sizeof(buf));
592 if (write(console_slave_outputd, buf, len) != len)
593 perror(
"error writing to console handle");
611 int i, n, found_free = -1;
614 n = n_console_handles;
616 if (!console_handles[i].
in_use) {
621 if (found_free == -1) {
625 realloc(console_handles,
sizeof(
627 found_free = n_console_handles;
628 n_console_handles ++;
631 chp = &console_handles[found_free];
638 *handlep = found_free;
674 if (
machine == NULL || consolename == NULL) {
675 printf(
"console_start_slave(): NULL ptr\n");
679 chp = console_new_handle(consolename, &handle);
720 if (
machine == NULL || consolename == NULL) {
721 printf(
"console_start_slave(): NULL ptr\n");
725 chp = console_new_handle(consolename, &handle);
751 if (handle < 0 || handle >= n_console_handles) {
752 fatal(
"console_change_inputability(): bad handle %i\n",
760 if (inputability != 0) {
764 fatal(
"%%\n%% WARNING! Input to console ha"
765 "ndle \"%s\" wasn't enabled,\n%% because "
766 "it", console_handles[handle].
name);
767 fatal(
" would interfere with other inputs,\n"
768 "%% and you did not use the -x command "
769 "line option!\n%%\n");
789 if (console_initialized)
792 tcgetattr(STDIN_FILENO, &console_oldtermios);
793 memcpy(&console_curtermios, &console_oldtermios,
794 sizeof (
struct termios));
796 console_curtermios.c_lflag &= ~ICANON;
797 console_curtermios.c_cc[VTIME] = 0;
798 console_curtermios.c_cc[VMIN] = 1;
800 console_curtermios.c_lflag &= ~ECHO;
816 console_curtermios.c_iflag &= ~ICRNL;
818 tcsetattr(STDIN_FILENO, TCSANOW, &console_curtermios);
820 console_stdout_pending = 1;
826 console_mouse_buttons = 0;
828 console_initialized = 1;
844 debug(
"console slaves (xterms): %s\n", allow_slaves?
847 debug(
"console handles:\n");
850 for (i=0; i<n_console_handles; i++) {
851 if (!console_handles[i].
in_use)
853 debug(
"%i: \"%s\"", i, console_handles[i].
name);
857 debug(
" [inputonly]");
859 debug(
" [outputonly]");
861 debug(
" [MAIN CONSOLE]");
870 fatal(
"WARNING! no main console handle?\n");
882 allow_slaves = allow;
920 if (console_handles[i].
in_use &&
927 fatal(
"#\n# ERROR! More than one console input is "
928 "in use,\n# but xterm slaves are not enabled.\n"
930 fatal(
"# Use -x to enable slave xterms.)\n#\n");
932 if (console_handles[i].
in_use &&
935 fatal(
"# console handle %i: '%s'\n",
936 i, console_handles[i].
name);
966 chp = console_new_handle(
"MAIN", &handle);
968 printf(
"console_init(): fatal error: could not create"
969 " console 0: handle = %i\n", handle);