]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/winwatch.c
libtags, zuke: add *.mod support (thanks kemal)
[plan9front.git] / sys / src / cmd / winwatch.c
index a76d15efaaebfcf7b826fc05109f0039c41d4b50..1f88dc541495281987aa399adaf9a954c378a004 100644 (file)
@@ -1,19 +1,25 @@
 #include <u.h>
 #include <libc.h>
 #include <draw.h>
+#include <cursor.h>
 #include <event.h>
 #include <regexp.h>
+#include <keyboard.h>
+
+enum {
+       VISIBLE = 1,
+       CURRENT = 2,
+};
 
 typedef struct Win Win;
 struct Win {
        int n;
        int dirty;
+       int state;
        char *label;
        Rectangle r;
 };
 
-
-
 Reprog  *exclude  = nil;
 Win *win;
 int nwin;
@@ -21,6 +27,7 @@ int mwin;
 int onwin;
 int rows, cols;
 Image *lightblue;
+Image *statecol[4];
 
 enum {
        PAD = 3,
@@ -63,14 +70,43 @@ estrdup(char *s)
        return t;
 }
 
+int
+readfile(char *buf, int nbuf, char *file, ...)
+{
+       va_list arg;
+       int n, fd;
+
+       va_start(arg, file);
+       vsnprint(buf, nbuf, file, arg);
+       va_end(arg);
+
+       if((fd = open(buf, OREAD)) < 0){
+               buf[0] = 0;
+               return -1;
+       }
+       n = read(fd, buf, nbuf-1);
+       close(fd);
+       if(n < 0){
+               buf[0] = 0;
+               return -1;
+       }
+       buf[n] = 0;
+       return n;
+}
 
 void
 refreshwin(void)
 {
-       char label[128];
-       int i, fd, lfd, n, nr, nw, m;
+       char label[128], wctl[128], *tok[8];
+       int i, fd, n, nr, nw, state;
+       static int mywinid = -1;
        Dir *pd;
 
+       if(mywinid < 0){
+               if(readfile(wctl, sizeof(wctl), "/dev/winid") > 0)
+                       mywinid = atoi(wctl);
+       }
+
        if((fd = open("/dev/wsys", OREAD)) < 0)
                return;
 
@@ -79,18 +115,23 @@ refreshwin(void)
        while((nr=dirread(fd, &pd)) > 0){
                for(i=0; i<nr; i++){
                        n = atoi(pd[i].name);
-                       sprint(label, "/dev/wsys/%d/label", n);
-                       if((lfd = open(label, OREAD)) < 0)
+                       if(n == mywinid)
                                continue;
-                       m = read(lfd, label, sizeof(label)-1);
-                       close(lfd);
-                       if(m < 0)
+                       if(readfile(label, sizeof(label), "/dev/wsys/%d/label", n) < 0)
                                continue;
-                       label[m] = '\0';
                        if(exclude != nil && regexec(exclude,label,nil,0))
                                continue;
-
-                       if(nw < nwin && win[nw].n == n && strcmp(win[nw].label, label)==0){
+                       if(readfile(wctl, sizeof(wctl), "/dev/wsys/%d/wctl", n) <= 0)
+                               continue;
+                       if(tokenize(wctl, tok, nelem(tok)) != 6)
+                               continue;
+                       state = 0;
+                       if(strcmp(tok[4], "current") == 0)
+                               state |= CURRENT;
+                       if(strcmp(tok[5], "visible") == 0)
+                               state |= VISIBLE;
+                       if(nw < nwin && win[nw].n == n && win[nw].state == state && 
+                          strcmp(win[nw].label, label)==0){
                                nw++;
                                continue;
                        }
@@ -106,6 +147,7 @@ refreshwin(void)
                        }
                        win[nw].n = n;
                        win[nw].label = estrdup(label);
+                       win[nw].state = state;
                        win[nw].dirty = 1;
                        win[nw].r = Rect(0,0,0,0);
                        nw++;
@@ -132,7 +174,7 @@ drawnowin(int i)
 void
 drawwin(int i)
 {
-       draw(screen, win[i].r, lightblue, nil, ZP);
+       draw(screen, win[i].r, statecol[win[i].state], nil, ZP);
        _string(screen, addpt(win[i].r.min, Pt(2,0)), display->black, ZP,
                font, win[i].label, nil, strlen(win[i].label), 
                win[i].r, nil, ZP, SoverD);
@@ -143,17 +185,21 @@ drawwin(int i)
 int
 geometry(void)
 {
-       int i, ncols, z;
+       int i, nrows, ncols, z;
        Rectangle r;
 
        z = 0;
-       rows = (Dy(screen->r)-2*MARGIN+PAD)/(font->height+PAD);
-       if(rows*cols < nwin || rows*cols >= nwin*2){
-               ncols = nwin <= 0 ? 1 : (nwin+rows-1)/rows;
-               if(ncols != cols){
-                       cols = ncols;
-                       z = 1;
-               }
+       nrows = (Dy(screen->r)-2*MARGIN+PAD)/(font->height+PAD);
+       if(nrows <= 0)
+               nrows = 1;
+       if(nrows != rows){
+               rows = nrows;
+               z = 1;
+       }
+       ncols = nwin <= 0 ? 1 : (nwin+rows-1)/rows;
+       if(ncols != cols){
+               cols = ncols;
+               z = 1;
        }
 
        r = Rect(0,0,(Dx(screen->r)-2*MARGIN+PAD)/cols-PAD, font->height);
@@ -191,45 +237,73 @@ eresized(int new)
        redraw(screen, 1);
 }
 
-void
-click(Mouse m)
+int
+label(Win w, Mouse m)
+{
+       char buf[512], fname[128];
+       int n, fd;
+
+       snprint(buf, sizeof(buf), "%s", w.label);
+       n = eenter(nil, buf, sizeof(buf), &m);
+       if(n <= 0)
+               return 0;
+       sprint(fname, "/dev/wsys/%d/label", w.n);
+       if((fd = open(fname, OWRITE)) < 0)
+               return 0;
+       write(fd, buf, n);
+       close(fd);
+       refreshwin();
+       redraw(screen, 1);
+       return 1;
+}
+
+int
+unhide(Win w)
 {
-       int fd, i, j;   
        char buf[128];
+       int fd;
 
-       if(m.buttons == 0 || (m.buttons & ~4))
-               return;
+       sprint(buf, "/dev/wsys/%d/wctl", w.n);
+       if((fd = open(buf, OWRITE)) < 0)
+               return 0;
+       if(w.state == (CURRENT|VISIBLE))
+               write(fd, "hide\n", 5);
+       else {
+               write(fd, "unhide\n", 7);
+               write(fd, "top\n", 4);
+               write(fd, "current\n", 8);
+       }
+       close(fd);
+       return 1;
+}
 
+int
+click(Mouse m)
+{
+       int i, b;
+
+       b = m.buttons & 7;
+       if(b != 2 && b != 4)
+               return 0;
        for(i=0; i<nwin; i++)
                if(ptinrect(m.xy, win[i].r))
                        break;
        if(i == nwin)
-               return;
-
+               return 0;
        do
                m = emouse();
-       while(m.buttons == 4);
-
-       if(m.buttons != 0){
-               do
-                       m = emouse();
-               while(m.buttons);
-               return;
+       while((m.buttons & 7) == b);
+       if((m.buttons & 7) || !ptinrect(m.xy, win[i].r))
+               return 0;
+
+       switch(b) {
+       case 2:
+               return label(win[i], m);
+       case 4:
+               return unhide(win[i]);
+       default:
+               return 0;
        }
-
-       for(j=0; j<nwin; j++)
-               if(ptinrect(m.xy, win[j].r))
-                       break;
-       if(j != i)
-               return;
-
-       sprint(buf, "/dev/wsys/%d/wctl", win[i].n);
-       if((fd = open(buf, OWRITE)) < 0)
-               return;
-       write(fd, "unhide\n", 7);
-       write(fd, "top\n", 4);
-       write(fd, "current\n", 8);
-       close(fd);
 }
 
 void
@@ -245,6 +319,7 @@ main(int argc, char **argv)
        char *fontname = nil;
        int Etimer;
        Event e;
+       int i;
 
        ARGBEGIN{
        case 'f':
@@ -262,14 +337,18 @@ main(int argc, char **argv)
        if(argc)
                usage();
 
-       initdraw(0, 0, "winwatch");
+       if(initdraw(0, fontname, "winwatch") < 0)
+               sysfatal("initdraw: %r");
        lightblue = allocimagemix(display, DPalebluegreen, DWhite);
-       if(lightblue == nil)
-               sysfatal("allocimagemix: %r");
 
-       if(fontname)
-               if((font = openfont(display, fontname)) == nil)
-                       sysfatal("font '%s' not found", fontname);
+       statecol[0] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xCCCCCCFF);
+       statecol[1] = lightblue;
+       statecol[2] = lightblue;
+       statecol[3] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPalegreygreen);
+
+       for(i=0; i<nelem(statecol); i++)
+               if(statecol[i] == nil)
+                       sysfatal("allocimage: %r");
 
        refreshwin();
        redraw(screen, 1);
@@ -279,12 +358,12 @@ main(int argc, char **argv)
        for(;;){
                switch(eread(Emouse|Ekeyboard|Etimer, &e)){
                case Ekeyboard:
-                       if(e.kbdc==0x7F || e.kbdc=='q')
+                       if(e.kbdc==Kdel || e.kbdc=='q')
                                exits(0);
                        break;
                case Emouse:
-                       if(e.mouse.buttons)
-                               click(e.mouse);
+                       if(click(e.mouse) == 0)
+                               continue;
                        /* fall through  */
                default:        /* Etimer */
                        refreshwin();