123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- #include <u.h>
- #include <libc.h>
- #include <draw.h>
- #include <thread.h>
- #include <mouse.h>
- #include <keyboard.h>
- #include <frame.h>
- #include <plumb.h>
- #include "flayer.h"
- #include "samterm.h"
- static char exname[64];
- void
- getscreen(int argc, char **argv)
- {
- char *t;
- USED(argc);
- USED(argv);
- if(initdraw(panic1, nil, "sam") < 0){
- fprint(2, "samterm: initimage: %r\n");
- threadexitsall("init");
- }
- t = getenv("tabstop");
- if(t != nil)
- maxtab = strtoul(t, nil, 0);
- draw(screen, screen->clipr, display->white, nil, ZP);
- }
- int
- screensize(int *w, int *h)
- {
- int fd, n;
- char buf[5*12+1];
- fd = open("/dev/screen", OREAD);
- if(fd < 0)
- return 0;
- n = read(fd, buf, sizeof(buf)-1);
- close(fd);
- if (n != sizeof(buf)-1)
- return 0;
- buf[n] = 0;
- if (h) {
- *h = atoi(buf+4*12)-atoi(buf+2*12);
- if (*h < 0)
- return 0;
- }
- if (w) {
- *w = atoi(buf+3*12)-atoi(buf+1*12);
- if (*w < 0)
- return 0;
- }
- return 1;
- }
- int
- snarfswap(char *fromsam, int nc, char **tosam)
- {
- char *s1;
- int f, n, ss;
- f = open("/dev/snarf", 0);
- if(f < 0)
- return -1;
- ss = SNARFSIZE;
- if(hversion < 2)
- ss = 4096;
- *tosam = s1 = alloc(ss);
- n = read(f, s1, ss-1);
- close(f);
- if(n < 0)
- n = 0;
- if (n == 0) {
- *tosam = 0;
- free(s1);
- } else
- s1[n] = 0;
- f = create("/dev/snarf", 1, 0666);
- if(f >= 0){
- write(f, fromsam, nc);
- close(f);
- }
- return n;
- }
- void
- dumperrmsg(int count, int type, int count0, int c)
- {
- fprint(2, "samterm: host mesg: count %d %ux %ux %ux %s...ignored\n",
- count, type, count0, c, rcvstring());
- }
- void
- removeextern(void)
- {
- remove(exname);
- }
- Readbuf hostbuf[2];
- Readbuf plumbbuf[2];
- void
- extproc(void *argv)
- {
- Channel *c;
- int i, n, which, *fdp;
- void **arg;
- arg = argv;
- c = arg[0];
- fdp = arg[1];
- i = 0;
- for(;;){
- i = 1-i; /* toggle */
- n = read(*fdp, plumbbuf[i].data, sizeof plumbbuf[i].data);
- if(n <= 0){
- fprint(2, "samterm: extern read error: %r\n");
- threadexits("extern"); /* not a fatal error */
- }
- plumbbuf[i].n = n;
- which = i;
- send(c, &which);
- }
- }
- void
- extstart(void)
- {
- char buf[32];
- int fd;
- static int p[2];
- static void *arg[2];
- if(pipe(p) < 0)
- return;
- sprint(exname, "/srv/sam.%s", getuser());
- fd = create(exname, 1, 0600);
- if(fd < 0){ /* assume existing guy is more important */
- Err:
- close(p[0]);
- close(p[1]);
- return;
- }
- sprint(buf, "%d", p[0]);
- if(write(fd, buf, strlen(buf)) <= 0)
- goto Err;
- close(fd);
- /*
- * leave p[0] open so if the file is removed the event
- * library won't get an error
- */
- plumbc = chancreate(sizeof(int), 0);
- arg[0] = plumbc;
- arg[1] = &p[1];
- proccreate(extproc, arg, 1024);
- atexit(removeextern);
- }
- int
- plumbformat(int i)
- {
- Plumbmsg *m;
- char *addr, *data, *act;
- int n;
- data = (char*)plumbbuf[i].data;
- m = plumbunpack(data, plumbbuf[i].n);
- if(m == nil)
- return 0;
- n = m->ndata;
- if(n == 0){
- plumbfree(m);
- return 0;
- }
- act = plumblookup(m->attr, "action");
- if(act!=nil && strcmp(act, "showfile")!=0){
- /* can't handle other cases yet */
- plumbfree(m);
- return 0;
- }
- addr = plumblookup(m->attr, "addr");
- if(addr){
- if(addr[0] == '\0')
- addr = nil;
- else
- addr = strdup(addr); /* copy to safe storage; we'll overwrite data */
- }
- memmove(data, "B ", 2); /* we know there's enough room for this */
- memmove(data+2, m->data, n);
- n += 2;
- if(data[n-1] != '\n')
- data[n++] = '\n';
- if(addr != nil){
- if(n+strlen(addr)+1+1 <= READBUFSIZE)
- n += sprint(data+n, "%s\n", addr);
- free(addr);
- }
- plumbbuf[i].n = n;
- plumbfree(m);
- return 1;
- }
- void
- plumbproc(void *argv)
- {
- Channel *c;
- int i, n, which, *fdp;
- void **arg;
- arg = argv;
- c = arg[0];
- fdp = arg[1];
- i = 0;
- for(;;){
- i = 1-i; /* toggle */
- n = read(*fdp, plumbbuf[i].data, READBUFSIZE);
- if(n <= 0){
- fprint(2, "samterm: plumb read error: %r\n");
- threadexits("plumb"); /* not a fatal error */
- }
- plumbbuf[i].n = n;
- if(plumbformat(i)){
- which = i;
- send(c, &which);
- }
- }
- }
- int
- plumbstart(void)
- {
- static int fd;
- static void *arg[2];
- plumbfd = plumbopen("send", OWRITE|OCEXEC); /* not open is ok */
- fd = plumbopen("edit", OREAD|OCEXEC);
- if(fd < 0)
- return -1;
- plumbc = chancreate(sizeof(int), 0);
- if(plumbc == nil){
- close(fd);
- return -1;
- }
- arg[0] =plumbc;
- arg[1] = &fd;
- proccreate(plumbproc, arg, 4096);
- return 1;
- }
- void
- hostproc(void *arg)
- {
- Channel *c;
- int i, n, which;
- c = arg;
- i = 0;
- for(;;){
- i = 1-i; /* toggle */
- n = read(0, hostbuf[i].data, sizeof hostbuf[i].data);
- if(n <= 0){
- fprint(2, "samterm: host read error: %r\n");
- threadexitsall("host");
- }
- hostbuf[i].n = n;
- which = i;
- send(c, &which);
- }
- }
- void
- hoststart(void)
- {
- hostc = chancreate(sizeof(int), 0);
- proccreate(hostproc, hostc, 1024);
- }
|