]> Pileus Git - ~andy/gtk/commitdiff
Added virtual functions set_pixel, get_color, fill_span and draw_drawable
authorAlexander Larsson <alla@lysator.liu.se>
Wed, 15 Nov 2000 12:45:30 +0000 (12:45 +0000)
committerAlexander Larsson <alexl@src.gnome.org>
Wed, 15 Nov 2000 12:45:30 +0000 (12:45 +0000)
2000-11-15  Alexander Larsson  <alla@lysator.liu.se>

* gdk/linux-fb/gdkprivate-fb.h:
Added virtual functions set_pixel, get_color,
fill_span and draw_drawable to the GC.
Added global _gdk_fb_screen_gc to use instead of
NULL when drawing to the screen.
Added _gdk_fb_gc_calc_state() prototype.

* gdk/linux-fb/gdkgc-fb.c:
Call _gdk_fb_gc_calc_state() on any gc state change.

* gdk/linux-fb/gdkglobals-fb.c:
Add _gdk_fb_screen_gc

* gdk/linux-fb/gdkdrawable-fb2.c:
_gdk_fb_gc_calc_state() calculates best functions
for the GC state and depth.
Moved bpp specialized code to separate functions.
Added optimized 24 bpp AA draw_drawable.

* gdk/linux-fb/gdkevents-fb.c:
Silence gcc warning.

* gdk/linux-fb/gdkimage-fb.c:
Use _gdk_fb_screen_gc

* gdk/linux-fb/gdkwindow-fb.c:
Init and use _gdk_fb_screen_gc

* gdk/linux-fb/mitypes.h:
Remove unused types.

15 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gdk/linux-fb/gdkdrawable-fb2.c
gdk/linux-fb/gdkevents-fb.c
gdk/linux-fb/gdkgc-fb.c
gdk/linux-fb/gdkglobals-fb.c
gdk/linux-fb/gdkimage-fb.c
gdk/linux-fb/gdkprivate-fb.h
gdk/linux-fb/gdkwindow-fb.c
gdk/linux-fb/mitypes.h

index 553666ae9690e4cf8eaf377acc37ff48ec624d41..9ebfd2eb5c1b31162fad90468eb9d589cd6994d2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+2000-11-15  Alexander Larsson  <alla@lysator.liu.se>
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Added virtual functions set_pixel, get_color,
+       fill_span and draw_drawable to the GC.
+       Added global _gdk_fb_screen_gc to use instead of
+       NULL when drawing to the screen.
+       Added _gdk_fb_gc_calc_state() prototype.
+
+       * gdk/linux-fb/gdkgc-fb.c:
+       Call _gdk_fb_gc_calc_state() on any gc state change.
+
+       * gdk/linux-fb/gdkglobals-fb.c:
+       Add _gdk_fb_screen_gc
+               
+       * gdk/linux-fb/gdkdrawable-fb2.c:
+       _gdk_fb_gc_calc_state() calculates best functions
+       for the GC state and depth.
+       Moved bpp specialized code to separate functions.
+       Added optimized 24 bpp AA draw_drawable.
+
+       * gdk/linux-fb/gdkevents-fb.c:
+       Silence gcc warning.
+
+       * gdk/linux-fb/gdkimage-fb.c:
+       Use _gdk_fb_screen_gc
+
+       * gdk/linux-fb/gdkwindow-fb.c:
+       Init and use _gdk_fb_screen_gc
+
+       * gdk/linux-fb/mitypes.h:
+       Remove unused types.
+
 2000-11-14  Havoc Pennington  <hp@pobox.com>
 
        * gtk/gtktextlayout.c (add_cursor): use PANGO_PIXELS() to convert
index 553666ae9690e4cf8eaf377acc37ff48ec624d41..9ebfd2eb5c1b31162fad90468eb9d589cd6994d2 100644 (file)
@@ -1,3 +1,36 @@
+2000-11-15  Alexander Larsson  <alla@lysator.liu.se>
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Added virtual functions set_pixel, get_color,
+       fill_span and draw_drawable to the GC.
+       Added global _gdk_fb_screen_gc to use instead of
+       NULL when drawing to the screen.
+       Added _gdk_fb_gc_calc_state() prototype.
+
+       * gdk/linux-fb/gdkgc-fb.c:
+       Call _gdk_fb_gc_calc_state() on any gc state change.
+
+       * gdk/linux-fb/gdkglobals-fb.c:
+       Add _gdk_fb_screen_gc
+               
+       * gdk/linux-fb/gdkdrawable-fb2.c:
+       _gdk_fb_gc_calc_state() calculates best functions
+       for the GC state and depth.
+       Moved bpp specialized code to separate functions.
+       Added optimized 24 bpp AA draw_drawable.
+
+       * gdk/linux-fb/gdkevents-fb.c:
+       Silence gcc warning.
+
+       * gdk/linux-fb/gdkimage-fb.c:
+       Use _gdk_fb_screen_gc
+
+       * gdk/linux-fb/gdkwindow-fb.c:
+       Init and use _gdk_fb_screen_gc
+
+       * gdk/linux-fb/mitypes.h:
+       Remove unused types.
+
 2000-11-14  Havoc Pennington  <hp@pobox.com>
 
        * gtk/gtktextlayout.c (add_cursor): use PANGO_PIXELS() to convert
index 553666ae9690e4cf8eaf377acc37ff48ec624d41..9ebfd2eb5c1b31162fad90468eb9d589cd6994d2 100644 (file)
@@ -1,3 +1,36 @@
+2000-11-15  Alexander Larsson  <alla@lysator.liu.se>
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Added virtual functions set_pixel, get_color,
+       fill_span and draw_drawable to the GC.
+       Added global _gdk_fb_screen_gc to use instead of
+       NULL when drawing to the screen.
+       Added _gdk_fb_gc_calc_state() prototype.
+
+       * gdk/linux-fb/gdkgc-fb.c:
+       Call _gdk_fb_gc_calc_state() on any gc state change.
+
+       * gdk/linux-fb/gdkglobals-fb.c:
+       Add _gdk_fb_screen_gc
+               
+       * gdk/linux-fb/gdkdrawable-fb2.c:
+       _gdk_fb_gc_calc_state() calculates best functions
+       for the GC state and depth.
+       Moved bpp specialized code to separate functions.
+       Added optimized 24 bpp AA draw_drawable.
+
+       * gdk/linux-fb/gdkevents-fb.c:
+       Silence gcc warning.
+
+       * gdk/linux-fb/gdkimage-fb.c:
+       Use _gdk_fb_screen_gc
+
+       * gdk/linux-fb/gdkwindow-fb.c:
+       Init and use _gdk_fb_screen_gc
+
+       * gdk/linux-fb/mitypes.h:
+       Remove unused types.
+
 2000-11-14  Havoc Pennington  <hp@pobox.com>
 
        * gtk/gtktextlayout.c (add_cursor): use PANGO_PIXELS() to convert
index 553666ae9690e4cf8eaf377acc37ff48ec624d41..9ebfd2eb5c1b31162fad90468eb9d589cd6994d2 100644 (file)
@@ -1,3 +1,36 @@
+2000-11-15  Alexander Larsson  <alla@lysator.liu.se>
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Added virtual functions set_pixel, get_color,
+       fill_span and draw_drawable to the GC.
+       Added global _gdk_fb_screen_gc to use instead of
+       NULL when drawing to the screen.
+       Added _gdk_fb_gc_calc_state() prototype.
+
+       * gdk/linux-fb/gdkgc-fb.c:
+       Call _gdk_fb_gc_calc_state() on any gc state change.
+
+       * gdk/linux-fb/gdkglobals-fb.c:
+       Add _gdk_fb_screen_gc
+               
+       * gdk/linux-fb/gdkdrawable-fb2.c:
+       _gdk_fb_gc_calc_state() calculates best functions
+       for the GC state and depth.
+       Moved bpp specialized code to separate functions.
+       Added optimized 24 bpp AA draw_drawable.
+
+       * gdk/linux-fb/gdkevents-fb.c:
+       Silence gcc warning.
+
+       * gdk/linux-fb/gdkimage-fb.c:
+       Use _gdk_fb_screen_gc
+
+       * gdk/linux-fb/gdkwindow-fb.c:
+       Init and use _gdk_fb_screen_gc
+
+       * gdk/linux-fb/mitypes.h:
+       Remove unused types.
+
 2000-11-14  Havoc Pennington  <hp@pobox.com>
 
        * gtk/gtktextlayout.c (add_cursor): use PANGO_PIXELS() to convert
index 553666ae9690e4cf8eaf377acc37ff48ec624d41..9ebfd2eb5c1b31162fad90468eb9d589cd6994d2 100644 (file)
@@ -1,3 +1,36 @@
+2000-11-15  Alexander Larsson  <alla@lysator.liu.se>
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Added virtual functions set_pixel, get_color,
+       fill_span and draw_drawable to the GC.
+       Added global _gdk_fb_screen_gc to use instead of
+       NULL when drawing to the screen.
+       Added _gdk_fb_gc_calc_state() prototype.
+
+       * gdk/linux-fb/gdkgc-fb.c:
+       Call _gdk_fb_gc_calc_state() on any gc state change.
+
+       * gdk/linux-fb/gdkglobals-fb.c:
+       Add _gdk_fb_screen_gc
+               
+       * gdk/linux-fb/gdkdrawable-fb2.c:
+       _gdk_fb_gc_calc_state() calculates best functions
+       for the GC state and depth.
+       Moved bpp specialized code to separate functions.
+       Added optimized 24 bpp AA draw_drawable.
+
+       * gdk/linux-fb/gdkevents-fb.c:
+       Silence gcc warning.
+
+       * gdk/linux-fb/gdkimage-fb.c:
+       Use _gdk_fb_screen_gc
+
+       * gdk/linux-fb/gdkwindow-fb.c:
+       Init and use _gdk_fb_screen_gc
+
+       * gdk/linux-fb/mitypes.h:
+       Remove unused types.
+
 2000-11-14  Havoc Pennington  <hp@pobox.com>
 
        * gtk/gtktextlayout.c (add_cursor): use PANGO_PIXELS() to convert
index 553666ae9690e4cf8eaf377acc37ff48ec624d41..9ebfd2eb5c1b31162fad90468eb9d589cd6994d2 100644 (file)
@@ -1,3 +1,36 @@
+2000-11-15  Alexander Larsson  <alla@lysator.liu.se>
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Added virtual functions set_pixel, get_color,
+       fill_span and draw_drawable to the GC.
+       Added global _gdk_fb_screen_gc to use instead of
+       NULL when drawing to the screen.
+       Added _gdk_fb_gc_calc_state() prototype.
+
+       * gdk/linux-fb/gdkgc-fb.c:
+       Call _gdk_fb_gc_calc_state() on any gc state change.
+
+       * gdk/linux-fb/gdkglobals-fb.c:
+       Add _gdk_fb_screen_gc
+               
+       * gdk/linux-fb/gdkdrawable-fb2.c:
+       _gdk_fb_gc_calc_state() calculates best functions
+       for the GC state and depth.
+       Moved bpp specialized code to separate functions.
+       Added optimized 24 bpp AA draw_drawable.
+
+       * gdk/linux-fb/gdkevents-fb.c:
+       Silence gcc warning.
+
+       * gdk/linux-fb/gdkimage-fb.c:
+       Use _gdk_fb_screen_gc
+
+       * gdk/linux-fb/gdkwindow-fb.c:
+       Init and use _gdk_fb_screen_gc
+
+       * gdk/linux-fb/mitypes.h:
+       Remove unused types.
+
 2000-11-14  Havoc Pennington  <hp@pobox.com>
 
        * gtk/gtktextlayout.c (add_cursor): use PANGO_PIXELS() to convert
index 553666ae9690e4cf8eaf377acc37ff48ec624d41..9ebfd2eb5c1b31162fad90468eb9d589cd6994d2 100644 (file)
@@ -1,3 +1,36 @@
+2000-11-15  Alexander Larsson  <alla@lysator.liu.se>
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Added virtual functions set_pixel, get_color,
+       fill_span and draw_drawable to the GC.
+       Added global _gdk_fb_screen_gc to use instead of
+       NULL when drawing to the screen.
+       Added _gdk_fb_gc_calc_state() prototype.
+
+       * gdk/linux-fb/gdkgc-fb.c:
+       Call _gdk_fb_gc_calc_state() on any gc state change.
+
+       * gdk/linux-fb/gdkglobals-fb.c:
+       Add _gdk_fb_screen_gc
+               
+       * gdk/linux-fb/gdkdrawable-fb2.c:
+       _gdk_fb_gc_calc_state() calculates best functions
+       for the GC state and depth.
+       Moved bpp specialized code to separate functions.
+       Added optimized 24 bpp AA draw_drawable.
+
+       * gdk/linux-fb/gdkevents-fb.c:
+       Silence gcc warning.
+
+       * gdk/linux-fb/gdkimage-fb.c:
+       Use _gdk_fb_screen_gc
+
+       * gdk/linux-fb/gdkwindow-fb.c:
+       Init and use _gdk_fb_screen_gc
+
+       * gdk/linux-fb/mitypes.h:
+       Remove unused types.
+
 2000-11-14  Havoc Pennington  <hp@pobox.com>
 
        * gtk/gtktextlayout.c (add_cursor): use PANGO_PIXELS() to convert
index 31550424fea5fcd2419d16f5bc4117ab0e0f5aed..4c7b6626ad56af377dd6a6c1a3d655885d5da4fb 100644 (file)
@@ -5,23 +5,11 @@
 
 #include <string.h>
 
+
 #ifndef g_alloca
 #define g_alloca alloca
 #endif
 
-typedef enum {
-  GPR_USED_BG,
-  GPR_AA_GRAYVAL,
-  GPR_NONE,
-  GPR_ERR_BOUNDS
-} GetPixelRet;
-
-static void         gdk_fb_drawable_set_pixel (GdkDrawable      *drawable,
-                                              GdkGC            *gc,
-                                              int               x,
-                                              int               y,
-                                              GdkColor         *spot,
-                                              gboolean          abs_coords);
 static GetPixelRet  gdk_fb_drawable_get_pixel (GdkDrawable      *drawable,
                                               GdkGC            *gc,
                                               int               x,
@@ -329,11 +317,10 @@ gdk_fb_clip_region (GdkDrawable *drawable,
 }
 
 static void
-gdk_fb_fill_span (GdkDrawable *drawable,
-                 GdkGC       *gc,
-                 GdkSegment  *cur,
-                 GdkColor    *color,
-                 GdkVisual   *visual)
+gdk_fb_fill_span_general (GdkDrawable *drawable,
+                         GdkGC       *gc,
+                         GdkSegment  *cur,
+                         GdkColor    *color)
 {
   int curx, cury;
   GdkColor spot = *color;
@@ -342,270 +329,376 @@ gdk_fb_fill_span (GdkDrawable *drawable,
 
   private = GDK_DRAWABLE_FBDATA (drawable);
   gc_private = GDK_GC_FBDATA (gc);
-  
-  if (gc &&
-      (gc_private->values.clip_mask ||
-       gc_private->values.tile ||
-       gc_private->values.stipple ||
-       gc_private->values.function == GDK_INVERT))
-    {
-      int clipxoff, clipyoff; /* Amounts to add to curx & cury to get x & y in clip mask */
-      int tsxoff, tsyoff;
-      GdkDrawable *cmask;
-      guchar *clipmem;
-      guint mask_rowstride;
-      GdkPixmap *ts = NULL;
-      GdkDrawableFBData *ts_private;
-      gboolean solid_stipple;
-      GdkFunction func = gc_private->values.function;
-
-      ts_private = GDK_DRAWABLE_IMPL_FBDATA (ts);
-      
-      cmask = gc_private->values.clip_mask;
-      clipxoff = clipyoff = tsxoff = tsyoff = 0;
-      mask_rowstride = 0;
-      solid_stipple = FALSE;
-      clipmem = NULL;
-      if (cmask)
-       {
-         GdkDrawableFBData *cmask_private;
-
-         cmask_private = GDK_DRAWABLE_IMPL_FBDATA (cmask);
-         
-         clipmem = cmask_private->mem;
-         clipxoff = cmask_private->abs_x - gc_private->values.clip_x_origin - private->abs_x;
-         clipyoff = cmask_private->abs_y - gc_private->values.clip_y_origin - private->abs_y;
-         mask_rowstride = cmask_private->rowstride;
-       }
 
-      if (gc_private->values.fill == GDK_TILED &&
-         gc_private->values.tile)
-       {
-         gint xstep, ystep;
-         gint relx, rely;
-         GdkFBDrawingContext *dc, dc_data;
-         dc = &dc_data;
+  g_assert (gc);
+
+  {
+    int clipxoff, clipyoff; /* Amounts to add to curx & cury to get x & y in clip mask */
+    int tsxoff, tsyoff;
+    GdkDrawable *cmask;
+    guchar *clipmem;
+    guint mask_rowstride;
+    GdkPixmap *ts = NULL;
+    GdkDrawableFBData *ts_private;
+    gboolean solid_stipple;
+    GdkFunction func = gc_private->values.function;
+    
+    cmask = gc_private->values.clip_mask;
+    clipxoff = clipyoff = tsxoff = tsyoff = 0;
+    mask_rowstride = 0;
+    solid_stipple = FALSE;
+    clipmem = NULL;
+    if (cmask)
+      {
+       GdkDrawableFBData *cmask_private;
+       
+       cmask_private = GDK_DRAWABLE_IMPL_FBDATA (cmask);
+       
+       clipmem = cmask_private->mem;
+       clipxoff = cmask_private->abs_x - gc_private->values.clip_x_origin - private->abs_x;
+       clipyoff = cmask_private->abs_y - gc_private->values.clip_y_origin - private->abs_y;
+       mask_rowstride = cmask_private->rowstride;
+      }
+    
+    if (gc_private->values.fill == GDK_TILED &&
+       gc_private->values.tile)
+      {
+       gint xstep, ystep;
+       gint relx, rely;
+       GdkFBDrawingContext *dc, dc_data;
+       dc = &dc_data;
+       
+       gdk_fb_drawing_context_init (dc, drawable, gc, FALSE, TRUE);
+       
+       ts = gc_private->values.tile;
+       ts_private = GDK_DRAWABLE_IMPL_FBDATA (ts);
+       for (cury = cur->y1; cury < cur->y2; cury += ystep)
+         {
+           int drawh;
+           
+           rely = cury - private->abs_y;
+           drawh = (rely + gc_private->values.ts_y_origin) % ts_private->height;
+           if (drawh < 0)
+             drawh += GDK_DRAWABLE_FBDATA (ts)->height;
+           
+           ystep = MIN (ts_private->height - drawh, cur->y2 - rely);
+           
+           for (curx = cur->x1; curx < cur->x2; curx += xstep)
+             {
+               int draww;
+               
+               relx = curx - private->abs_x;
+               
+               draww = (relx + gc_private->values.ts_x_origin) % ts_private->width;
+               if (draww < 0)
+                 draww += ts_private->width;
+               
+               xstep = MIN (ts_private->width - draww, cur->x2 - relx);
+               
+               gdk_fb_draw_drawable_3 (drawable, gc, GDK_DRAWABLE_IMPL (ts),
+                                       dc,
+                                       draww, drawh,
+                                       relx, rely,
+                                       xstep, ystep);
+             }
+         }
+       
+       gdk_fb_drawing_context_finalize (dc);
+       
+       return;
+      }
+    else if ((gc_private->values.fill == GDK_STIPPLED ||
+             gc_private->values.fill == GDK_OPAQUE_STIPPLED) &&
+            gc_private->values.stipple)
+      {
+       ts = gc_private->values.stipple;
+       tsxoff = GDK_DRAWABLE_FBDATA (ts)->abs_x - gc_private->values.ts_x_origin - private->abs_x;
+       tsyoff = GDK_DRAWABLE_FBDATA (ts)->abs_y - gc_private->values.ts_y_origin - private->abs_y;
+       solid_stipple = (gc_private->values.fill == GDK_OPAQUE_STIPPLED);
+      }
+    
+    for (cury = cur->y1; cury < cur->y2; cury++)
+      {
+       for (curx = cur->x1; curx < cur->x2; curx++)
+         {
+           int maskx = curx+clipxoff, masky = cury + clipyoff;
+           guchar foo;
+           
+           if (cmask)
+             {
+               foo = clipmem[masky*mask_rowstride + (maskx >> 3)];
+               
+               if (!(foo & (1 << (maskx % 8))))
+                 continue;
+             }
+           
+           if (func == GDK_INVERT)
+             {
+               (gc_private->get_color) (drawable, gc, curx, cury, &spot);
+               spot.pixel = ~spot.pixel;
+               spot.red = ~spot.red;
+               spot.green = ~spot.green;
+               spot.blue = ~spot.blue;
+             }
+           else if (ts)
+             {
+               int wid, hih;
+               
+               ts_private = GDK_DRAWABLE_IMPL_FBDATA (ts);
+               
+               wid = ts_private->width;
+               hih = ts_private->height;
+               
+               maskx = (curx+tsxoff)%wid;
+               masky = (cury+tsyoff)%hih;
+               if (maskx < 0)
+                 maskx += wid;
+               if (masky < 0)
+                 masky += hih;
+               
+               foo = ts_private->mem[(maskx >> 3) + ts_private->rowstride*masky];
+               if (foo & (1 << (maskx % 8)))
+                 {
+                   spot = gc_private->values.foreground;
+                 }
+               else if (solid_stipple)
+                 {
+                   spot = gc_private->values.background;
+                 }
+               else
+                 continue;
+             }
+           
+           (gc_private->set_pixel) (drawable, gc, curx, cury, spot.pixel);
+         }
+      }
+  }
+}
 
-         gdk_fb_drawing_context_init (dc, drawable, gc, FALSE, TRUE);
+static void
+gdk_fb_fill_span_simple_1 (GdkDrawable *drawable,
+                          GdkGC       *gc,
+                          GdkSegment  *cur,
+                          GdkColor    *color)
+{
+  int curx, cury;
+  GdkGCFBData *gc_private;
+  GdkDrawableFBData *private;
+  guchar *mem, *ptr;
+  guint rowstride;
 
-         ts = gc_private->values.tile;
-         for (cury = cur->y1; cury < cur->y2; cury += ystep)
-           {
-             int drawh;
-             
-             rely = cury - private->abs_y;
-             drawh = (rely + gc_private->values.ts_y_origin) % ts_private->height;
-             if (drawh < 0)
-               drawh += GDK_DRAWABLE_FBDATA (ts)->height;
+  private = GDK_DRAWABLE_FBDATA (drawable);
+  gc_private = GDK_GC_FBDATA (gc);
 
-             ystep = MIN (ts_private->height - drawh, cur->y2 - rely);
+  g_assert (gc);
 
-             for (curx = cur->x1; curx < cur->x2; curx += xstep)
-               {
-                 int draww;
+  g_assert (!gc_private->values.clip_mask &&
+           !gc_private->values.tile &&
+           !gc_private->values.stipple &&
+           gc_private->values.function != GDK_INVERT);
 
-                 relx = curx - private->abs_x;
+  mem = private->mem;
+  rowstride = private->rowstride;
 
-                 draww = (relx + gc_private->values.ts_x_origin) % ts_private->width;
-                 if (draww < 0)
-                   draww += ts_private->width;
+  {
+    int fromx = MIN ((cur->x1+7)&(~7), cur->x2);
+    int begn = fromx - cur->x1, begoff = cur->x1 % 8, endn;
+    guchar begmask, endmask;
+    int body_end = cur->x2 & ~7;
+    int body_len = (body_end - fromx)/8;
+    
+    begmask = ((1 << (begn + begoff)) - 1)
+      & ~((1 << (begoff)) - 1);
+    endn = cur->x2 - body_end;
+    endmask = (1 << endn) - 1;
+    
+    for (cury = cur->y1; cury < cur->y2; cury++)
+      {
+       ptr = mem + cury*rowstride + (cur->x1 >> 3);
+       
+       if (color->pixel)
+         *ptr |= begmask;
+       else
+         *ptr &= ~begmask;
+       
+       curx = fromx;
+       
+       if (curx < cur->x2)
+         {
+           ptr = mem + cury*rowstride + (curx >> 3);
+           memset (ptr, color->pixel?0xFF:0, body_len);
+           
+           if (endn)
+             {
+               ptr = mem + cury*rowstride + (body_end >> 3);
+               if (color->pixel)
+                 *ptr |= endmask;
+               else
+                 *ptr &= ~endmask;
+             }
+         }
+      }
+  }
+}
 
-                 xstep = MIN (ts_private->width - draww, cur->x2 - relx);
+static void
+gdk_fb_fill_span_simple_8 (GdkDrawable *drawable,
+                          GdkGC       *gc,
+                          GdkSegment  *cur,
+                          GdkColor    *color)
+{
+  int cury;
+  GdkGCFBData *gc_private;
+  GdkDrawableFBData *private;
+  guchar *mem, *ptr;
+  guint rowstride;
 
-                 gdk_fb_draw_drawable_3 (drawable, gc, GDK_DRAWABLE_IMPL (ts),
-                                         dc,
-                                         draww, drawh,
-                                         relx, rely,
-                                         xstep, ystep);
-               }
-           }
+  private = GDK_DRAWABLE_FBDATA (drawable);
+  gc_private = GDK_GC_FBDATA (gc);
 
-         gdk_fb_drawing_context_finalize (dc);
+  g_assert (gc);
 
-         return;
-       }
-      else if ((gc_private->values.fill == GDK_STIPPLED ||
-               gc_private->values.fill == GDK_OPAQUE_STIPPLED) &&
-              gc_private->values.stipple)
-       {
-         ts = gc_private->values.stipple;
-         tsxoff = GDK_DRAWABLE_FBDATA (ts)->abs_x - gc_private->values.ts_x_origin - private->abs_x;
-         tsyoff = GDK_DRAWABLE_FBDATA (ts)->abs_y - gc_private->values.ts_y_origin - private->abs_y;
-         solid_stipple = (gc_private->values.fill == GDK_OPAQUE_STIPPLED);
-       }
+  g_assert (!gc_private->values.clip_mask &&
+           !gc_private->values.tile &&
+           !gc_private->values.stipple &&
+           gc_private->values.function != GDK_INVERT);
 
-      for (cury = cur->y1; cury < cur->y2; cury++)
-       {
-         for (curx = cur->x1; curx < cur->x2; curx++)
-           {
-             int maskx = curx+clipxoff, masky = cury + clipyoff;
-             guchar foo;
+  mem = private->mem;
+  rowstride = private->rowstride;
 
-             if (cmask)
-               {
-                 foo = clipmem[masky*mask_rowstride + (maskx >> 3)];
-                 
-                 if (!(foo & (1 << (maskx % 8))))
-                   continue;
-               }
-
-             if (func == GDK_INVERT)
-               {
-                 gdk_fb_drawable_get_pixel (drawable, gc, curx, cury, &spot, TRUE, NULL, NULL);
-                 spot.pixel = ~spot.pixel;
-                 spot.red = ~spot.red;
-                 spot.green = ~spot.green;
-                 spot.blue = ~spot.blue;
-               }
-             else if (ts)
-               {
-                 int wid = ts_private->width, hih = ts_private->height;
-
-                 maskx = (curx+tsxoff)%wid;
-                 masky = (cury+tsyoff)%hih;
-                 if (maskx < 0)
-                   maskx += wid;
-                 if (masky < 0)
-                   masky += hih;
-
-                 foo = ts_private->mem[(maskx >> 3) + ts_private->rowstride*masky];
-                 if (foo & (1 << (maskx % 8)))
-                   {
-                     spot = gc_private->values.foreground;
-                   }
-                 else if (solid_stipple)
-                   {
-                     spot = gc_private->values.background;
-                   }
-                 else
-                   continue;
-               }
-
-             gdk_fb_drawable_set_pixel (drawable, gc, curx, cury, &spot, TRUE);
-           }
-       }
+  for (cury = cur->y1; cury < cur->y2; cury++)
+    {
+      ptr = mem + cury*rowstride + cur->x1;
+      memset (ptr, color->pixel, cur->x2 - cur->x1);
     }
-  else
+}
+static void
+gdk_fb_fill_span_simple_16 (GdkDrawable *drawable,
+                           GdkGC       *gc,
+                           GdkSegment  *cur,
+                           GdkColor    *color)
+{
+  int cury;
+  GdkGCFBData *gc_private;
+  GdkDrawableFBData *private;
+  guchar *mem;
+  guint rowstride;
+  int n;
+  int i;
+
+  private = GDK_DRAWABLE_FBDATA (drawable);
+  gc_private = GDK_GC_FBDATA (gc);
+
+  g_assert (gc);
+
+  g_assert (!gc_private->values.clip_mask &&
+           !gc_private->values.tile &&
+           !gc_private->values.stipple &&
+           gc_private->values.function != GDK_INVERT);
+
+  mem = private->mem;
+  rowstride = private->rowstride;
+
+  n = cur->x2 - cur->x1;
+  for (cury = cur->y1; cury < cur->y2; cury++)
     {
-      guchar *mem = private->mem, *ptr;
-      guint rowstride = private->rowstride;
-      int n;
+      guint16 *p16 = (guint16 *)(mem + cury * rowstride + cur->x1*2);
+      for (i = 0; i < n; i++)
+       *(p16++) = color->pixel;
+    }
+}
 
-      switch (private->depth)
-       {
-       case 1:
-         {
-           int fromx = MIN ((cur->x1+7)&(~7), cur->x2);
-           int begn = fromx - cur->x1, begoff = cur->x1 % 8, endn;
-           guchar begmask, endmask;
-           int body_end = cur->x2 & ~7;
-           int body_len = (body_end - fromx)/8;
-
-           begmask = ((1 << (begn + begoff)) - 1)
-             & ~((1 << (begoff)) - 1);
-           endn = cur->x2 - body_end;
-           endmask = (1 << endn) - 1;
-
-           for (cury = cur->y1; cury < cur->y2; cury++)
-             {
-               ptr = mem + cury*rowstride + (cur->x1 >> 3);
+static void
+gdk_fb_fill_span_simple_24 (GdkDrawable *drawable,
+                           GdkGC       *gc,
+                           GdkSegment  *cur,
+                           GdkColor    *color)
+{
+  int cury;
+  GdkGCFBData *gc_private;
+  GdkDrawableFBData *private;
+  guchar *mem, *ptr;
+  guint rowstride;
+  int n;
+  guchar redval, greenval, blueval;
+  guchar *firstline, *ptr_end;
 
-               if (spot.pixel)
-                 *ptr |= begmask;
-               else
-                 *ptr &= ~begmask;
+  private = GDK_DRAWABLE_FBDATA (drawable);
+  gc_private = GDK_GC_FBDATA (gc);
 
-               curx = fromx;
+  g_assert (gc);
 
-               if (curx < cur->x2)
-                 {
-                   ptr = mem + cury*rowstride + (curx >> 3);
-                   memset (ptr, spot.pixel?0xFF:0, body_len);
+  g_assert (!gc_private->values.clip_mask &&
+           !gc_private->values.tile &&
+           !gc_private->values.stipple &&
+           gc_private->values.function != GDK_INVERT);
 
-                   if (endn)
-                     {
-                       ptr = mem + cury*rowstride + (body_end >> 3);
-                       if (spot.pixel)
-                         *ptr |= endmask;
-                       else
-                         *ptr &= ~endmask;
-                     }
-                 }
-             }
-         }
-         break;
-       case 8:
-         for (cury = cur->y1; cury < cur->y2; cury++)
-           {
-             ptr = mem + cury*rowstride + cur->x1;
-             memset (ptr, spot.pixel, cur->x2 - cur->x1);
-           }
-         break;
-       case 16:
-         {
-           int i;
-           n = cur->x2 - cur->x1;
-           for (cury = cur->y1; cury < cur->y2; cury++)
-             {
-               guint16 *p16 = (guint16 *)(mem + cury * rowstride + cur->x1*2);
-               for (i = 0; i < n; i++)
-                 *(p16++) = spot.pixel;
-             }
-         }
-         break;
-       case 24:
-         {
-           guchar redval = spot.red>>8, greenval=spot.green>>8, blueval=spot.blue>>8;
-           guchar *firstline, *ptr_end;
+  mem = private->mem;
+  rowstride = private->rowstride;
 
-           if ((cur->y2 - cur->y1) <= 0)
-             break;
+  {
+    redval = color->red>>8;
+    greenval = color->green>>8;
+    blueval = color->blue>>8;
+    
+    if ((cur->y2 - cur->y1) <= 0)
+      return;
+    
+    n = (cur->x2 - cur->x1)*3;
+    
+    firstline = ptr = mem + cur->y1 * rowstride + cur->x1*3;
+    ptr_end = ptr+n;
+    while (ptr < ptr_end)
+      {
+       ptr[gdk_display->red_byte] = redval;
+       ptr[gdk_display->green_byte] = greenval;
+       ptr[gdk_display->blue_byte] = blueval;
+       ptr += 3;
+      }
+    for (cury = cur->y1 + 1, ptr = mem + cury * rowstride + cur->x1*3; cury < cur->y2; cury++, ptr += rowstride)
+      {
+       memcpy (ptr, firstline, n);
+      }
+  }
+}
+static void
+gdk_fb_fill_span_simple_32 (GdkDrawable *drawable,
+                           GdkGC       *gc,
+                           GdkSegment  *cur,
+                           GdkColor    *color)
+{
+  int cury;
+  GdkGCFBData *gc_private;
+  GdkDrawableFBData *private;
+  guchar *mem;
+  guint rowstride;
+  int n;
+  int i;
 
-           n = (cur->x2 - cur->x1)*3;
+  private = GDK_DRAWABLE_FBDATA (drawable);
+  gc_private = GDK_GC_FBDATA (gc);
 
-           firstline = ptr = mem + cur->y1 * rowstride + cur->x1*3;
-           ptr_end = ptr+n;
-           while (ptr < ptr_end)
-             {
-               ptr[gdk_display->red_byte] = redval;
-               ptr[gdk_display->green_byte] = greenval;
-               ptr[gdk_display->blue_byte] = blueval;
-               ptr += 3;
-             }
-           for (cury = cur->y1 + 1, ptr = mem + cury * rowstride + cur->x1*3; cury < cur->y2; cury++, ptr += rowstride)
-             {
-               memcpy (ptr, firstline, n);
-             }
-         }
-         break;
-       case 32:
-         {
-           int i;
-           n = cur->x2 - cur->x1;
-           for (cury = cur->y1; cury < cur->y2; cury++)
-             {
-               guint32 *p32 = (guint32 *)(mem + cury * rowstride + cur->x1*4);
-               for (i = 0; i < n; i++)
-                 *(p32++) = spot.pixel;
-             }
-         }
-         break;
-       default:
-         g_assert_not_reached ();
-#if 0
-         for(cury = cur->y1; cury < cur->y2; cury++)
-           {
-             for(curx = cur->x1; curx < cur->x2; curx++)
-               {
-                 gdk_fb_drawable_set_pixel (drawable, gc, curx, cury, &spot, TRUE);
-               }
-           }
-#endif
-         break;
-       }
+  g_assert (gc);
+
+  g_assert (!gc_private->values.clip_mask &&
+           !gc_private->values.tile &&
+           !gc_private->values.stipple &&
+           gc_private->values.function != GDK_INVERT);
+
+  mem = private->mem;
+  rowstride = private->rowstride;
+
+  n = cur->x2 - cur->x1;
+  for (cury = cur->y1; cury < cur->y2; cury++)
+    {
+      guint32 *p32 = (guint32 *)(mem + cury * rowstride + cur->x1*4);
+      for (i = 0; i < n; i++)
+       *(p32++) = color->pixel;
     }
 }
 
+
+
 void
 gdk_fb_fill_spans (GdkDrawable *real_drawable,
                   GdkGC *gc,
@@ -616,7 +709,6 @@ gdk_fb_fill_spans (GdkDrawable *real_drawable,
   GdkColor color;
   GdkRegion *real_clip_region, *tmpreg;
   GdkRectangle draw_rect;
-  GdkVisual *visual = gdk_visual_get_system ();
   gboolean handle_cursor = FALSE;
   GdkDrawable *drawable;
   GdkDrawableFBData *private;
@@ -629,7 +721,7 @@ gdk_fb_fill_spans (GdkDrawable *real_drawable,
   if (GDK_IS_WINDOW (private->wrapper) && GDK_WINDOW_P (private->wrapper)->input_only)
     g_error ("Drawing on the evil input-only!");
 
-  if (gc && (GDK_GC_FBDATA (gc)->values_mask | GDK_GC_FOREGROUND))
+  if (gc && (GDK_GC_FBDATA (gc)->values_mask & GDK_GC_FOREGROUND))
     color = GDK_GC_FBDATA (gc)->values.foreground;
   else if (GDK_IS_WINDOW (private->wrapper))
     color = GDK_WINDOW_P (private->wrapper)->bg_color;
@@ -684,12 +776,12 @@ gdk_fb_fill_spans (GdkDrawable *real_drawable,
          for (j = 0; j < tmpreg->numRects; j++)
            {
              cur = tmpreg->rects[j];
-             gdk_fb_fill_span (drawable, gc, &cur, &color, visual);
+             (GDK_GC_FBDATA (gc)->fill_span) (drawable, gc, &cur, &color);
            }
          gdk_region_destroy (tmpreg);
          break;
        case GDK_OVERLAP_RECTANGLE_IN:
-         gdk_fb_fill_span (drawable, gc, &cur, &color, visual);
+         (GDK_GC_FBDATA (gc)->fill_span) (drawable, gc, &cur, &color);
          break;
        default:
          break;
@@ -809,59 +901,220 @@ gdk_fb_drawable_get_pixel (GdkDrawable *drawable,
 }
 
 static void
-gdk_fb_drawable_set_pixel(GdkDrawable *drawable, GdkGC *gc, int x, int y, GdkColor *spot,
-                         gboolean abs_coords)
+gdk_fb_drawable_set_pixel_1(GdkDrawable *drawable,
+                           GdkGC *gc,
+                           int x,
+                           int y,
+                           gulong pixel)
 {
   GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
   guchar *mem = private->mem;
   guint rowstride = private->rowstride;
+  guchar *ptr;
 
-  if (!abs_coords)
-    {
-      x += private->abs_x;
-      y += private->abs_y;
-    }
+  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+  
+  ptr = mem + (y*rowstride) + (x >> 3);
 
-  switch (private->depth)
+  if (pixel)
+    *ptr |= (1 << (x % 8));
+  else
+    *ptr &= ~(1 << (x % 8));
+}
+
+static void
+gdk_fb_drawable_set_pixel_8(GdkDrawable *drawable,
+                           GdkGC *gc,
+                           int x,
+                           int y,
+                           gulong pixel)
+{
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  guchar *mem = private->mem;
+  guint rowstride = private->rowstride;
+
+  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+
+  mem[x + y*rowstride] = pixel;
+}
+
+static void
+gdk_fb_drawable_set_pixel_16(GdkDrawable *drawable,
+                            GdkGC *gc,
+                            int x,
+                            int y,
+                            gulong pixel)
+{
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  guchar *mem = private->mem;
+  guint rowstride = private->rowstride;
+  guint16 *ptr;
+
+  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+  
+  ptr = (guint16 *)&mem[x*2 + y*rowstride];
+  *ptr = pixel;
+}
+
+static void
+gdk_fb_drawable_set_pixel_24(GdkDrawable *drawable,
+                           GdkGC *gc,
+                           int x,
+                           int y,
+                           gulong pixel)
+{
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  guchar *mem = private->mem;
+  guint rowstride = private->rowstride;
+  guchar *smem;
+  
+  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+  
+  smem = &mem[x*3 + y*rowstride];
+  smem[0] = pixel & 0xff;
+  smem[1] = (pixel >> 8) & 0xff;
+  smem[2] = (pixel >> 16) & 0xff;
+}
+
+static void
+gdk_fb_drawable_set_pixel_32(GdkDrawable *drawable,
+                           GdkGC *gc,
+                           int x,
+                           int y,
+                           gulong pixel)
+{
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  guchar *mem = private->mem;
+  guint rowstride = private->rowstride;
+  guint32 *smem;
+
+  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+  
+  smem = (guint32 *)&mem[x*4 + y*rowstride];
+  *smem = pixel;
+}
+
+
+static GetPixelRet
+gdk_fb_drawable_get_color_1 (GdkDrawable *drawable,
+                            GdkGC *gc,
+                            int x,
+                            int y,
+                            GdkColor *color)
+{
+  GetPixelRet retval = GPR_NONE;
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  guchar *mem = private->mem;
+  guint rowstride = private->rowstride;
+  guchar foo;
+
+  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+  
+  foo = mem[(x >> 3) + y * rowstride];
+  if (foo & (1 << (x % 8)))
+    *color = GDK_GC_FBDATA (gc)->values.foreground;
+  else
     {
-    case 1:
-      {
-       guchar *foo = mem + (y*rowstride) + (x >> 3);
+      retval = GPR_USED_BG;
 
-       if (spot->pixel)
-         *foo |= (1 << (x % 8));
-       else
-         *foo &= ~(1 << (x % 8));
-      }
-      break;
-    case 8:
-      mem[x + y*rowstride] = spot->pixel;
-      break;
-    case 16:
-      {
-       guint16 *p16 = (guint16 *)&mem[x*2 + y*rowstride];
-       *p16 = spot->pixel;
-      }
-      break;
-    case 24:
-      {
-       guchar *smem = &mem[x*3 + y*rowstride];
-       smem[gdk_display->red_byte] = spot->red >> 8;
-       smem[gdk_display->green_byte] = spot->green >> 8;
-       smem[gdk_display->blue_byte] = spot->blue >> 8;
-      };
-      break;
-    case 32:
-      {
-       guint32 *smem = (guint32 *)&mem[x*4 + y*rowstride];
-       *smem = spot->pixel;
-      }
-      break;
-    default:
-      g_assert_not_reached ();
-      break;
+      *color = GDK_GC_FBDATA (gc)->values.background;
     }
+  
+  return retval;
+}
+
+static GetPixelRet
+gdk_fb_drawable_get_color_8 (GdkDrawable *drawable,
+                            GdkGC *gc,
+                            int x,
+                            int y,
+                            GdkColor *color)
+{
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  guchar *mem = private->mem;
+  guint rowstride = private->rowstride;
+  gint pixel;
+
+  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+  
+  pixel = mem[x + y * rowstride];
+  *color = private->colormap->colors[pixel];
+
+  return GPR_NONE;
+}
+static GetPixelRet
+gdk_fb_drawable_get_color_16 (GdkDrawable *drawable,
+                             GdkGC *gc,
+                             int x,
+                             int y,
+                             GdkColor *color)
+{
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  guchar *mem = private->mem;
+  guint rowstride = private->rowstride;
+  guint16 val16;
+
+  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+
+  val16 = *((guint16 *)&mem[x*2 + y*rowstride]);
+
+  color->red = (((1<<gdk_display->modeinfo.red.length) - 1) & (val16 >> gdk_display->modeinfo.red.offset)) << (16 - gdk_display->modeinfo.red.length);
+  color->green = (((1<<gdk_display->modeinfo.green.length) - 1) & (val16 >> gdk_display->modeinfo.green.offset)) << (16 - gdk_display->modeinfo.green.length);
+  color->blue = (((1<<gdk_display->modeinfo.blue.length) - 1) & (val16 >> gdk_display->modeinfo.blue.offset)) << (16 - gdk_display->modeinfo.blue.length);
+
+  color->pixel = val16;
 
+  return GPR_NONE;
+}
+
+static GetPixelRet
+gdk_fb_drawable_get_color_24 (GdkDrawable *drawable,
+                             GdkGC *gc,
+                             int x,
+                             int y,
+                             GdkColor *color)
+{
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  guchar *mem = private->mem;
+  guint rowstride = private->rowstride;
+  guchar *smem;
+
+  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+
+  smem = &mem[x*3 + y*rowstride];
+  color->red = smem[gdk_display->red_byte] << 8;
+  color->green = smem[gdk_display->green_byte] << 8;
+  color->blue = smem[gdk_display->blue_byte] << 8;
+#if (G_BYTE_ORDER == G_BIG_ENDIAN)
+  color->pixel = (smem[0]<<16)|(smem[1]<<8)|smem[2];
+#else
+  color->pixel = smem[0]|(smem[1]<<8)|(smem[2]<<16);
+#endif
+
+  return GPR_NONE;
+}
+
+static GetPixelRet
+gdk_fb_drawable_get_color_32 (GdkDrawable *drawable,
+                             GdkGC *gc,
+                             int x,
+                             int y,
+                             GdkColor *color)
+{
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  guchar *mem = private->mem;
+  guint rowstride = private->rowstride;
+  guchar *smem;
+
+  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+  
+  smem = &mem[x*4 + y*rowstride];
+  color->red = smem[gdk_display->red_byte] << 8;
+  color->green = smem[gdk_display->green_byte] << 8;
+  color->blue = smem[gdk_display->blue_byte] << 8;
+  color->pixel = *(guint32 *)smem;
+
+  return GPR_NONE;
 }
 
 void
@@ -926,6 +1179,183 @@ gdk_fb_drawing_context_finalize (GdkFBDrawingContext *dc)
     gdk_fb_cursor_unhide ();
 }
 
+void
+gdk_fb_draw_drawable_memmove (GdkDrawable *drawable,
+                             GdkGC       *gc,
+                             GdkPixmap   *src,
+                             GdkFBDrawingContext *dc,
+                             gint         start_y,
+                             gint         end_y,
+                             gint         start_x,
+                             gint         end_x,
+                             gint         src_x_off,
+                             gint         src_y_off,
+                             gint         draw_direction)
+{
+  GdkDrawableFBData *src_private = GDK_DRAWABLE_FBDATA (src);
+  guint depth = src_private->depth;
+  guint src_rowstride = src_private->rowstride;
+  guchar *srcmem = src_private->mem;
+  int linelen = (end_x - start_x)*(depth>>3);
+  gint cur_y;
+  
+  for(cur_y = start_y; cur_y*draw_direction < end_y*draw_direction; cur_y += draw_direction)
+    {
+      memmove (dc->mem + (cur_y * dc->rowstride) + start_x*(depth>>3),
+              srcmem + ((cur_y + src_y_off)*src_rowstride) + (start_x + src_x_off)*(depth>>3),
+              linelen);
+    }
+
+}
+
+
+void
+gdk_fb_draw_drawable_generic (GdkDrawable *drawable,
+                             GdkGC       *gc,
+                             GdkPixmap   *src,
+                             GdkFBDrawingContext *dc,
+                             gint         start_y,
+                             gint         end_y,
+                             gint         start_x,
+                             gint         end_x,
+                             gint         src_x_off,
+                             gint         src_y_off,
+                             gint         draw_direction)
+{
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  int cur_x, cur_y;
+
+  for (cur_y = start_y; cur_y*draw_direction < end_y*draw_direction; cur_y+=draw_direction)
+    {
+      for (cur_x = start_x; cur_x < end_x; cur_x++)
+       {
+         GdkColor spot;
+         
+         if (GDK_GC_FBDATA(gc)->values.clip_mask)
+           {
+             int maskx = cur_x + dc->clipxoff, masky = cur_y + dc->clipyoff;
+             guchar foo;
+             
+             foo = dc->clipmem[masky*dc->clip_rowstride + (maskx >> 3)];
+             
+             if (!(foo & (1 << (maskx % 8))))
+               continue;
+           }
+         
+         switch (gdk_fb_drawable_get_pixel (src, gc, cur_x + src_x_off, cur_y + src_y_off, &spot, TRUE, NULL, NULL))
+           {
+           case GPR_AA_GRAYVAL:
+             {
+               GdkColor realspot, fg;
+               guint graylevel = spot.pixel;
+               gint tmp;
+               
+               if (private->depth == 1)
+                 {
+                   if (spot.pixel > 192)
+                     spot = GDK_GC_FBDATA (gc)->values.foreground;
+                   else
+                     spot = GDK_GC_FBDATA (gc)->values.background;
+                   break;
+                 }
+               else
+                 {
+                   if (graylevel >= 254)
+                     {
+                       spot = GDK_GC_FBDATA (gc)->values.foreground;
+                     }
+                   else if (graylevel <= 2)
+                     {
+                       if (!dc->draw_bg)
+                         continue;
+                       
+                       spot = GDK_GC_FBDATA (gc)->values.background;
+                     }
+                   else
+                     {
+                       switch ((GDK_GC_FBDATA (gc)->get_color) (drawable, gc, cur_x, cur_y, &realspot))
+                         {
+                         case GPR_USED_BG:
+                           {
+                             int bgx, bgy;
+                             
+                             bgx = (cur_x - GDK_DRAWABLE_IMPL_FBDATA (dc->bg_relto)->abs_x) % GDK_DRAWABLE_IMPL_FBDATA (dc->bgpm)->width;
+                             bgy = (cur_y - GDK_DRAWABLE_IMPL_FBDATA (dc->bg_relto)->abs_y) % GDK_DRAWABLE_IMPL_FBDATA (dc->bgpm)->height;
+                             gdk_fb_drawable_get_pixel (dc->bgpm, gc, bgx, bgy, &realspot, FALSE, NULL, NULL);
+                           }
+                           break;
+                         case GPR_NONE:
+                           break;
+                         default:
+                           g_assert_not_reached ();
+                           break;
+                         }
+                       
+                       fg = GDK_GC_FBDATA (gc)->values.foreground;
+
+                       /* Now figure out what 'spot' should actually look like */
+                       fg.red >>= 8;
+                       fg.green >>= 8;
+                       fg.blue >>= 8;
+                       realspot.red >>= 8;
+                       realspot.green >>= 8;
+                       realspot.blue >>= 8;
+
+                               
+                       tmp = (fg.red - realspot.red) * graylevel;
+                       spot.red = realspot.red + ((tmp + (tmp >> 8) + 0x80) >> 8);
+                       spot.red <<= 8;
+                       
+                       tmp = (fg.green - realspot.green) * graylevel;
+                       spot.green = realspot.green + ((tmp + (tmp >> 8) + 0x80) >> 8);
+                       spot.green <<= 8;
+                       
+                       tmp = (fg.blue - realspot.blue) * graylevel;
+                       spot.blue = realspot.blue + ((tmp + (tmp >> 8) + 0x80) >> 8);
+                       spot.blue <<= 8;
+                       
+                       /* Now find the pixel for this thingie */
+                       switch (private->depth)
+                         {
+                         case 8:
+                           if (!gdk_colormap_alloc_color (private->colormap, &spot, FALSE, TRUE))
+                             {
+                               g_error ("Can't allocate AA color!");
+                             }
+                           break;
+                         case 16:
+                           spot.pixel = (spot.red >> (16 - gdk_display->modeinfo.red.length)) << gdk_display->modeinfo.red.offset;
+                           spot.pixel |= (spot.green >> (16 - gdk_display->modeinfo.green.length)) << gdk_display->modeinfo.green.offset;
+                           spot.pixel |= (spot.blue >> (16 - gdk_display->modeinfo.blue.length)) << gdk_display->modeinfo.blue.offset;
+                           break;
+                         case 24:
+                         case 32:
+                           spot.pixel = ((spot.red & 0xFF00) >> 8  << (gdk_display->modeinfo.red.offset))
+                             | ((spot.green & 0xFF00) >> 8 << (gdk_display->modeinfo.green.offset))
+                             | ((spot.blue & 0xFF00) >> 8 << (gdk_display->modeinfo.blue.offset));
+                           break;
+                         }
+                     }
+                 }
+             }
+             break;
+           case GPR_USED_BG:
+             if (!dc->draw_bg)
+               continue;
+             break;
+           case GPR_NONE:
+             break;
+           default:
+             g_assert_not_reached ();
+             break;
+           }
+         
+         (GDK_GC_FBDATA (gc)->set_pixel) (drawable, gc, cur_x, cur_y, spot.pixel);
+       }
+    }
+
+}
+
 void
 gdk_fb_draw_drawable_2 (GdkDrawable *drawable,
                        GdkGC       *gc,
@@ -962,12 +1392,14 @@ gdk_fb_draw_drawable_3 (GdkDrawable *drawable,
   GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
   GdkDrawableFBData *src_private = GDK_DRAWABLE_FBDATA (src);
   GdkRectangle rect;
-  guchar *srcmem = GDK_DRAWABLE_FBDATA(src)->mem;
   int src_x_off, src_y_off;
   GdkRegion *tmpreg, *real_clip_region;
   int i;
   int draw_direction = 1;
-  gboolean do_quick_draw;
+  gdk_fb_draw_drawable_func *draw_func = NULL;
+  GdkGCFBData *gc_private;
+
+  g_assert (gc);
 
   if (GDK_IS_WINDOW (private->wrapper))
     {
@@ -977,6 +1409,8 @@ gdk_fb_draw_drawable_3 (GdkDrawable *drawable,
        g_error ("Drawing on the evil input-only!");
     }
 
+  gc_private = GDK_GC_FBDATA (gc);
+  
   if (drawable == src)
     {
       GdkRegionBox srcb, destb;
@@ -991,18 +1425,40 @@ gdk_fb_draw_drawable_3 (GdkDrawable *drawable,
 
       if (EXTENTCHECK (&srcb, &destb) && ydest > ysrc)
        draw_direction = -1;
-#if 0
-       {
-         GdkDrawableFBData *fbd = src_private;
-
-         /* One lame hack deserves another ;-) */
-         srcmem = g_alloca (fbd->rowstride * (fbd->lim_y - fbd->llim_y));
-         memmove (srcmem, dc->mem + (fbd->rowstride * fbd->llim_y), fbd->rowstride * (fbd->lim_y - fbd->llim_y));
-         srcmem -= (fbd->rowstride * fbd->llim_y);
-       }
-#endif
     }
 
+  switch (src_private->depth)
+    {
+    case 1:
+      draw_func = gc_private->draw_drawable[GDK_FB_SRC_BPP_1];
+      break;
+    case 8:
+      draw_func = gc_private->draw_drawable[GDK_FB_SRC_BPP_8];
+      break;
+    case 16:
+      draw_func = gc_private->draw_drawable[GDK_FB_SRC_BPP_16];
+      break;
+    case 24:
+      draw_func = gc_private->draw_drawable[GDK_FB_SRC_BPP_24];
+      break;
+    case 32:
+      draw_func = gc_private->draw_drawable[GDK_FB_SRC_BPP_32];
+      break;
+    case 77:
+      draw_func = gc_private->draw_drawable[GDK_FB_SRC_BPP_7_AA_GRAYVAL];
+      break;
+    case 78:
+      draw_func = gc_private->draw_drawable[GDK_FB_SRC_BPP_8_AA_GRAYVAL];
+      break;
+    case 0:
+      g_warning ("gdk_fb_draw_drawable_3() - source drawable with zero depth, ignoring\n");
+      return;
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+    }
+  
   /* Do some magic to avoid creating extra regions unnecessarily */
   tmpreg = dc->real_clip_region;
 
@@ -1026,15 +1482,10 @@ gdk_fb_draw_drawable_3 (GdkDrawable *drawable,
   src_x_off = (src_private->abs_x + xsrc) - (private->abs_x + xdest);
   src_y_off = (src_private->abs_y + ysrc) - (private->abs_y + ydest);
 
-  do_quick_draw = src_private->depth == private->depth  &&
-    src_private->depth >= 8 &&
-    src_private->depth <= 32 &&
-    (!gc || !GDK_GC_FBDATA (gc)->values.clip_mask);
-
   for(i = 0; i < real_clip_region->numRects; i++)
     {
       GdkRegionBox *cur = &real_clip_region->rects[i];
-      int start_y, end_y, cur_y;
+      int start_y, end_y;
 
       if (draw_direction > 0)
        {
@@ -1047,148 +1498,24 @@ gdk_fb_draw_drawable_3 (GdkDrawable *drawable,
          end_y = cur->y1 - 1;
        }
 
-      if (do_quick_draw)
-       {
-         guint depth = src_private->depth;
-         guint src_rowstride = src_private->rowstride;
-         int linelen = (cur->x2 - cur->x1)*(depth>>3);
-
-         for(cur_y = start_y; cur_y*draw_direction < end_y*draw_direction; cur_y += draw_direction)
-           {
-             memmove (dc->mem + (cur_y * dc->rowstride) + cur->x1*(depth>>3),
-                      srcmem + ((cur_y + src_y_off)*src_rowstride) + (cur->x1 + src_x_off)*(depth>>3),
-                      linelen);
-           }
-       }
-      else
-       {
-         int cur_x;
-
-         for (cur_y = start_y; cur_y*draw_direction < end_y*draw_direction; cur_y+=draw_direction)
-           {
-             for (cur_x = cur->x1; cur_x < cur->x2; cur_x++)
-               {
-                 GdkColor spot;
-
-                 if (gc && GDK_GC_FBDATA(gc)->values.clip_mask)
-                   {
-                     int maskx = cur_x+dc->clipxoff, masky = cur_y + dc->clipyoff;
-                     guchar foo;
-
-                     foo = dc->clipmem[masky*dc->clip_rowstride + (maskx >> 3)];
-
-                     if (!(foo & (1 << (maskx % 8))))
-                       continue;
-                   }
-
-                 switch (gdk_fb_drawable_get_pixel (src, gc, cur_x + src_x_off, cur_y + src_y_off, &spot, TRUE, NULL, NULL))
-                   {
-                   case GPR_AA_GRAYVAL:
-                     {
-                       GdkColor realspot, fg;
-                       guint graylevel = spot.pixel;
-                       gint tmp;
-
-                       if (private->depth == 1)
-                         {
-                           if (spot.pixel > 192)
-                             spot = GDK_GC_FBDATA (gc)->values.foreground;
-                           else
-                             spot = GDK_GC_FBDATA (gc)->values.background;
-                           break;
-                         }
-                       else
-                         {
-                           if (graylevel >= 254)
-                             {
-                               spot = GDK_GC_FBDATA (gc)->values.foreground;
-                             }
-                           else if (graylevel <= 2)
-                             {
-                               if (!dc->draw_bg)
-                                 continue;
-
-                               spot = GDK_GC_FBDATA (gc)->values.background;
-                             }
-                           else
-                             {
-                               switch (gdk_fb_drawable_get_pixel (drawable, gc, cur_x, cur_y, &realspot, TRUE, dc->bg_relto, dc->bgpm))
-                                 {
-                                 case GPR_NONE:
-                                 case GPR_USED_BG:
-                                   break;
-                                 default:
-                                   g_assert_not_reached ();
-                                   break;
-                                 }
-
-                               fg = GDK_GC_FBDATA (gc)->values.foreground;
-                               /* Now figure out what 'spot' should actually look like */
-                               fg.red >>= 8;
-                               fg.green >>= 8;
-                               fg.blue >>= 8;
-                               realspot.red >>= 8;
-                               realspot.green >>= 8;
-                               realspot.blue >>= 8;
-
-                               tmp = (fg.red - realspot.red) * graylevel;
-                               spot.red = realspot.red + ((tmp + (tmp >> 8) + 0x80) >> 8);
-                               spot.red <<= 8;
-
-                               tmp = (fg.green - realspot.green) * graylevel;
-                               spot.green = realspot.green + ((tmp + (tmp >> 8) + 0x80) >> 8);
-                               spot.green <<= 8;
-
-                               tmp = (fg.blue - realspot.blue) * graylevel;
-                               spot.blue = realspot.blue + ((tmp + (tmp >> 8) + 0x80) >> 8);
-                               spot.blue <<= 8;
-
-                               /* Now find the pixel for this thingie */
-                               switch (private->depth)
-                                 {
-                                 case 8:
-                                   if (!gdk_colormap_alloc_color (private->colormap, &spot, FALSE, TRUE))
-                                     {
-                                       g_error ("Can't allocate AA color!");
-                                     }
-                                   break;
-                                 case 16:
-                                   spot.pixel = (spot.red >> (16 - gdk_display->modeinfo.red.length)) << gdk_display->modeinfo.red.offset;
-                                   spot.pixel |= (spot.green >> (16 - gdk_display->modeinfo.green.length)) << gdk_display->modeinfo.green.offset;
-                                   spot.pixel |= (spot.blue >> (16 - gdk_display->modeinfo.blue.length)) << gdk_display->modeinfo.blue.offset;
-                                   break;
-                                 case 24:
-                                 case 32:
-                                   spot.pixel = ((spot.red & 0xFF00) << (gdk_display->modeinfo.red.offset - 8))
-                                     | ((spot.green & 0xFF00) << (gdk_display->modeinfo.green.offset - 8))
-                                     | ((spot.blue & 0xFF00) << (gdk_display->modeinfo.blue.offset - 8));
-                                   break;
-                                 }
-                             }
-                         }
-                     }
-                     break;
-                   case GPR_USED_BG:
-                     if (!dc->draw_bg)
-                       continue;
-                     break;
-                   case GPR_NONE:
-                     break;
-                   default:
-                     g_assert_not_reached ();
-                     break;
-                   }
-
-                 gdk_fb_drawable_set_pixel (drawable, gc, cur_x, cur_y, &spot, src_private->depth);
-               }
-           }
-       }
+      (*draw_func) (drawable,
+                   gc,
+                   src,
+                   dc,
+                   start_y,
+                   end_y,
+                   cur->x1,
+                   cur->x2,
+                   src_x_off,
+                   src_y_off,
+                   draw_direction);
     }
 
  out:
   gdk_region_destroy (real_clip_region);
 }
 
+
 void
 gdk_fb_draw_drawable (GdkDrawable *drawable,
                      GdkGC       *gc,
@@ -1203,6 +1530,181 @@ gdk_fb_draw_drawable (GdkDrawable *drawable,
   gdk_fb_draw_drawable_2 (drawable, gc, GDK_DRAWABLE_IMPL (src), xsrc, ysrc, xdest, ydest, width, height, TRUE, TRUE);
 }
 
+
+static void
+gdk_fb_draw_drawable_aa_24 (GdkDrawable *drawable,
+                           GdkGC       *gc,
+                           GdkPixmap   *src,
+                           GdkFBDrawingContext *dc,
+                           gint         start_y,
+                           gint         end_y,
+                           gint         start_x,
+                           gint         end_x,
+                           gint         src_x_off,
+                           gint         src_y_off,
+                           gint         draw_direction)
+{
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  int x, y;
+  GdkGCFBData *gc_private;
+  guchar *dmem = private->mem;
+  guint dst_rowstride = private->rowstride;
+  guchar *smem = GDK_DRAWABLE_FBDATA (src)->mem;
+  guint src_rowstride = GDK_DRAWABLE_FBDATA (src)->rowstride;
+  guchar *dst;
+  guint grayval;
+  gint r, g, b, tmp;
+  GdkColor fg;
+  gint fg_r, fg_g, fg_b;
+  
+  gc_private = GDK_GC_FBDATA (gc);
+
+  fg = GDK_GC_FBDATA (gc)->values.foreground;
+  fg_r = fg.red >> 8;
+  fg_g = fg.green >> 8;
+  fg_b = fg.blue >> 8;
+  
+  for (y = start_y; y*draw_direction < end_y*draw_direction; y+=draw_direction)
+    {
+      for (x = start_x; x < end_x; x++)
+       {
+         grayval = smem[x + src_x_off + (y + src_y_off) * src_rowstride];
+
+         if ((grayval <= 2) && (!dc->draw_bg))
+           continue;
+
+         dst = &dmem[x*3 + y*dst_rowstride];
+         
+         if (grayval >= 254)
+           {
+             dst[gdk_display->red_byte] = fg_r;
+             dst[gdk_display->green_byte] = fg_g;
+             dst[gdk_display->blue_byte] = fg_b;
+           }
+         else if (grayval <= 2)
+           {
+             dst[gdk_display->red_byte] = GDK_GC_FBDATA (gc)->values.background.red >> 8;
+             dst[gdk_display->green_byte] = GDK_GC_FBDATA (gc)->values.background.green >> 8;
+             dst[gdk_display->blue_byte] = GDK_GC_FBDATA (gc)->values.background.blue >> 8;
+           }
+         else
+           {
+             r = dst[gdk_display->red_byte];
+             tmp = (fg_r - r) * (gint)grayval;
+             r = r + ((tmp + (tmp >> 8) + 0x80) >> 8);
+             dst[gdk_display->red_byte] = r;
+
+             g = dst[gdk_display->green_byte];
+             tmp = (fg_g - g) * (gint)grayval;
+             g = g + ((tmp + (tmp >> 8) + 0x80) >> 8);
+             dst[gdk_display->green_byte] = g;
+
+             b = dst[gdk_display->blue_byte];
+             tmp = (fg_b - b) * (gint)grayval;
+             b = b + ((tmp + (tmp >> 8) + 0x80) >> 8);
+             dst[gdk_display->blue_byte] = b;
+           }
+       }
+    }
+}
+
+
+void
+_gdk_fb_gc_calc_state (GdkGC           *gc,
+                      GdkGCValuesMask  changed)
+{
+  GdkGCFBData *gc_private;
+  int i;
+
+  gc_private = GDK_GC_FBDATA (gc);
+
+  gc_private->fill_span = gdk_fb_fill_span_general;
+
+  for (i=0;i<GDK_NUM_FB_SRCBPP;i++)
+    gc_private->draw_drawable[i] = gdk_fb_draw_drawable_generic;
+  
+  if (changed & _GDK_FB_GC_DEPTH)
+    switch (gc_private->depth)
+      {
+      case 1:
+       gc_private->set_pixel = gdk_fb_drawable_set_pixel_1;
+       gc_private->get_color = gdk_fb_drawable_get_color_1;
+       break;
+      case 8:
+       gc_private->set_pixel = gdk_fb_drawable_set_pixel_8;
+       gc_private->get_color = gdk_fb_drawable_get_color_8;
+       break;
+      case 16:
+       gc_private->set_pixel = gdk_fb_drawable_set_pixel_16;
+       gc_private->get_color = gdk_fb_drawable_get_color_16;
+       break;
+      case 24:
+       gc_private->set_pixel = gdk_fb_drawable_set_pixel_24;
+       gc_private->get_color = gdk_fb_drawable_get_color_24;
+       break;
+      case 32:
+       gc_private->set_pixel = gdk_fb_drawable_set_pixel_32;
+       gc_private->get_color = gdk_fb_drawable_get_color_32;
+       break;
+      default:
+       g_assert_not_reached ();
+       break;
+      }
+
+  if (!gc_private->values.clip_mask)
+    {
+    switch (gc_private->depth)
+      {
+      case 8:
+       gc_private->draw_drawable[GDK_FB_SRC_BPP_8] = gdk_fb_draw_drawable_memmove;
+       break;
+      case 16:
+       gc_private->draw_drawable[GDK_FB_SRC_BPP_16] = gdk_fb_draw_drawable_memmove;
+       break;
+      case 24:
+       if (getenv("foo") && strcmp(getenv("foo"), "bar")==0)
+         gc_private->draw_drawable[GDK_FB_SRC_BPP_8_AA_GRAYVAL] = gdk_fb_draw_drawable_aa_24;
+       gc_private->draw_drawable[GDK_FB_SRC_BPP_24] = gdk_fb_draw_drawable_memmove;
+       break;
+      case 32:
+       gc_private->draw_drawable[GDK_FB_SRC_BPP_32] = gdk_fb_draw_drawable_memmove;
+       break;
+      }
+      
+    }
+
+  
+  if (!gc_private->values.clip_mask &&
+      !gc_private->values.tile &&
+      !gc_private->values.stipple &&
+       gc_private->values.function != GDK_INVERT)
+    {
+      switch (gc_private->depth)
+       {
+       case 1:
+         gc_private->fill_span = gdk_fb_fill_span_simple_1;
+         break;
+       case 8:
+         gc_private->fill_span = gdk_fb_fill_span_simple_8;
+         break;
+       case 16:
+         gc_private->fill_span = gdk_fb_fill_span_simple_16;
+         break;
+       case 24:
+         gc_private->fill_span = gdk_fb_fill_span_simple_24;
+         break;
+       case 32:
+         gc_private->fill_span = gdk_fb_fill_span_simple_32;
+         break;
+       default:
+         g_assert_not_reached ();
+         break;
+    }
+    }
+
+}
+
+
 static void
 gdk_fb_draw_text(GdkDrawable    *drawable,
                 GdkFont        *font,
index 36c9cfd8c153f44f2de895993e06fdc93f24d667..89ae218e9054a60f9d2457b49486872416624043 100644 (file)
@@ -204,7 +204,7 @@ fb_events_dispatch (gpointer source_data,
 
   GDK_THREADS_ENTER ();
 
-  while (event = gdk_event_unqueue ())
+  while ((event = gdk_event_unqueue ()))
     {
       if (event->type == GDK_EXPOSE &&
          event->expose.window == gdk_parent_root)
index 62bb2b78f1039c4dec1c1a3f33b63b69065bc495..44a06ff9825cdb4a9bd8aef94d34c5d898032286 100644 (file)
@@ -74,15 +74,19 @@ _gdk_fb_gc_new (GdkDrawable      *drawable,
                GdkGCValuesMask   values_mask)
 {
   GdkGC *gc;
-  GdkGC *private;
-  GdkGCFBData *data;
+  GdkGCFBData *private;
   
   gc = GDK_GC (g_object_new (gdk_gc_fb_get_type (), NULL));
-  private = (GdkGC *)gc;
 
-  data = (GdkGCFBData *)gc;
-  data->values.foreground.pixel = 255;
-  data->values.foreground.red = data->values.foreground.green = data->values.foreground.blue = 65535;
+  private = (GdkGCFBData *)gc;
+  
+  private->depth = GDK_DRAWABLE_FBDATA (drawable)->depth;
+  private->values.foreground.pixel = 255;
+  private->values.foreground.red =
+    private->values.foreground.green =
+    private->values.foreground.blue = 65535;
+
+  _gdk_fb_gc_calc_state (gc, _GDK_FB_GC_DEPTH);
 
   gdk_fb_gc_set_values (gc, values, values_mask);
 
@@ -259,6 +263,8 @@ gdk_fb_gc_set_values (GdkGC           *gc,
       private->values.join_style = values->join_style;
       private->values_mask |= GDK_GC_JOIN_STYLE;
     }
+
+  _gdk_fb_gc_calc_state (gc, values_mask);
 }
 
 static void
@@ -298,6 +304,8 @@ gc_unset_cmask(GdkGC *gc)
       data->values.clip_mask = NULL;
       data->values_mask &= ~ GDK_GC_CLIP_MASK;
     }
+
+  _gdk_fb_gc_calc_state (gc, GDK_GC_CLIP_MASK);
 }
 
 void
@@ -326,6 +334,8 @@ gdk_gc_set_clip_rectangle (GdkGC    *gc,
   data->values.clip_y_origin = 0;
 
   gc_unset_cmask (gc);
+
+  _gdk_fb_gc_calc_state (gc, GDK_GC_CLIP_X_ORIGIN|GDK_GC_CLIP_Y_ORIGIN);
 } 
 
 void
@@ -357,6 +367,8 @@ gdk_gc_set_clip_region (GdkGC         *gc,
   data->values.clip_y_origin = 0;
 
   gc_unset_cmask (gc);
+  
+  _gdk_fb_gc_calc_state (gc, GDK_GC_CLIP_X_ORIGIN|GDK_GC_CLIP_Y_ORIGIN);
 }
 
 
index 58ba0102647d750970cf6fcbe01735f1bc114600..3cc3a9b71ff1c6b3cad42237acb557d53bd1d773 100644 (file)
@@ -39,3 +39,4 @@ GdkEventMask _gdk_fb_pointer_grab_events, _gdk_fb_keyboard_grab_events;
 GdkFBWindow *gdk_root_window = NULL;
 GdkFBDisplay *gdk_display = NULL;
 GdkCursor *_gdk_fb_pointer_grab_cursor;
+GdkGC *_gdk_fb_screen_gc = NULL;
index 6b728a1bf59bc22ff0bbbf624a0c318d96d2a67e..3c112fe60a4fa2c3e86bae6bba1fa9f06eb2d8f4 100644 (file)
@@ -201,7 +201,7 @@ _gdk_fb_get_image (GdkDrawable *drawable,
   fbd.drawable_data.window_type = GDK_DRAWABLE_PIXMAP;
 
   gdk_fb_draw_drawable_2 ((GdkPixmap *)&fbd,
-                         NULL,
+                         _gdk_fb_screen_gc,
                          drawable,
                          x, y,
                          0, 0,
index 76d029f6eb42a14fd28d7b6ab6f144093755684d..c71572f24db4e99f251a0dfa0647bf22337542ff 100644 (file)
@@ -57,6 +57,8 @@
 typedef struct _GdkDrawableFBData GdkDrawableFBData;
 typedef struct _GdkWindowFBData GdkWindowFBData;
 typedef struct _GdkPixmapFBData GdkPixmapFBData;
+typedef struct _GdkFBDrawingContext GdkFBDrawingContext;
+
 #define GDK_DRAWABLE_PIXMAP (GDK_WINDOW_FOREIGN+1)
 
 struct _GdkDrawableFBData
@@ -161,6 +163,36 @@ typedef struct {
 #define GDK_GC_FBDATA(x) ((GdkGCFBData *)(x))
 #define GDK_GC_P(x) ((GdkGC *)(x))
 
+typedef enum {
+  GPR_USED_BG,
+  GPR_AA_GRAYVAL,
+  GPR_NONE,
+  GPR_ERR_BOUNDS
+} GetPixelRet;
+
+typedef enum {
+  GDK_FB_SRC_BPP_1,
+  GDK_FB_SRC_BPP_8,
+  GDK_FB_SRC_BPP_16,
+  GDK_FB_SRC_BPP_24,
+  GDK_FB_SRC_BPP_32,
+  GDK_FB_SRC_BPP_7_AA_GRAYVAL,
+  GDK_FB_SRC_BPP_8_AA_GRAYVAL,
+  GDK_NUM_FB_SRCBPP
+} GdkFbSrcBPP;
+
+typedef void gdk_fb_draw_drawable_func (GdkDrawable *drawable,
+                                       GdkGC       *gc,
+                                       GdkPixmap   *src,
+                                       GdkFBDrawingContext *dc,
+                                       gint         start_y,
+                                       gint         end_y,
+                                       gint         start_x,
+                                       gint         end_x,
+                                       gint         src_x_off,
+                                       gint         src_y_off,
+                                       gint         draw_direction);
+
 typedef struct {
   GdkGC parent_instance;
 
@@ -170,48 +202,88 @@ typedef struct {
   GdkGCValues values;
   gint dash_offset;
   gushort dash_list_len;
-  guchar depth, alu;
+  guchar alu;
+
+  /* The GC can only be used with target drawables of
+   * the same depth as the initial drawable
+   * specified in gd_gc_new().
+   */
+  guchar depth;
+  
+  /* Calculated state: */
+  /* These functions can only be called for drawables
+   * that have the same depth as the gc. 
+   */
+  void        (*set_pixel) (GdkDrawable    *drawable,
+                           GdkGC          *gc,
+                           int             x,
+                           int             y,
+                           gulong          pixel);
+
+  GetPixelRet (*get_color) (GdkDrawable      *drawable,
+                           GdkGC            *gc,
+                           int               x,
+                           int               y,
+                           GdkColor         *color);
+  
+  void        (*fill_span) (GdkDrawable *drawable,
+                           GdkGC       *gc,
+                           GdkSegment  *cur,
+                           GdkColor    *color);
+
+  gdk_fb_draw_drawable_func *draw_drawable[GDK_NUM_FB_SRCBPP];
 } GdkGCFBData;
 
 typedef struct {
   GdkGCClass parent_class;
 } GdkGCFBClass;
 
+
+extern GdkGC *_gdk_fb_screen_gc;
+
 GType gdk_gc_fb_get_type (void) G_GNUC_CONST;
 
 /* Routines from gdkgeometry-fb.c */
 
-void _gdk_window_init_position     (GdkWindow    *window);
-void _gdk_window_move_resize_child (GdkWindow    *window,
-                                   gint          x,
-                                   gint          y,
-                                   gint          width,
-                                   gint          height);
-void _gdk_window_process_expose    (GdkWindow    *window,
-                                   gulong        serial,
-                                   GdkRectangle *area);
-void gdk_window_invalidate_region_clear(GdkWindow *window, GdkRegion *region);
-void gdk_window_invalidate_rect_clear(GdkWindow *window, GdkRectangle *rect);
-GdkGC *_gdk_fb_gc_new(GdkDrawable *drawable, GdkGCValues *values, GdkGCValuesMask values_mask);
-
-GdkImage*_gdk_fb_get_image (GdkDrawable *drawable,
-                           gint         x,
-                           gint         y,
-                           gint         width,
-                           gint         height);
-  
-void gdk_fb_drawable_clear (GdkDrawable *drawable);
-void gdk_fb_draw_drawable  (GdkDrawable    *drawable,
-                           GdkGC          *gc,
-                           GdkPixmap      *src,
-                           gint            xsrc,
-                           gint            ysrc,
-                           gint            xdest,
-                           gint            ydest,
-                           gint            width,
-                           gint            height);
-
-typedef struct {
+void      _gdk_window_init_position          (GdkWindow       *window);
+void      _gdk_window_move_resize_child      (GdkWindow       *window,
+                                             gint             x,
+                                             gint             y,
+                                             gint             width,
+                                             gint             height);
+void      _gdk_window_process_expose         (GdkWindow       *window,
+                                             gulong           serial,
+                                             GdkRectangle    *area);
+void      gdk_window_invalidate_region_clear (GdkWindow       *window,
+                                             GdkRegion       *region);
+void      gdk_window_invalidate_rect_clear   (GdkWindow       *window,
+                                             GdkRectangle    *rect);
+
+GdkGC *   _gdk_fb_gc_new                     (GdkDrawable     *drawable,
+                                             GdkGCValues     *values,
+                                             GdkGCValuesMask  values_mask);
+
+#define _GDK_FB_GC_DEPTH (1<<31)
+void      _gdk_fb_gc_calc_state              (GdkGC           *gc,
+                                             GdkGCValuesMask  changed);
+
+GdkImage *_gdk_fb_get_image                  (GdkDrawable     *drawable,
+                                             gint             x,
+                                             gint             y,
+                                             gint             width,
+                                             gint             height);
+void      gdk_fb_drawable_clear              (GdkDrawable     *drawable);
+void      gdk_fb_draw_drawable               (GdkDrawable     *drawable,
+                                             GdkGC           *gc,
+                                             GdkPixmap       *src,
+                                             gint             xsrc,
+                                             gint             ysrc,
+                                             gint             xdest,
+                                             gint             ydest,
+                                             gint             width,
+                                             gint             height);
+
+struct _GdkFBDrawingContext {
   GdkWindow *bg_relto;
   GdkPixmap *bgpm;
 
@@ -226,7 +298,7 @@ typedef struct {
   gboolean draw_bg : 1;
   gboolean copy_region : 1;
   gboolean handle_cursor : 1;
-} GdkFBDrawingContext;
+};
 
 void gdk_fb_drawing_context_init(GdkFBDrawingContext *dc, GdkDrawable *drawable,
                                 GdkGC *gc, gboolean draw_bg, gboolean do_clipping);
index dd0e86442aa001661dc16c8a4a77db9deb0b9e05..f7d300d389e9600690c2a14ce5e69d2c4830f43d 100644 (file)
@@ -135,6 +135,9 @@ _gdk_windowing_window_init (void)
 
   GDK_DRAWABLE_IMPL_FBDATA (gdk_parent_root)->lim_x = attr.width;
   GDK_DRAWABLE_IMPL_FBDATA (gdk_parent_root)->lim_y = attr.height;
+
+  _gdk_fb_screen_gc = gdk_gc_new (gdk_parent_root);
+  
   gdk_fb_drawable_clear (gdk_parent_root);
 }
 
@@ -871,7 +874,9 @@ gdk_fb_window_move_resize (GdkWindow *window,
                    {
                      GdkRegionBox *reg = ltmp->data;
 
-                     gdk_fb_draw_drawable_3 (GDK_DRAWABLE_IMPL(gdk_parent_root), NULL, GDK_DRAWABLE_IMPL(gdk_parent_root),
+                     gdk_fb_draw_drawable_3 (GDK_DRAWABLE_IMPL(gdk_parent_root),
+                                             _gdk_fb_screen_gc,
+                                             GDK_DRAWABLE_IMPL(gdk_parent_root),
                                              &fbdc,
                                              (reg->x1 - dx),
                                              (reg->y1 - dy),
@@ -1018,7 +1023,7 @@ _gdk_windowing_window_clear_area (GdkWindow *window,
              xstep = GDK_DRAWABLE_IMPL_FBDATA (bgpm)->width - draww;
 
              gdk_fb_draw_drawable_3 (GDK_DRAWABLE_IMPL (window),
-                                     NULL,
+                                     _gdk_fb_screen_gc,
                                      GDK_DRAWABLE_IMPL (bgpm),
                                      &fbdc,
                                      draww, drawh,
@@ -1030,7 +1035,7 @@ _gdk_windowing_window_clear_area (GdkWindow *window,
       gdk_fb_drawing_context_finalize (&fbdc);
     }
   else if (!bgpm)
-    gdk_fb_draw_rectangle (GDK_DRAWABLE_IMPL (window), NULL, TRUE, x, y, width, height);
+    gdk_fb_draw_rectangle (GDK_DRAWABLE_IMPL (window), _gdk_fb_screen_gc, TRUE, x, y, width, height);
 }
 
 /* What's the diff? */
index e975d364e4d4878fad6c9384f64205e2c3c332fc..527e0dc1cf9f54318149efa66ac5f6e271e58999 100644 (file)
@@ -23,16 +23,9 @@ typedef struct _miDash *miDashPtr;
 #define CT_YXSORTED             14
 #define CT_YXBANDED             18
 
-typedef union {
-  guint32 val;
-  gpointer ptr;
-} ChangeGCVal, *ChangeGCValPtr;
-
 #define PixmapBytePad(w, d) (w)
 #define BitmapBytePad(w) (w)
 
-typedef GdkSegment BoxRec, *BoxPtr;
-
 typedef struct _miArc {
     gint16 x, y;
     guint16   width, height;