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