home *** CD-ROM | disk | FTP | other *** search
- /*
- * UAE - The Un*x Amiga Emulator
- *
- * Interface to the Tcl/Tk GUI
- *
- * Copyright 1996 Bernd Schmidt
- */
-
- #include "sysconfig.h"
- #include "sysdeps.h"
- #include <signal.h>
-
- #include "config.h"
- #include "options.h"
- #include "memory.h"
- #include "custom.h"
- #include "newcpu.h"
- #include "disk.h"
- #include "gui.h"
-
- static int inpipe, outpipe;
- static char *child_argv[4];
- static char filename1[80];
- static char filename2[80];
- static int made_file = 0;
- static struct stat stbuf;
- static pid_t child_pid;
- static int child_died = 0;
-
- int quit_program;
-
- static void sigchldhandler(int foo)
- {
- child_died = 1;
- }
-
- int gui_init(void)
- {
- struct timeval tv;
- int result;
-
- quit_program = 0;
-
- gettimeofday(&tv, NULL);
- sprintf(filename1, "/tmp/uaea%d", tv.tv_sec * 1000 + tv.tv_usec / 1000);
- result = mknod (filename1, 0600 | S_IFIFO, 0);
- if (result < 0)
- return result;
- made_file = 1;
-
- sprintf(filename2, "/tmp/uaeb%d", tv.tv_sec * 1000 + tv.tv_usec / 1000);
- result = mknod (filename2, 0600 | S_IFIFO, 0);
- if (result < 0)
- return result;
- made_file = 2;
-
- inpipe = open (filename1, O_RDONLY|O_NONBLOCK);
- if (inpipe < 0)
- return inpipe;
-
- /* Why doesn't O_WRONLY work? */
- outpipe = open (filename2, O_RDWR);
- if (outpipe < 0)
- return outpipe;
-
- fstat (inpipe, &stbuf);
- child_pid = fork();
- if (child_pid < 0)
- return child_pid;
- if (child_pid > 0) {
- fd_set fs;
- printf("Waiting for GUI process to start...\n");
- FD_ZERO(&fs);
- FD_SET(inpipe, &fs);
- signal(SIGCHLD, sigchldhandler);
- result = select(inpipe+1, &fs, NULL, NULL, NULL);
- if (result < 0) {
- kill(child_pid, SIGTERM);
- return -1;
- } else {
- char buffer[20];
- fstat (inpipe, &stbuf);
- if (stbuf.st_size != strlen("Startup")+1) {
- kill(child_pid, SIGTERM);
- return -1;
- }
- read (inpipe, buffer, 8);
- if (strncmp("Startup\n", buffer, 8) != 0) {
- kill(child_pid, SIGTERM);
- return -1;
- }
- }
- printf("OK.\n");
- return 0;
- }
- /* FIXME: how can I prevent that the child exits when I hit ^C in the
- * shell window? */
- child_argv[0] = "uae-ui.tk";
- child_argv[1] = my_strdup(filename1);
- child_argv[2] = my_strdup(filename2);
- child_argv[3] = NULL;
- execvp("uae-ui", child_argv);
- /* Shouldn't get here */
- exit(0);
-
- }
-
- void gui_exit(void)
- {
- if (inpipe >= 0)
- close(inpipe);
- if (outpipe >= 0)
- close(outpipe);
- if (made_file > 0)
- unlink(filename1);
- if (made_file > 1)
- unlink(filename2);
- if (child_pid)
- kill(child_pid, SIGTERM);
- }
-
- void gui_led(int led, int on)
- {
- char line[80];
- sprintf(line, "%s %d\n", led == 0 ? "power" : "driveled", on);
- write(outpipe, line, strlen(line));
- if (led > 0) {
- sprintf(line, "%d\n", led-1);
- write(outpipe, line, strlen (line));
- }
- }
-
- void gui_filename(int num, char *name)
- {
- char line[80];
- sprintf(line, "drivename\n");
- write(outpipe, line, strlen(line));
- sprintf(line, "%d\n", num);
- write(outpipe, line, strlen(line));
- sprintf(line, "%s\n", name);
- write(outpipe, line, strlen(line));
- }
-
- static void getline(char *p)
- {
- int cnt = 80;
- char buf;
- do {
- read(inpipe, &buf, 1);
- *p++ = buf;
- } while (--cnt && buf != '\n');
- *(p-1) = 0;
- }
-
- void gui_handle_events(void)
- {
- char command[100];
- off_t oldsize = stbuf.st_size;
- fstat (inpipe, &stbuf);
- if (stbuf.st_size > oldsize) {
- getline(command);
- if (strcmp (command, "eject") == 0) {
- int drive;
- getline(command);
- drive = atoi(command);
- disk_eject (drive);
- } else if (strcmp (command, "insert") == 0) {
- int drive;
- getline(command);
- drive = atoi(command);
- if (disk_empty(drive)) {
- fd_set fs;
- FD_ZERO(&fs);
- FD_SET(inpipe, &fs);
- write(outpipe, "ok\n", 3);
- select(inpipe+1, &fs, NULL, NULL, NULL);
- getline(command);
- disk_insert (drive, command);
- } else
- write(outpipe, "no\n", 3);
- } else if (strcmp (command, "debug") == 0) {
- broken_in = 1;
- specialflags |= SPCFLAG_BRK;
- } else if (strcmp (command, "bye") == 0) {
- broken_in = 1;
- specialflags |= SPCFLAG_BRK;
- quit_program = 1;
- } else if (strcmp (command, "reset") == 0) {
- MC68000_reset();
- }
-
- }
- }
-