|
|
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.