URI: 
       tscreen.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tscreen.c (6692B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <draw.h>
            4 #include <cursor.h>
            5 #include <event.h>
            6 #include <bio.h>
            7 #include "proof.h"
            8 
            9 static        int        checkmouse(void);
           10 /* static        int        buttondown(void); */
           11 static        char        *getmousestr(void);
           12 static        char        *getkbdstr(int);
           13 
           14 extern        Cursor        blot;
           15 extern        char        *track;
           16 
           17 Mouse        mouse;
           18 
           19 void
           20 mapscreen(void)
           21 {
           22         if(initdraw(0, 0, "proof") < 0){
           23                 fprint(2, "proof: initdraw failed: %r\n");
           24                 exits("initdraw");
           25         }
           26         einit(Ekeyboard|Emouse);
           27 }
           28 
           29 void
           30 clearscreen(void)
           31 {
           32         draw(screen, screen->r, display->black, nil, ZP);
           33 }
           34 
           35 void
           36 screenprint(char *fmt, ...)
           37 {
           38         char buf[100];
           39         Point p;
           40         va_list args;
           41 
           42         va_start(args, fmt);
           43         vseprint(buf, &buf[sizeof buf], fmt, args);
           44         va_end(args);
           45         p = Pt(screen->clipr.min.x+40, screen->clipr.max.y-40);
           46         string(screen, p, display->black, ZP, font, buf);
           47 }
           48 
           49 #define        Viewkey        0xb2
           50 #define etimer(x, y) 0
           51 
           52 char *
           53 getcmdstr(void)
           54 {
           55         Event ev;
           56         int e;
           57         static ulong timekey = 0;
           58         ulong tracktm = 0;
           59         Dir *dir;
           60 
           61         if(track){
           62                 if(timekey == 0)
           63                         timekey = etimer(0, 5000);
           64                 dir = dirstat(track);
           65                 if(dir != nil){
           66                         tracktm = dir->mtime;
           67                         free(dir);
           68                 }
           69         }
           70         for (;;) {
           71                 e = event(&ev);
           72                 if(resized){
           73                         resized = 0;
           74                         return "p";
           75                 }
           76                 if ((e & Emouse) && ev.mouse.buttons) {
           77                         mouse = ev.mouse;
           78                         return getmousestr();
           79                 } else if (e & Ekeyboard)
           80                         return getkbdstr(ev.kbdc);        /* sadly, no way to unget */
           81                 else if (e & timekey) {
           82                         if((dir = dirstat(track)) != nil){
           83                                 if(tracktm < dir->mtime){
           84                                         free(dir);
           85                                         return "q";
           86                                 }
           87                                 free(dir);
           88                         }
           89                 }
           90         }
           91 }
           92 
           93 static char *
           94 getkbdstr(int c0)
           95 {
           96         static char buf[100];
           97         char *p;
           98         int c;
           99 
          100         if (c0 == '\n')
          101                 return "";
          102         buf[0] = c0;
          103         buf[1] = 0;
          104         screenprint("%s", buf);
          105         for (p = buf+1; (c = ekbd()) != '\n' && c != '\r' && c != -1 && c != Viewkey; ) {
          106                 if (c == '\b' && p > buf) {
          107                         *--p = ' ';
          108                 } else {
          109                         *p++ = c;
          110                         *p = 0;
          111                 }
          112                 screenprint("%s", buf);
          113         }
          114         *p = 0;
          115         return buf;
          116 }
          117 
          118 
          119 #define button3(b)        ((b) & 4)
          120 #define button2(b)        ((b) & 2)
          121 #define button1(b)        ((b) & 1)
          122 #define button23(b)        ((b) & 6)
          123 #define button123(b)        ((b) & 7)
          124 
          125 #define        butcvt(b)        (1 << ((b) - 1))
          126 
          127 #if 0
          128 static int buttondown(void)        /* report state of buttons, if any */
          129 {
          130         if (!ecanmouse())        /* no event pending */
          131                 return 0;
          132         mouse = emouse();        /* something, but it could be motion */
          133         return mouse.buttons & 7;
          134 }
          135 #endif
          136 
          137 int waitdown(void)        /* wait until some button is down */
          138 {
          139         while (!(mouse.buttons & 7))
          140                 mouse = emouse();
          141         return mouse.buttons & 7;
          142 }
          143 
          144 int waitup(void)
          145 {
          146         while (mouse.buttons & 7)
          147                 mouse = emouse();
          148         return mouse.buttons & 7;
          149 }
          150 
          151 char *m3[]        = { "next", "prev", "page n", "again", "bigger", "smaller", "pan", "quit?", 0 };
          152 char *m2[]        = { 0 };
          153 
          154 enum { Next = 0, Prev, Page, Again, Bigger, Smaller, Pan, Quit };
          155 
          156 Menu        mbut3        = { m3, 0, 0 };
          157 Menu        mbut2        = { m2, 0, 0 };
          158 
          159 int        last_hit;
          160 int        last_but;
          161 
          162 char *pan(void)
          163 {
          164         Point dd, xy, lastxy, min, max;
          165 
          166         esetcursor(&blot);
          167         waitdown();
          168         xy = mouse.xy;
          169         do{
          170                 lastxy = mouse.xy;
          171                 mouse = emouse();
          172                 dd = subpt(mouse.xy, lastxy);
          173                 min = addpt(screen->clipr.min, dd);
          174                 max = addpt(screen->clipr.max, dd);
          175                 draw(screen, rectaddpt(screen->r, subpt(mouse.xy, lastxy)),
          176                         screen, nil, screen->r.min);
          177                 if(mouse.xy.x < lastxy.x)        /* moved left, clear right */
          178                         draw(screen, Rect(max.x, screen->r.min.y, screen->r.max.x, screen->r.max.y),
          179                                 display->white, nil, ZP);
          180                 else        /* moved right, clear left*/
          181                         draw(screen, Rect(screen->r.min.x, screen->r.min.y, min.x, screen->r.max.y),
          182                                 display->white, nil, ZP);
          183                 if(mouse.xy.y < lastxy.y)        /* moved up, clear down */
          184                         draw(screen, Rect(screen->r.min.x, max.y, screen->r.max.x, screen->r.max.y),
          185                                 display->white, nil, ZP);
          186                 else                /* moved down, clear up */
          187                         draw(screen, Rect(screen->r.min.x, screen->r.min.y, screen->r.max.x, min.y),
          188                                 display->white, nil, ZP);
          189                 flushimage(display, 1);
          190         }while(mouse.buttons);
          191 
          192         xyoffset = addpt(xyoffset, subpt(mouse.xy, xy));
          193 
          194         esetcursor(0);
          195         return "p";
          196 }
          197 
          198 static char *getmousestr(void)
          199 {
          200         static char buf[20];
          201 
          202         checkmouse();
          203         if (last_but == 1)
          204                 return "p";        /* repaint after panning */
          205         if (last_but == 2) {
          206                 return "c";
          207         } else if (last_but == 3) {
          208                 switch (last_hit) {
          209                 case Next:
          210                         return "";
          211                 case Prev:
          212                         return "-1";
          213                 case Page:
          214                         screenprint("page? ");
          215                         return "c";
          216                 case Again:
          217                         return "p";
          218                 case Bigger:
          219                         sprint(buf, "m%g", mag * 1.1);
          220                         return buf;
          221                 case Smaller:
          222                         sprint(buf, "m%g", mag / 1.1);
          223                         return buf;
          224                 case Pan:
          225                         return pan();
          226                 case Quit:
          227                         return "q";
          228                 default:
          229                         return "c";
          230                 }
          231         } else {                /* button 1 or bail out */
          232                 return "c";
          233         }
          234 }
          235 
          236 static int
          237 checkmouse(void)        /* return button touched if any */
          238 {
          239         int c, b;
          240         char *p;
          241         extern int confirm(int);
          242 
          243         b = waitdown();
          244         last_but = 0;
          245         last_hit = -1;
          246         c = 0;
          247         if (button3(b)) {
          248                 last_hit = emenuhit(3, &mouse, &mbut3);
          249                 last_but = 3;
          250         } else if (button2(b)) {
          251                 last_hit = emenuhit(2, &mouse, &mbut2);
          252                 last_but = 2;
          253         } else {                /* button1() */
          254                 pan();
          255                 last_but = 1;
          256         }
          257         waitup();
          258         if (last_but == 3 && last_hit >= 0) {
          259                 p = m3[last_hit];
          260                 c = p[strlen(p) - 1];
          261         }
          262         if (c == '?' && !confirm(last_but))
          263                 last_hit = -1;
          264         return last_but;
          265 }
          266 
          267 Cursor deadmouse = {
          268         { 0, 0},        /* offset */
          269         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
          270           0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41,
          271           0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0,
          272           0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
          273         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
          274           0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41,
          275           0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0,
          276           0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }
          277 };
          278 
          279 Cursor blot ={
          280         { 0, 0 },
          281         { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
          282           0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
          283           0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
          284           0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, },
          285         { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
          286           0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
          287           0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
          288           0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }
          289 };
          290 
          291 Cursor skull ={
          292         { 0, 0 },
          293         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03,
          294           0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0,
          295           0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27,
          296           0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
          297         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03,
          298           0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0,
          299           0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27,
          300           0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }
          301 };
          302 
          303 int
          304 confirm(int but)        /* ask for confirmation if menu item ends with '?' */
          305 {
          306         int c;
          307         static int but_cvt[8] = { 0, 1, 2, 0, 3, 0, 0, 0 };
          308 
          309         esetcursor(&skull);
          310         c = waitdown();
          311         waitup();
          312         esetcursor(0);
          313         return but == but_cvt[c];
          314 }