[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Always use UTF-8 when running base-config?



Martin Sj�gren <martin@strakt.com>:

> > I applied Alan Cox's patches to bogl-0.1.12 and found that
> > bogl-bterm-udeb's bterm scrolled much faster. I have forwarded the
> > patches to Daniel Jacobowitz. Anyone else who wants them, let me know.
> 
> Any progress on this? Dan?
> 
> Where can I find those patches, Edmund?

It's probably best if I just post them here.
These patches do four things

1.	Avoiding multiple redraws of the same thing
2.	Deferring redrawing for batching of updates, which also
	simplifies the code.
3.	Use a clean/dirty model to cut down on rendering
4.	Apply a pile of optimisations to the vga16 renderer

This isnt the final thing. Something is wrong in the dirty_scroll logic
that I've yet to pin down so that is disabled. This is an important bug
to solve as most lines are mainly spaces so we can render far less
characters

VGA renderer optimisations:

diff -u --recursive bogl/bogl-vga16.c bogl-ac/bogl-vga16.c
--- bogl/bogl-vga16.c	2001-12-01 17:04:42.000000000 +0000
+++ bogl-ac/bogl-vga16.c	2002-12-17 01:59:02.000000000 +0000
@@ -1,5 +1,8 @@
 /* BOGL - Ben's Own Graphics Library.
    Written by Ben Pfaff <pfaffben@debian.org>.
+   
+   VGA optimisations
+   (c) Copyright Red Hat Inc 2002, <alan@redhat.com>.
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -48,16 +51,26 @@
 static inline void 
 set_color (int c)
 {
-  outb (0, 0x3ce);
-  outb (c, 0x3cf);
+  static int cached_color = -1;
+  if(cached_color != c)
+  {
+    outb (0, 0x3ce);
+    outb (c, 0x3cf);
+    cached_color = c;
+  }
 }
 
 /* Set the Enable Set/Reset Register. */
 static inline void
 set_enable_sr (int mask)
 {
-  outb (1, 0x3ce);
-  outb (mask, 0x3cf);
+  static int cached_mask = -1;
+  if(cached_mask != mask)
+  {
+    outb (1, 0x3ce);
+    outb (mask, 0x3cf);
+    cached_mask = mask;
+  }
 }
 
 /* Select the Bit Mask Register on the Graphics Controller. */
@@ -81,24 +94,40 @@
 static inline void
 set_op (int op)
 {
-  outb (3, 0x3ce);
-  outb (op, 0x3cf);
+  static int cached_op = -1;
+  
+  if(op != cached_op)
+  {
+    outb (3, 0x3ce);
+    outb (op, 0x3cf);
+    cached_op = op;
+  }
 }
 
 /* Set the Memory Plane Write Enable register. */
 static inline void
 set_write_planes (int mask)
 {
-  outb (2, 0x3c4);
-  outb (mask, 0x3c5);
+  static int cached_mask = -1;
+  if(mask != cached_mask)
+  {
+    outb (2, 0x3c4);
+    outb (mask, 0x3c5);
+    mask = cached_mask;
+  }
 }
 
 /* Set the Read Map Select register. */
 static inline void
 set_read_plane (int plane)
 {
-  outb (4, 0x3ce);
-  outb (plane, 0x3cf);
+  static int cached_plane = -1;
+  if(cached_plane != plane)
+  {
+    outb (4, 0x3ce);
+    outb (plane, 0x3cf);
+    cached_plane = plane;
+  }
 }
 
 /* Set the Graphics Mode Register.  The write mode is in bits 0-1, the
@@ -106,8 +135,13 @@
 static inline void
 set_mode (int mode)
 {
-  outb (5, 0x3ce);
-  outb (mode, 0x3cf);
+  static int cached_mode = -1;
+  if(cached_mode != mode)
+  {
+    outb (5, 0x3ce);
+    outb (mode, 0x3cf);
+    cached_mode = mode;
+  }
 }
 
 /* Read-modify-write the specified memory byte. */
@@ -170,8 +204,15 @@
       set_mask (0xff);
       last = bogl_frame + x2 / 8 + y * bogl_line_len;
       while (dst < last)
-	*dst++ = 1;
-      
+      {
+        while(!((unsigned long)dst&3) && last-dst > 3)
+        {
+        	*(unsigned int *)dst = 0x01010101;
+        	dst+=4;
+        }
+        if(dst < last)
+	        *dst++ = 1;
+      }
       set_mask (0xff << (7 - x2 % 8));
       rmw (dst);
     }
@@ -265,8 +306,15 @@
 	  set_mask (0xff);
 	  last = bogl_frame + x2 / 8 + y * bogl_line_len;
 	  while (dst < last)
-	    *dst++ = 1;
-      
+	  {
+            while(!((unsigned long)dst&3) && last-dst > 3)
+	    {
+        	*(unsigned int *)dst = 0x01010101;
+        	dst+=4;
+            }
+            if(dst < last)
+	      *dst++ = 1;
+          }
 	  set_mask (0xff << (7 - x2 % 8));
 	  rmw (dst);
 	}
@@ -291,7 +339,7 @@
   int k;
   wchar_t wc;
 
-  void plot (void)
+  void plot (int bg)
     {
       volatile char *dst = bogl_frame + xx / 8 + yy * bogl_line_len;
       int y, i;
@@ -302,8 +350,11 @@
 	  
 	  for (i = ul_size - 1; i >= 0; i--)
 	    {
-	      set_mask (b);
-	      rmw (dst + i);
+	      if((b & 0xFF) || bg == -1)
+	      {
+	        set_mask (b);
+	        rmw (dst + i);
+	      }
 	      b >>= 8;
 	    }
 	  
@@ -353,7 +404,7 @@
 
       if (x >= (int) ul_bits)
 	{
-	  plot ();
+	  plot (bg);
 
 	  x -= ul_bits;
 	  for (y = 0; y < h; y++)
@@ -364,7 +415,7 @@
 	    goto done;
 	}
     }
-  plot ();
+  plot (bg);
 
  done:
   bogl_drawing = 0;


Bterm optimisations:

diff -u --recursive bogl/bogl-term.c bogl-ac/bogl-term.c
--- bogl/bogl-term.c	2002-08-17 21:27:06.000000000 +0100
+++ bogl-ac/bogl-term.c	2002-12-17 01:49:59.000000000 +0000
@@ -1,6 +1,9 @@
 /* BOGL - Ben's Own Graphics Library.
    This file is by Edmund GRIMLEY EVANS <edmundo@rano.org>.
 
+   Rendering optimisation and delay code
+   (c) Copyright Red Hat Inc 2002  <alan@redhat.com>
+
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation; either version 2 of the
@@ -55,16 +58,18 @@
   memset(&term->ps, 0, sizeof(&term->ps));
 
   term->screen = malloc(term->xsize * term->ysize * sizeof(wchar_t));
+  term->dirty = malloc(term->xsize * term->ysize);
   term->screenfg = malloc(term->xsize * term->ysize * sizeof(int));
   term->screenbg = malloc(term->xsize * term->ysize * sizeof(int));
   term->screenul = malloc(term->xsize * term->ysize * sizeof(int));
   term->cchars = malloc(term->xsize * term->ysize * sizeof(wchar_t *));
-  if (!term->screen || !term->screenfg || !term->screenbg || !term->screenul || !term->cchars) {
+  if (!term->screen || !term->screenfg || !term->screenbg || !term->screenul || !term->cchars || !term->dirty) {
     free(term->screen);
     free(term->screenfg);
     free(term->screenbg);
     free(term->screenul);
     free(term->cchars);
+    free(term->dirty);
     free(term);
     return 0;
   }
@@ -74,6 +79,7 @@
     term->screenbg[i] = term->def_bg;
     term->screenul[i] = 0;
     term->cchars[i] = 0;
+    term->dirty[i] = 1;
   }
   term->yorig = 0;
 
@@ -85,6 +91,65 @@
 #define SCR(x, y) \
 ((x) + (((y) + term->yorig) % term->ysize) * term->xsize)
 
+
+static int term_match(struct bogl_term *term, int p1, int p2)
+{
+    if(term->screen[p1] != term->screen[p2])
+    	return 0;
+    if(term->screenfg[p1] != term->screenfg[p2])
+    	return 0;
+    if(term->screenbg[p1] != term->screenbg[p2])
+    	return 0;
+    if(term->screenul[p1] != term->screenul[p2])
+    	return 0;
+    return 1;
+}
+
+static int term_is_clear(struct bogl_term *term, int p1)
+{
+    if(term->screen[p1] != ' ')
+    	return 0;
+    if(term->screenfg[p1] != term->fg)
+    	return 0;
+    if(term->screenbg[p1] != term->bg)
+    	return 0;
+    if(term->screenul[p1] != 0)
+    	return 0;
+    return 1;
+}
+
+/* We are scrolling so anything which isnt the same as the spot below
+   is deemed dirty */
+   
+static void dirty_scroll(struct bogl_term *term)
+{
+    int x,y;
+    
+    for(y = 0; y < term->ysize-1; y++)
+    	for(x=0; x < term->xsize; x++)
+    {
+    	/* FIXME - why doesn't this logic work */
+    	// if(!term_match(term, SCR(x,y), SCR(x,y+1)))
+    		term->dirty[SCR(x,y)]=1;
+    }
+}
+
+/* We are backscrolling so anything which isnt the same as the spot above
+   is deemed dirty */
+   
+static void dirty_backscroll(struct bogl_term *term)
+{
+    int x,y;
+    
+    for(y = 1; y < term->ysize; y++)
+    	for(x=0; x < term->xsize; x++)
+    {
+    	/* FIXME - why doesn't this logic work */
+    	// if(!term_match(term, SCR(x,y), SCR(x,y-1)))
+    		term->dirty[SCR(x,y)]=1;
+    }
+}
+
 static void
 cursor_down (struct bogl_term *term)
 {
@@ -95,7 +160,10 @@
         return;
     }
 
+
     ++term->yorig;
+    dirty_scroll(term);
+
     for (i = 0; i < term->xsize; i++)
     {
         int p = SCR(i, term->ypos);
@@ -104,12 +172,10 @@
         term->screenfg[p] = term->fg;
         term->screenbg[p] = term->bg;
         term->screenul[p] = 0;
+        term->dirty[p] = 1;
         free (term->cchars[p]);
         term->cchars[p] = 0;
     }
-
-    /* If we had a bogl_move or bogl_scroll we could use it here. */
-    bogl_term_redraw (term);
 }
 
 static void
@@ -163,9 +229,8 @@
             fg = term->screenbg[i], bg = term->screenfg[i];
         else
             fg = term->screenfg[i], bg = term->screenbg[i];
-
-        put_char (term, x, term->ypos, term->screen[i], term->cchars[i],
-		  fg, bg, term->screenul[i]);
+        put_char(term, x, term->ypos, term->screen[i], term->cchars[i], fg, bg, term->screenul[i]);
+        term->dirty[SCR(x, term->ypos)] = 1;
     }
 }
 
@@ -176,11 +241,14 @@
     if (!term->screen[i])
     {
         for (j = i - 1; !term->screen[j]; j--)
+        {
+            if(term->screen[j] != ' ')
+            	term->dirty[j] = 1;
             term->screen[j] = ' ';
+        }
 
         term->screen[j] = ' ';
-
-        bogl_clear (XPOS(term->xpos + j - i), YPOS(term->ypos), XPOS(term->xpos), YPOS(term->ypos + 1), term->screenbg[j]);
+        term->dirty[j] = 1;
     }
 }
 
@@ -190,9 +258,13 @@
   int j, i = SCR(term->xpos, term->ypos);
 
   for (j = 0; term->xpos + j < term->xsize && !term->screen[i + j]; j++)
-    term->screen[i + j] = ' ';
-  if (j)
-    bogl_clear(XPOS(term->xpos), YPOS(term->ypos), XPOS(term->xpos + j), YPOS(term->ypos + 1), term->screenbg[i]);
+  {
+    if(term->screen[i + j] != ' ')
+    {
+    	term->dirty[i + j] = 1;
+        term->screen[i + j] = ' ';
+    }
+  }
 }
 
 void
@@ -203,9 +275,6 @@
     int i, j, w, txp, f, b, use_acs;
     char buf[MB_LEN_MAX];
 
-    if (term->cur_visible)
-        show_cursor (term, 0);
-
     k = 0;
     while (1)
     {
@@ -253,7 +322,6 @@
 
         if (wc == 8)
         {                       /* cub1=^H */
-            show_cursor (term, 0);
             if (term->xpos)
                 --term->xpos;
             term->state = 0;
@@ -262,22 +330,26 @@
 
         if (wc == 9)
         {                       /* ht=^I */
-            show_cursor (term, 0);
+            int target;
             /* I'm not sure whether this way of going over the right margin
                is correct, so I don't declare this capability in terminfo. */
-            term->xpos = (term->xpos / 8) * 8 + 8;
-            if (term->xpos >= term->xsize)
+            target = (term->xpos / 8) * 8 + 8;
+            while(term->xpos < target)
             {
-                term->xpos = 0;
-                cursor_down (term);
-            }
+	        if (term->xpos >= term->xsize)
+	        {
+	            term->xpos = 0;
+	            cursor_down (term);
+	            break;
+	        }
+	        bogl_term_out(term, " ", 1);
+	    }
             term->state = 0;
             continue;
         }
 
         if (wc == 10)
         {                       /* ind=^J */
-            show_cursor (term, 0);
             cursor_down (term);
             term->state = 0;
             continue;
@@ -285,7 +357,6 @@
 
         if (wc == 13)
         {                       /* cr=^M */
-            show_cursor (term, 0);
             term->xpos = 0;
             term->state = 0;
             continue;
@@ -332,6 +403,7 @@
 
                     /* Move all other lines down.  Fortunately, this is easy.  */
                     term->yorig--;
+                    dirty_backscroll(term);
 
                     /* Clear the top line.  */
                     for (i = SCR (0, 0); i < SCR (term->xsize, 0); i++)
@@ -341,10 +413,8 @@
                         term->screenbg[i] = term->bg;
                         term->screenul[i] = 0;
                         term->cchars[i] = 0;
+                        term->dirty[i] = 1;
                     }
-
-		    /* Update the screen.  We really need scrolling.  */
-                    bogl_term_redraw(term);
                 }
             }
             term->state = 0;
@@ -386,8 +456,6 @@
             {                   /* home=\E[H, cup=\E[%i%p1%d;%p2%dH */
                 if (term->state < 3)
                 {
-                    /* Hide the cursor before moving it.  */
-                    show_cursor (term, 0);
                     if (term->state == 2)
                     {
                         if (term->arg[1] <= term->xsize)
@@ -408,35 +476,33 @@
                    until cursor, 2 means clear whole screen.  */
                 if (term->state == 1 && term->arg[0] == 2)
                 {
-                    bogl_clear (XPOS (0), YPOS (0),
-                                XPOS (term->xsize), YPOS (term->ysize),
-                                term->bg);
                     for (i = 0; i < term->xsize * term->ysize; i++)
                     {
-                        term->screen[i] = ' ';
-                        term->screenfg[i] = term->fg;
-                        term->screenbg[i] = term->bg;
-                        term->screenul[i] = 0;
+                    	if(!term_is_clear(term, i))
+                    	{
+	                    term->dirty[i] = 1;
+	                    term->screen[i] = ' ';
+	                    term->screenfg[i] = term->fg;
+	                    term->screenbg[i] = term->bg;
+	                    term->screenul[i] = 0;
+	                }
                         free (term->cchars[i]);
                         term->cchars[i] = 0;
                     }
                 }
                 else if (term->state == 1 && term->arg[0] == 0)
                 {
-                    bogl_clear (XPOS (term->xpos), YPOS (term->ypos),
-                                XPOS (term->xsize), YPOS (term->ypos + 1),
-                                term->bg);
-                    if (term->ypos + 1 < term->ysize)
-                        bogl_clear (XPOS (0), YPOS (term->ypos + 1),
-                                    XPOS (term->xsize), YPOS (term->ysize),
-                                    term->bg);
                     for (i = SCR (term->xpos, term->ypos);
                          i < term->xsize * term->ysize; i++)
                     {
-                        term->screen[i] = ' ';
-                        term->screenfg[i] = term->fg;
-                        term->screenbg[i] = term->bg;
-                        term->screenul[i] = 0;
+                        if(!term_is_clear(term, i))
+                        {
+                    	    term->dirty[i] = 1;
+                            term->screen[i] = ' ';
+                            term->screenfg[i] = term->fg;
+                            term->screenbg[i] = term->bg;
+                            term->screenul[i] = 0;
+                        }
                         free (term->cchars[i]);
                         term->cchars[i] = 0;
                     }
@@ -449,16 +515,17 @@
             {                   /* el=\E[K */
                 if (term->state == 1 && !term->arg[0])
                 {
-                    bogl_clear (XPOS (term->xpos), YPOS (term->ypos),
-                                XPOS (term->xsize), YPOS (term->ypos + 1),
-                                term->bg);
                     clear_left (term);
                     for (i = SCR (term->xpos, term->ypos); i < SCR (term->xsize, term->ypos); i++)
                     {
-                        term->screen[i] = ' ';
-                        term->screenfg[i] = term->fg;
-                        term->screenbg[i] = term->bg;
-                        term->screenul[i] = 0;
+                        if(!term_is_clear(term, i))
+                        {
+                            term->dirty[i] = 1;
+                            term->screen[i] = ' ';
+                            term->screenfg[i] = term->fg;
+                            term->screenbg[i] = term->bg;
+                            term->screenul[i] = 0;
+                        }
                         free (term->cchars[i]);
                         term->cchars[i] = 0;
                     }
@@ -598,18 +665,20 @@
 
                 if (term->xpos + w > term->xsize)
                 {
-                    bogl_clear (XPOS (term->xpos), YPOS (term->ypos), XPOS (term->xsize), YPOS (term->ypos + 1), term->bg);
-
                     clear_left (term);
 
                     for (i = SCR (term->xpos, term->ypos); i < SCR (term->xsize, term->ypos); i++)
                     {
-                        term->screen[i] = ' ';
-                        /* Use term->fg and term->bg rather than f and b - this is not
-                           affected by reverse video. */
-                        term->screenfg[i] = term->fg;
-                        term->screenbg[i] = term->bg;
-                        term->screenul[i] = 0;
+                        if(!term_is_clear(term,i))
+                        {
+                            term->dirty[i] = 1;
+                            term->screen[i] = ' ';
+                            /* Use term->fg and term->bg rather than f and b - this is not
+                               affected by reverse video. */
+                            term->screenfg[i] = term->fg;
+                            term->screenbg[i] = term->bg;
+                            term->screenul[i] = 0;
+                        }
                         free (term->cchars[i]);
                         term->cchars[i] = NULL;
                     }
@@ -620,6 +689,7 @@
 
                 clear_left (term);
                 i = SCR (term->xpos, term->ypos);
+                term->dirty[i] = 1;
                 term->screen[i] = wc;
                 term->screenfg[i] = f;
                 term->screenbg[i] = b;
@@ -629,6 +699,7 @@
 
                 for (j = 1; j < w; j++)
                 {
+                    term->dirty[i + j] = 1;
                     term->screen[i + j] = 0;
                     term->screenfg[i + j] = f;
                     term->screenbg[i + j] = b;
@@ -637,7 +708,6 @@
 
                 if (bogl_in_font (term->font, wc))
                 {
-                    bogl_text (XPOS (term->xpos), YPOS (term->ypos), buf, kk, f, b, term->ul, term->font);
                     term->xp = term->xpos, term->yp = term->ypos;
                     term->xpos += w;
                 }
@@ -648,7 +718,6 @@
 
                     for (r = 0; r < w; r++)
                     {
-                        bogl_text (XPOS (term->xpos), YPOS (term->ypos), buf, kk, f, b, term->ul, term->font);
                         term->xp = term->xpos, term->yp = term->ypos;
                         ++term->xpos;
                     }
@@ -662,12 +731,12 @@
             if (txp >= 0)
             {
                 term->xp = txp;
-                bogl_text (XPOS (term->xp), YPOS (term->yp), buf, kk, f, -1, term->ul, term->font);
+//                bogl_text (XPOS (term->xp), YPOS (term->yp), buf, kk, f, -1, term->ul, term->font);
             }
             else
             {
                 clear_left (term);
-                bogl_text (XPOS (term->xpos), YPOS (term->ypos), buf, kk, f, b, term->ul, term->font);
+//                bogl_text (XPOS (term->xpos), YPOS (term->ypos), buf, kk, f, b, term->ul, term->font);
                 term->xp = term->xpos, term->yp = term->ypos;
                 term->xpos += 1;
                 clear_right (term);
@@ -675,8 +744,6 @@
         }
     }
 
-    if (term->cur_visible)
-        show_cursor (term, 1);
 }
 
 void
@@ -684,16 +751,23 @@
 {
     int x, y, i;
 
+    /* We should move these and distinguish redraw/refresh I guess
+    		-- AC */
+    		
     bogl_clear(0, YPOS(term->ysize), bogl_xres, bogl_yres, 0);
     bogl_clear(XPOS(term->xsize), 0, bogl_xres, YPOS(term->ysize), 0);
     for (y = 0; y < term->ysize; y++)
         for (x = 0; x < term->xsize; x++)
         {
             i = SCR(x, y);
-            if (term->screen[i])
+            if (term->screen[i] && term->dirty[i])
+            {
                 put_char(term, x, y, term->screen[i], term->cchars[i], term->screenfg[i], term->screenbg[i], term->screenul[i]);
+                term->dirty[i] = 0;
+            }
         }
-    
     if (term->cur_visible)
+    {
         show_cursor(term, 1);
+    }        
 }
diff -u --recursive bogl/bogl-term.h bogl-ac/bogl-term.h
--- bogl/bogl-term.h	2002-08-17 21:27:20.000000000 +0100
+++ bogl-ac/bogl-term.h	2002-12-17 00:54:13.000000000 +0000
@@ -20,6 +20,7 @@
   mbstate_t ps;
   wchar_t *screen; /* character in cell, or 0 */
   int *screenfg, *screenbg, *screenul; /* colours in cell */
+  char *dirty; /* bitmask of dirty chars */
   wchar_t **cchars; /* combining chars in cell, or 0 */
   int yorig; /* increment this to scroll */
   int acs;
diff -u --recursive bogl/bterm.c bogl-ac/bterm.c
--- bogl/bterm.c	2001-12-01 17:04:42.000000000 +0000
+++ bogl-ac/bterm.c	2002-12-17 01:25:39.000000000 +0000
@@ -1,5 +1,7 @@
 /* BOGL - Ben's Own Graphics Library.
    This file is by Edmund GRIMLEY EVANS <edmundo@rano.org>.
+   Rendering design redone by Red Hat Inc, Alan Cox <alan@redhat.com>
+   
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -17,7 +19,8 @@
    USA. */
 
 /*
- * This provides a simple virtual terminal.
+ * This provides a simple virtual terminal, with delayed refresh
+ * so that it appears fast even when it isn't being fast.
  */
 
 #include <errno.h>
@@ -151,7 +154,7 @@
 {
   struct termios ntio;
   int ret;
-  char buf[256];
+  char buf[8192];
   struct timeval tv;
   int ptyfd, ttyfd;
   struct bogl_term *term;
@@ -159,6 +162,7 @@
   char *locale = "", *font_name = NULL, *command = NULL;
   int i;
   char o = ' ';
+  int pending = 0;
 
   for (i = 1 ; i < argc ; ++i)
       if (argv[i][0] == '-')
@@ -237,8 +241,17 @@
   for (;;) {
     fd_set fds;
     int max = 0;
-    tv.tv_sec = 10;
-    tv.tv_usec = 100000;
+    
+    if(pending)
+    {
+    	tv.tv_sec = 0;
+    	tv.tv_usec = 0;
+    }
+    else
+    {
+    	tv.tv_sec = 10;
+    	tv.tv_usec = 100000;
+    }
     FD_ZERO(&fds);
     FD_SET(0, &fds);
     FD_SET(ptyfd, &fds);
@@ -250,7 +263,14 @@
       bogl_term_redraw(term);
     }
     if (ret == 0 || (ret < 0 && errno == EINTR))
+    {
+      if(pending)
+      {
+      	pending = 0;
+	bogl_term_redraw(term);
+      }      	
       continue;
+    }
 
     if (ret < 0)
       perror("select");
@@ -262,7 +282,10 @@
     else if (FD_ISSET(ptyfd,&fds)) {
       ret = read(ptyfd, buf, sizeof(buf));
       if (ret > 0)
+      {
 	bogl_term_out(term, buf, ret);
+	pending = 1;
+      }
     }
   }
 }
--- bogl-vga16.c~       2002-12-18 00:24:48.000000000 +0000
+++ bogl-vga16.c        2002-12-18 00:24:48.000000000 +0000
@@ -434,7 +434,7 @@
   assert (xx >= 0 && xx < bogl_xres);
   assert (xx + pixmap->width <= bogl_xres);
   assert (yy >= 0 && yy < bogl_yres);
-  assert (yy + pixmap->width <= bogl_yres);
+  assert (yy + pixmap->height <= bogl_yres);
   src = pixmap->data;

   bogl_drawing = 1;

Reply to: