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",
218 console_handles[handle].machine_name,
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[
305 fatal(
"[ WARNING: console fifo overrun, handle %i ]\n", handle);
315 static int console_stdin_avail(
int handle)
321 return d_avail(STDIN_FILENO);
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++) {
392 ch = console_handles[handle].
fifo[console_handles[handle].
fifo_tail];
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);
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);
729 if (machine->
name != NULL) {
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 &&
934 !console_handles[i].using_xterm)
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);
void fatal(const char *fmt,...)
int console_start_slave_inputonly(struct machine *machine, const char *consolename, int use_for_input)
#define DEBUG_INDENTATION
void console_getmouse(int *x, int *y, int *buttons, int *fb_nr)
#define SETTINGS_FORMAT_YESNO
struct settings * settings_new(void)
unsigned char fifo[CONSOLE_FIFO_LEN]
void console_init_main(struct emul *emul)
int console_warn_if_slaves_are_needed(int init)
int console_are_slaves_allowed(void)
void console_makeavail(int handle, char ch)
void console_putchar(int handle, int ch)
int console_readchar(int handle)
void console_sigcont(int x)
void console_mouse_coordinates(int x, int y, int fb_nr)
void console_mouse_button(int button, int pressed)
#define CHECK_ALLOCATION(ptr)
void console_slave(const char *arg)
int console_charavail(int handle)
struct settings * global_settings
int console_change_inputability(int handle, int inputability)
void settings_remove(struct settings *settings, const char *name)
void console_allow_slaves(int allow)
#define SETTINGS_TYPE_SUBSETTINGS
void console_deinit_main(void)
void COMBINE() strlen(struct cpu *cpu, struct arm_instr_call *ic, int low_addr)
void console_deinit(void)
void debug_indentation(int diff)
int console_start_slave(struct machine *machine, const char *consolename, int use_for_input)
void settings_add(struct settings *settings, const char *name, int writable, int type, int format, void *ptr)
struct machine ** machines
#define SETTINGS_TYPE_INT
void console_debug_dump(struct machine *machine)
#define USING_XTERM_BUT_NOT_YET_OPEN
const char * machine_name
#define CONSOLE_OUTPUT_ONLY