|
|
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: printf("OK.\n");
94: return 0;
95: }
96: /* FIXME: how can I prevent that the child exits when I hit ^C in the
97: * shell window? */
98: child_argv[0] = "uae-ui.tk";
99: child_argv[1] = my_strdup(filename1);
100: child_argv[2] = my_strdup(filename2);
101: child_argv[3] = NULL;
102: execvp("uae-ui", child_argv);
103: /* Shouldn't get here */
104: exit(0);
105:
106: }
107:
108: void gui_exit(void)
109: {
110: if (inpipe >= 0)
111: close(inpipe);
112: if (outpipe >= 0)
113: close(outpipe);
114: if (made_file > 0)
115: unlink(filename1);
116: if (made_file > 1)
117: unlink(filename2);
118: if (child_pid)
119: kill(child_pid, SIGTERM);
120: }
121:
122: void gui_led(int led, int on)
123: {
124: char line[80];
125: sprintf(line, "%s %d\n", led == 0 ? "power" : "driveled", on);
126: write(outpipe, line, strlen(line));
127: if (led > 0) {
128: sprintf(line, "%d\n", led-1);
129: write(outpipe, line, strlen (line));
130: }
131: }
132:
133: void gui_filename(int num, char *name)
134: {
135: char line[80];
136: sprintf(line, "drivename\n");
137: write(outpipe, line, strlen(line));
138: sprintf(line, "%d\n", num);
139: write(outpipe, line, strlen(line));
140: sprintf(line, "%s\n", name);
141: write(outpipe, line, strlen(line));
142: }
143:
144: static void getline(char *p)
145: {
146: int cnt = 80;
147: char buf;
148: do {
149: read(inpipe, &buf, 1);
150: *p++ = buf;
151: } while (--cnt && buf != '\n');
152: *(p-1) = 0;
153: }
154:
155: void gui_handle_events(void)
156: {
157: char command[100];
158: off_t oldsize = stbuf.st_size;
159: fstat (inpipe, &stbuf);
160: if (stbuf.st_size > oldsize) {
161: getline(command);
162: if (strcmp (command, "eject") == 0) {
163: int drive;
164: getline(command);
165: drive = atoi(command);
166: disk_eject (drive);
167: } else if (strcmp (command, "insert") == 0) {
168: int drive;
169: getline(command);
170: drive = atoi(command);
171: if (disk_empty(drive)) {
172: fd_set fs;
173: FD_ZERO(&fs);
174: FD_SET(inpipe, &fs);
175: write(outpipe, "ok\n", 3);
176: select(inpipe+1, &fs, NULL, NULL, NULL);
177: getline(command);
178: disk_insert (drive, command);
179: } else
180: write(outpipe, "no\n", 3);
181: } else if (strcmp (command, "debug") == 0) {
182: broken_in = 1;
183: specialflags |= SPCFLAG_BRK;
184: } else if (strcmp (command, "bye") == 0) {
185: broken_in = 1;
186: specialflags |= SPCFLAG_BRK;
187: quit_program = 1;
188: } else if (strcmp (command, "reset") == 0) {
189: MC68000_reset();
190: }
191:
192: }
193: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.