]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/9/pc/cga.c
merge
[plan9front.git] / sys / src / 9 / pc / cga.c
index 66b49b5eba70069c790e5e768500044c037d1c36..824cd62eb67c7f9a0cab83d1523655763f37b503 100644 (file)
@@ -99,7 +99,9 @@ cgascreenputc(Rune c)
        int i;
        uchar *p;
 
-       if(c == '\n'){
+       if(c == '\0')
+               return;
+       else if(c == '\n'){
                cgapos = cgapos/Width;
                cgapos = (cgapos+1)*Width;
        }
@@ -138,8 +140,10 @@ cgascreenputc(Rune c)
 static void
 cgascreenputs(char* s, int n)
 {
+       static char rb[UTFmax];
+       static int nrb;
+       char *e;
        Rune r;
-       int i;
 
        if(!islo()){
                /*
@@ -152,29 +156,64 @@ cgascreenputs(char* s, int n)
        else
                lock(&cgascreenlock);
 
-       while(n > 0){
-               i = chartorune(&r, s);
-               if(i <= 0){
-                       s++;
-                       --n;
-                       continue;
+       e = s + n;
+       while(s < e){
+               rb[nrb++] = *s++;
+               if(nrb >= UTFmax || fullrune(rb, nrb)){
+                       chartorune(&r, rb);
+                       cgascreenputc(r);
+                       nrb = 0;
                }
-               cgascreenputc(r);
-               s += i;
-               n -= i;
        }
 
        unlock(&cgascreenlock);
 }
 
+static void
+cgatokmesg(void)
+{
+       int i, n;
+       char *p;
+
+       ilock(&kmesg.lk);
+       n = kmesg.n;
+       for(i = cgapos-2; i >= 0 && n < sizeof kmesg.buf-UTFmax-1; i -= 2){
+               if((i % Width) == Width-2)
+                       n++;
+               n += runelen(cp437[CGASCREENBASE[i]]);
+       }
+       n -= kmesg.n;
+       if(n > 0){
+               memmove(kmesg.buf+n, kmesg.buf, kmesg.n);
+               kmesg.n += n;
+               p = kmesg.buf;
+               for(i += 2; i >= 0 && i < cgapos && p < kmesg.buf+n; i += 2){
+                       p += runetochar(p, &cp437[CGASCREENBASE[i]]);
+                       if((i % Width) == Width-2)
+                               *p++ = '\n';
+               }
+       }
+       iunlock(&kmesg.lk);
+}
+
 void
 screeninit(void)
 {
+       static int once;
 
        cgapos = cgaregr(0x0E)<<8;
        cgapos |= cgaregr(0x0F);
        cgapos *= 2;
 
+       if(cgapos >= Width*Height){
+               cgapos = 0;
+               movecursor();
+       }
+
+       if(once == 0){
+               once = 1;
+               cgatokmesg();
+       }
+
        screenputs = cgascreenputs;
 }
-