1 #include "u.h" 2 #include "lib.h" 3 #include "dat.h" 4 #include "fns.h" 5 #include "error.h" 6 7 #include <draw.h> 8 #include <memdraw.h> 9 #include "screen.h" 10 11 #define MINX 8 12 #define Backgnd 0xFF /* white */ 13 14 Memsubfont *memdefont; 15 16 struct{ 17 Point pos; 18 int bwid; 19 }out; 20 21 Lock screenlock; 22 23 Memimage *conscol; 24 Memimage *back; 25 extern Memimage *gscreen; 26 27 static Rectangle flushr; 28 static Rectangle window; 29 static Point curpos; 30 static int h; 31 static void termscreenputs(char*, int); 32 33 34 static void 35 screenflush(void) 36 { 37 drawflushr(flushr); 38 flushr = Rect(10000, 10000, -10000, -10000); 39 } 40 41 static void 42 addflush(Rectangle r) 43 { 44 if(flushr.min.x >= flushr.max.x) 45 flushr = r; 46 else 47 combinerect(&flushr, r); 48 } 49 50 static void 51 screenwin(void) 52 { 53 Point p; 54 char *greet; 55 Memimage *grey; 56 57 drawqlock(); 58 back = memwhite; 59 conscol = memblack; 60 memfillcolor(gscreen, 0x444488FF); 61 62 h = memdefont->height; 63 64 window.min = addpt(gscreen->r.min, Pt(20,20)); 65 window.max.x = window.min.x + Dx(gscreen->r)*3/4-40; 66 window.max.y = window.min.y + Dy(gscreen->r)*3/4-100; 67 68 memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP, S); 69 window = insetrect(window, 4); 70 memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S); 71 72 /* a lot of work to get a grey color */ 73 grey = allocmemimage(Rect(0,0,1,1), CMAP8); 74 grey->flags |= Frepl; 75 grey->clipr = gscreen->r; 76 memfillcolor(grey, 0xAAAAAAFF); 77 memimagedraw(gscreen, Rect(window.min.x, window.min.y, 78 window.max.x, window.min.y+h+5+6), grey, ZP, nil, ZP, S); 79 freememimage(grey); 80 window = insetrect(window, 5); 81 82 greet = " Plan 9 Console "; 83 p = addpt(window.min, Pt(10, 0)); 84 memimagestring(gscreen, p, conscol, ZP, memdefont, greet); 85 window.min.y += h+6; 86 curpos = window.min; 87 window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h; 88 flushmemscreen(gscreen->r); 89 drawqunlock(); 90 } 91 92 void 93 terminit(void) 94 { 95 memdefont = getmemdefont(); 96 out.pos.x = MINX; 97 out.pos.y = 0; 98 out.bwid = memdefont->info[' '].width; 99 screenwin(); 100 screenputs = termscreenputs; 101 } 102 103 static void 104 scroll(void) 105 { 106 int o; 107 Point p; 108 Rectangle r; 109 110 o = 8*h; 111 r = Rpt(window.min, Pt(window.max.x, window.max.y-o)); 112 p = Pt(window.min.x, window.min.y+o); 113 memimagedraw(gscreen, r, gscreen, p, nil, p, S); 114 r = Rpt(Pt(window.min.x, window.max.y-o), window.max); 115 memimagedraw(gscreen, r, back, ZP, nil, ZP, S); 116 flushmemscreen(gscreen->r); 117 curpos.y -= o; 118 } 119 120 static void 121 screenputc(char *buf) 122 { 123 Point p; 124 int w, pos; 125 Rectangle r; 126 static int *xp; 127 static int xbuf[256]; 128 129 if(xp < xbuf || xp >= &xbuf[sizeof(xbuf)]) 130 xp = xbuf; 131 132 switch(buf[0]) { 133 case '\n': 134 if(curpos.y+h >= window.max.y) 135 scroll(); 136 curpos.y += h; 137 screenputc("\r"); 138 break; 139 case '\r': 140 xp = xbuf; 141 curpos.x = window.min.x; 142 break; 143 case '\t': 144 p = memsubfontwidth(memdefont, " "); 145 w = p.x; 146 *xp++ = curpos.x; 147 pos = (curpos.x-window.min.x)/w; 148 pos = 8-(pos%8); 149 r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h); 150 memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S); 151 addflush(r); 152 curpos.x += pos*w; 153 break; 154 case '\b': 155 if(xp <= xbuf) 156 break; 157 xp--; 158 r = Rect(*xp, curpos.y, curpos.x, curpos.y + h); 159 memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S); 160 addflush(r); 161 curpos.x = *xp; 162 break; 163 default: 164 p = memsubfontwidth(memdefont, buf); 165 w = p.x; 166 167 if(curpos.x >= window.max.x-w) 168 screenputc("\n"); 169 170 *xp++ = curpos.x; 171 r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y + h); 172 memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S); 173 memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf); 174 addflush(r); 175 curpos.x += w; 176 } 177 } 178 179 static void 180 termscreenputs(char *s, int n) 181 { 182 int i, locked; 183 Rune r; 184 char buf[4]; 185 186 lock(&screenlock); 187 locked = drawcanqlock(); 188 while(n > 0){ 189 i = chartorune(&r, s); 190 if(i == 0){ 191 s++; 192 --n; 193 continue; 194 } 195 memmove(buf, s, i); 196 buf[i] = 0; 197 n -= i; 198 s += i; 199 screenputc(buf); 200 } 201 if(locked) 202 drawqunlock(); 203 screenflush(); 204 unlock(&screenlock); 205 } 206