|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * Interface to the Tcl/Tk GUI ! 5: * ! 6: * Copyright 1996 Bernd Schmidt ! 7: */ ! 8: ! 9: #include "sysconfig.h" ! 10: #include "sysdeps.h" ! 11: #include <signal.h> ! 12: ! 13: #include "config.h" ! 14: #include "options.h" ! 15: #include "memory.h" ! 16: #include "custom.h" ! 17: #include "newcpu.h" ! 18: #include "disk.h" ! 19: #include "gui.h" ! 20: ! 21: static int inpipe, outpipe; ! 22: static char *child_argv[4]; ! 23: static char filename1[80]; ! 24: static char filename2[80]; ! 25: static int made_file = 0; ! 26: static struct stat stbuf; ! 27: static pid_t child_pid; ! 28: static int child_died = 0; ! 29: ! 30: int quit_program; ! 31: ! 32: static void sigchldhandler(int foo) ! 33: { ! 34: child_died = 1; ! 35: } ! 36: ! 37: int gui_init(void) ! 38: { ! 39: struct timeval tv; ! 40: int result; ! 41: ! 42: quit_program = 0; ! 43: ! 44: gettimeofday(&tv, NULL); ! 45: sprintf(filename1, "/tmp/uaea%d", tv.tv_sec * 1000 + tv.tv_usec / 1000); ! 46: result = mknod (filename1, 0600 | S_IFIFO, 0); ! 47: if (result < 0) ! 48: return result; ! 49: made_file = 1; ! 50: ! 51: sprintf(filename2, "/tmp/uaeb%d", tv.tv_sec * 1000 + tv.tv_usec / 1000); ! 52: result = mknod (filename2, 0600 | S_IFIFO, 0); ! 53: if (result < 0) ! 54: return result; ! 55: made_file = 2; ! 56: ! 57: inpipe = open (filename1, O_RDONLY|O_NONBLOCK); ! 58: if (inpipe < 0) ! 59: return inpipe; ! 60: ! 61: /* Why doesn't O_WRONLY work? */ ! 62: outpipe = open (filename2, O_RDWR); ! 63: if (outpipe < 0) ! 64: return outpipe; ! 65: ! 66: fstat (inpipe, &stbuf); ! 67: child_pid = fork(); ! 68: if (child_pid < 0) ! 69: return child_pid; ! 70: if (child_pid > 0) { ! 71: fd_set fs; ! 72: printf("Waiting for GUI process to start...\n"); ! 73: FD_ZERO(&fs); ! 74: FD_SET(inpipe, &fs); ! 75: signal(SIGCHLD, sigchldhandler); ! 76: result = select(inpipe+1, &fs, NULL, NULL, NULL); ! 77: if (result < 0) { ! 78: kill(child_pid, SIGTERM); ! 79: return -1; ! 80: } else { ! 81: char buffer[20]; ! 82: fstat (inpipe, &stbuf); ! 83: if (stbuf.st_size != strlen("Startup")+1) { ! 84: kill(child_pid, SIGTERM); ! 85: return -1; ! 86: } ! 87: read (inpipe, buffer, 8); ! 88: if (strncmp("Startup\n", buffer, 8) != 0) { ! 89: kill(child_pid, SIGTERM); ! 90: return -1; ! 91: } ! 92: } ! 93: if (made_file > 0) ! 94: unlink(filename1); ! 95: if (made_file > 1) ! 96: unlink(filename2); ! 97: made_file = 0; ! 98: printf("OK.\n"); ! 99: return 0; ! 100: } ! 101: /* FIXME: how can I prevent that the child exits when I hit ^C in the ! 102: * shell window? */ ! 103: child_argv[0] = "uae-ui.tk"; ! 104: child_argv[1] = my_strdup(filename1); ! 105: child_argv[2] = my_strdup(filename2); ! 106: child_argv[3] = NULL; ! 107: execvp("uae-ui", child_argv); ! 108: /* Shouldn't get here */ ! 109: exit(0); ! 110: ! 111: } ! 112: ! 113: void gui_exit(void) ! 114: { ! 115: if (made_file > 0) ! 116: unlink(filename1); ! 117: if (made_file > 1) ! 118: unlink(filename2); ! 119: if (inpipe >= 0) ! 120: close(inpipe); ! 121: if (outpipe >= 0) ! 122: close(outpipe); ! 123: if (child_pid) ! 124: kill(child_pid, SIGTERM); ! 125: } ! 126: ! 127: void gui_led(int led, int on) ! 128: { ! 129: char line[80]; ! 130: ! 131: if (child_died || no_gui) ! 132: return; ! 133: ! 134: sprintf(line, "%s %d\n", led == 0 ? "power" : "driveled", on); ! 135: write(outpipe, line, strlen(line)); ! 136: if (led > 0) { ! 137: sprintf(line, "%d\n", led-1); ! 138: write(outpipe, line, strlen (line)); ! 139: } ! 140: } ! 141: ! 142: void gui_filename(int num, char *name) ! 143: { ! 144: char line[80]; ! 145: ! 146: if (child_died || no_gui) ! 147: return; ! 148: ! 149: sprintf(line, "drivename\n"); ! 150: write(outpipe, line, strlen(line)); ! 151: sprintf(line, "%d\n", num); ! 152: write(outpipe, line, strlen(line)); ! 153: sprintf(line, "%s\n", name); ! 154: write(outpipe, line, strlen(line)); ! 155: } ! 156: ! 157: static void getline(char *p) ! 158: { ! 159: int cnt = 80; ! 160: char buf; ! 161: do { ! 162: read(inpipe, &buf, 1); ! 163: *p++ = buf; ! 164: } while (--cnt && buf != '\n'); ! 165: *(p-1) = 0; ! 166: } ! 167: ! 168: void gui_handle_events(void) ! 169: { ! 170: char command[100]; ! 171: off_t oldsize = stbuf.st_size; ! 172: ! 173: if (child_died || no_gui) ! 174: return; ! 175: ! 176: fstat (inpipe, &stbuf); ! 177: if (stbuf.st_size > oldsize) { ! 178: getline(command); ! 179: if (strcmp (command, "eject") == 0) { ! 180: int drive; ! 181: getline(command); ! 182: drive = atoi(command); ! 183: disk_eject (drive); ! 184: } else if (strcmp (command, "insert") == 0) { ! 185: int drive; ! 186: getline(command); ! 187: drive = atoi(command); ! 188: if (disk_empty(drive)) { ! 189: fd_set fs; ! 190: FD_ZERO(&fs); ! 191: FD_SET(inpipe, &fs); ! 192: write(outpipe, "ok\n", 3); ! 193: select(inpipe+1, &fs, NULL, NULL, NULL); ! 194: getline(command); ! 195: disk_insert (drive, command); ! 196: } else ! 197: write(outpipe, "no\n", 3); ! 198: } else if (strcmp (command, "debug") == 0) { ! 199: activate_debugger(); ! 200: } else if (strcmp (command, "bye") == 0) { ! 201: broken_in = 1; ! 202: regs.spcflags |= SPCFLAG_BRK; ! 203: quit_program = 1; ! 204: } else if (strcmp (command, "reset") == 0) { ! 205: m68k_reset(); ! 206: } ! 207: ! 208: } ! 209: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.