 2c396fea9f
			
		
	
	2c396fea9f
	
	
	
		
			
			2001-05-10 Alexander Larsson <alexl@redhat.com> * gdk/linux-fb/gdkprivate-fb.h: Make sure you can compile out the implementation/wrapper assert macros. * gdk/linux-fb/gdkdrawable-fb2.c: Check implementation/wrappers, initialize type for pixmap dummys. * gdk/linux-fb/gdkimage-fb.c (_gdk_fb_get_image): Hide the cursor if reading from the screen. * gdk/linux-fb/gdkrender-fb.c (gdk_fb_fill_span_generic): Fix sign bug in tiling code. * gdk/linux-fb/gdkwindow-fb.c (_gdk_windowing_window_clear_area): Handle background pixmaps.
		
			
				
	
	
		
			1454 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1454 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "config.h"
 | |
| #include "gdkprivate-fb.h"
 | |
| #include <string.h>
 | |
| #include <signal.h>
 | |
| #include <sys/time.h>
 | |
| 
 | |
| /*
 | |
|  * Reading pixel values from a generic drawable.
 | |
|  */
 | |
| 
 | |
| static GetPixelRet
 | |
| gdk_fb_drawable_get_color (GdkDrawable *drawable,
 | |
| 			   GdkGC *gc,
 | |
| 			   int x,
 | |
| 			   int y,
 | |
| 			   GdkColor *spot)
 | |
| {
 | |
|   GetPixelRet retval = GPR_NONE;
 | |
|   GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
 | |
|   guchar *mem = private->mem;
 | |
|   guint rowstride = private->rowstride;
 | |
| 
 | |
|   switch (private->depth)
 | |
|     {
 | |
|     case 1:
 | |
|       {
 | |
| 	guchar foo = mem[(x >> 3) + y * rowstride];
 | |
| 	if (foo & (1 << (x % 8)))
 | |
| 	  *spot = GDK_GC_FBDATA (gc)->values.foreground;
 | |
| 	else
 | |
| 	  {
 | |
| 	    retval = GPR_USED_BG;
 | |
| 	    *spot = GDK_GC_FBDATA (gc)->values.background;
 | |
| 	  }
 | |
|       }
 | |
|       break;
 | |
|     case 71:
 | |
|       if (mem[x + y * rowstride])
 | |
| 	*spot = GDK_GC_FBDATA (gc)->values.foreground;
 | |
|       else
 | |
| 	*spot = GDK_GC_FBDATA (gc)->values.background;
 | |
|       break;
 | |
|     case 77:
 | |
|       retval = GPR_AA_GRAYVAL;
 | |
|       spot->pixel = mem[x + y * rowstride] << 1;
 | |
|       spot->red = spot->green = spot->blue = spot->pixel << 8;
 | |
|       break;
 | |
|     case 78: /* AA mode */
 | |
|       retval = GPR_AA_GRAYVAL;
 | |
|       spot->pixel = mem[x + y * rowstride];
 | |
|       spot->red = spot->green = spot->blue = spot->pixel << 8;
 | |
|       break;
 | |
|     case 8:
 | |
|       spot->pixel = mem[x + y * rowstride];
 | |
|       *spot = private->colormap->colors[spot->pixel];
 | |
|       break;
 | |
|     case 16:
 | |
|       {
 | |
| 	guint16 val16 = *((guint16 *)&mem[x*2 + y*rowstride]);
 | |
| 
 | |
| 	spot->red = (((1<<gdk_display->modeinfo.red.length) - 1) & (val16 >> gdk_display->modeinfo.red.offset)) << (16 - gdk_display->modeinfo.red.length);
 | |
| 	spot->green = (((1<<gdk_display->modeinfo.green.length) - 1) & (val16 >> gdk_display->modeinfo.green.offset)) << (16 - gdk_display->modeinfo.green.length);
 | |
| 	spot->blue = (((1<<gdk_display->modeinfo.blue.length) - 1) & (val16 >> gdk_display->modeinfo.blue.offset)) << (16 - gdk_display->modeinfo.blue.length);
 | |
| 
 | |
| 	spot->pixel = val16;
 | |
|       }
 | |
|       break;
 | |
|     case 24:
 | |
|       {
 | |
| 	guchar *smem = &mem[x*3 + y*rowstride];
 | |
| 	spot->red = smem[gdk_display->red_byte] << 8;
 | |
| 	spot->green = smem[gdk_display->green_byte] << 8;
 | |
| 	spot->blue = smem[gdk_display->blue_byte] << 8;
 | |
| #if (G_BYTE_ORDER == G_BIG_ENDIAN)
 | |
| 	spot->pixel = (smem[0]<<16)|(smem[1]<<8)|smem[2];
 | |
| #else
 | |
| 	spot->pixel = smem[0]|(smem[1]<<8)|(smem[2]<<16);
 | |
| #endif
 | |
|       }
 | |
|       break;
 | |
|     case 32:
 | |
|       {
 | |
| 	guchar *smem = &mem[x*4 + y*rowstride];
 | |
| 	spot->red = smem[gdk_display->red_byte] << 8;
 | |
| 	spot->green = smem[gdk_display->green_byte] << 8;
 | |
| 	spot->blue = smem[gdk_display->blue_byte] << 8;
 | |
| 	spot->pixel = *(guint32 *)smem;
 | |
|       }
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|   return retval;
 | |
| }
 | |
| 
 | |
| /*************************************
 | |
|  * gc->get_color() implementations
 | |
|  *************************************/
 | |
| 
 | |
| static GetPixelRet
 | |
| gdk_fb_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
 | |
|     {
 | |
|       retval = GPR_USED_BG;
 | |
| 
 | |
|       *color = GDK_GC_FBDATA (gc)->values.background;
 | |
|     }
 | |
|   
 | |
|   return retval;
 | |
| }
 | |
| 
 | |
| static GetPixelRet
 | |
| gdk_fb_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_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_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_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;
 | |
| }
 | |
| 
 | |
| /*************************************
 | |
|  * gc->set_pixel() implementations
 | |
|  *************************************/
 | |
| 
 | |
| static void
 | |
| gdk_fb_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;
 | |
| 
 | |
|   g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
 | |
|   
 | |
|   ptr = mem + (y*rowstride) + (x >> 3);
 | |
| 
 | |
|   if (pixel)
 | |
|     *ptr |= (1 << (x % 8));
 | |
|   else
 | |
|     *ptr &= ~(1 << (x % 8));
 | |
| }
 | |
| 
 | |
| static void
 | |
| gdk_fb_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_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_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_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;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*************************************
 | |
|  * gc->fill_span() implementations
 | |
|  *************************************/
 | |
| 
 | |
| static void
 | |
| gdk_fb_fill_span_generic (GdkDrawable *drawable,
 | |
| 			  GdkGC       *gc,
 | |
| 			  GdkSpan     *span,
 | |
| 			  GdkColor    *color)
 | |
| {
 | |
|   int curx;
 | |
|   GdkColor spot = *color;
 | |
|   GdkGCFBData *gc_private;
 | |
|   GdkDrawableFBData *private;
 | |
|   gint left, right, y;
 | |
|   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;
 | |
| 
 | |
|   private = GDK_DRAWABLE_FBDATA (drawable);
 | |
|   gc_private = GDK_GC_FBDATA (gc);
 | |
| 
 | |
|   g_assert (gc);
 | |
| 
 | |
|   y = span->y;
 | |
|   left = span->x;
 | |
|   right = span->x + span->width;
 | |
|   
 | |
|   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;
 | |
|       gint relx, rely;
 | |
|       int drawh;
 | |
|       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);
 | |
|       
 | |
|       rely = y - private->abs_y;
 | |
|       drawh = (rely - gc_private->values.ts_y_origin) % ts_private->height;
 | |
|       if (drawh < 0)
 | |
| 	drawh += ts_private->height;
 | |
|       
 | |
|       for (curx = left; curx < right; 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, right - relx);
 | |
| 	  
 | |
| 	  gdk_fb_draw_drawable_3 (drawable, gc, GDK_DRAWABLE_IMPL (ts),
 | |
| 				  dc,
 | |
| 				  draww, drawh,
 | |
| 				  relx, rely,
 | |
| 				  xstep, 1);
 | |
| 	}
 | |
|       
 | |
|       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_IMPL_FBDATA (ts)->abs_x - gc_private->values.ts_x_origin - private->abs_x;
 | |
|       tsyoff = - GDK_DRAWABLE_IMPL_FBDATA (ts)->abs_y - gc_private->values.ts_y_origin - private->abs_y;
 | |
|       solid_stipple = (gc_private->values.fill == GDK_OPAQUE_STIPPLED);
 | |
|     }
 | |
|   
 | |
|   for (curx = left; curx < right; curx++)
 | |
|     {
 | |
|       int maskx = curx+clipxoff, masky = y + 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, y, &spot);
 | |
| 	  spot.pixel = ~spot.pixel;
 | |
| 	  spot.red = ~spot.red;
 | |
| 	  spot.green = ~spot.green;
 | |
| 	  spot.blue = ~spot.blue;
 | |
| 	}
 | |
|       else if (func == GDK_XOR)
 | |
| 	{
 | |
| 	  (gc_private->get_color) (drawable, gc, curx, y, &spot);
 | |
| 	  spot.pixel ^= gc_private->values.foreground.pixel;
 | |
| 	}
 | |
|       else if (func != GDK_COPY)
 | |
| 	{
 | |
| 	  g_warning ("Unsupported GdkFunction %d\n", func);
 | |
| 	}
 | |
|       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 = (y+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, y, spot.pixel);
 | |
|     }
 | |
| }
 | |
| 
 | |
| static void
 | |
| gdk_fb_fill_span_simple_1 (GdkDrawable *drawable,
 | |
| 			   GdkGC       *gc,
 | |
| 			   GdkSpan     *span,
 | |
| 			   GdkColor    *color)
 | |
| {
 | |
|   int curx;
 | |
|   GdkGCFBData *gc_private;
 | |
|   GdkDrawableFBData *private;
 | |
|   guchar *mem, *ptr;
 | |
|   guint rowstride;
 | |
|   gint left, right, y;
 | |
| 
 | |
|   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);
 | |
| 
 | |
|   y = span->y;
 | |
|   left = span->x;
 | |
|   right = span->x + span->width;
 | |
|   
 | |
|   mem = private->mem;
 | |
|   rowstride = private->rowstride;
 | |
| 
 | |
|   {
 | |
|     int fromx = MIN ((left+7)&(~7), right);
 | |
|     int begn = fromx - left, begoff = left % 8, endn;
 | |
|     guchar begmask, endmask;
 | |
|     int body_end = right & ~7;
 | |
|     int body_len = (body_end - fromx)/8;
 | |
|     
 | |
|     begmask = ((1 << (begn + begoff)) - 1)
 | |
|       & ~((1 << (begoff)) - 1);
 | |
|     endn = right - body_end;
 | |
|     endmask = (1 << endn) - 1;
 | |
|     
 | |
|     ptr = mem + y*rowstride + (left >> 3);
 | |
| 	
 | |
|     if (color->pixel)
 | |
|       *ptr |= begmask;
 | |
|     else
 | |
|       *ptr &= ~begmask;
 | |
|     
 | |
|     curx = fromx;
 | |
|     
 | |
|     if (curx < right)
 | |
|       {
 | |
| 	ptr = mem + y*rowstride + (curx >> 3);
 | |
| 	memset (ptr, color->pixel?0xFF:0, body_len);
 | |
| 	
 | |
| 	if (endn)
 | |
| 	  {
 | |
| 	    ptr = mem + y*rowstride + (body_end >> 3);
 | |
| 	    if (color->pixel)
 | |
| 	      *ptr |= endmask;
 | |
| 	    else
 | |
| 	      *ptr &= ~endmask;
 | |
| 	  }
 | |
|       }
 | |
|   }
 | |
| }
 | |
| 
 | |
| static void
 | |
| gdk_fb_fill_span_simple_8 (GdkDrawable *drawable,
 | |
| 			   GdkGC       *gc,
 | |
| 			   GdkSpan     *span,
 | |
| 			   GdkColor    *color)
 | |
| {
 | |
|   GdkGCFBData *gc_private;
 | |
|   GdkDrawableFBData *private;
 | |
|   guchar *mem, *ptr;
 | |
|   guint rowstride;
 | |
| 
 | |
|   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;
 | |
| 
 | |
|   ptr = mem + span->y*rowstride + span->x;
 | |
|   memset (ptr, color->pixel, span->width);
 | |
| }
 | |
| static void
 | |
| gdk_fb_fill_span_simple_16 (GdkDrawable *drawable,
 | |
| 			    GdkGC       *gc,
 | |
| 			    GdkSpan     *span,
 | |
| 			    GdkColor    *color)
 | |
| {
 | |
|   GdkGCFBData *gc_private;
 | |
|   GdkDrawableFBData *private;
 | |
|   guchar *mem;
 | |
|   guint rowstride;
 | |
|   guint16 *p16;
 | |
|   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 = span->width;
 | |
|   p16 = (guint16 *)(mem + span->y * rowstride + span->x*2);
 | |
|   for (i = 0; i < n; i++)
 | |
|     *(p16++) = color->pixel;
 | |
| }
 | |
| 
 | |
| static void
 | |
| gdk_fb_fill_span_simple_24 (GdkDrawable *drawable,
 | |
| 			    GdkGC       *gc,
 | |
| 			    GdkSpan     *span,
 | |
| 			    GdkColor    *color)
 | |
| {
 | |
|   GdkGCFBData *gc_private;
 | |
|   GdkDrawableFBData *private;
 | |
|   guchar *mem, *ptr;
 | |
|   guint rowstride;
 | |
|   int n;
 | |
|   guchar redval, greenval, blueval;
 | |
|   guchar *firstline, *ptr_end;
 | |
| 
 | |
|   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;
 | |
| 
 | |
|   redval = color->red>>8;
 | |
|   greenval = color->green>>8;
 | |
|   blueval = color->blue>>8;
 | |
|     
 | |
|   n = span->width*3;
 | |
|     
 | |
|   firstline = ptr = mem + span->y * rowstride + span->x*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;
 | |
|     }
 | |
| }
 | |
| static void
 | |
| gdk_fb_fill_span_simple_32 (GdkDrawable *drawable,
 | |
| 			    GdkGC       *gc,
 | |
| 			    GdkSpan     *span,
 | |
| 			    GdkColor    *color)
 | |
| {
 | |
|   GdkGCFBData *gc_private;
 | |
|   GdkDrawableFBData *private;
 | |
|   guchar *mem;
 | |
|   guint rowstride;
 | |
|   guint32 *p32;
 | |
|   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 = span->width;
 | |
|   p32 = (guint32 *)(mem + span->y * rowstride + span->x*4);
 | |
|   for (i = 0; i < n; i++)
 | |
|     *(p32++) = color->pixel;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*************************************
 | |
|  * gc->draw_drawable() implementations
 | |
|  *************************************/
 | |
| 
 | |
| static 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;
 | |
| 
 | |
|   if (draw_direction < 0)
 | |
|     {
 | |
|       int tmp;
 | |
|       tmp = start_y;
 | |
|       start_y = end_y;
 | |
|       end_y = tmp;
 | |
|       start_y--;
 | |
|       end_y--;
 | |
|       
 | |
|       tmp = start_x;
 | |
|       start_x = end_x;
 | |
|       end_x = tmp;
 | |
|       start_x--;
 | |
|       end_x--;
 | |
|     }
 | |
| 
 | |
|   for (cur_y = start_y; cur_y != end_y; cur_y+=draw_direction)
 | |
|     {
 | |
|       for (cur_x = start_x; cur_x != end_x; cur_x+=draw_direction)
 | |
| 	{
 | |
| 	  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_color (src, gc, cur_x + src_x_off, cur_y + src_y_off, &spot))
 | |
| 	    {
 | |
| 	    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 + private->abs_x;
 | |
| 			      bgy = (cur_y - GDK_DRAWABLE_IMPL_FBDATA (dc->bg_relto)->abs_y) % GDK_DRAWABLE_IMPL_FBDATA (dc->bgpm)->height + private->abs_y;
 | |
| 			      gdk_fb_drawable_get_color (dc->bgpm, gc, bgx, bgy, &realspot);
 | |
| 			    }
 | |
| 			    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_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;
 | |
| 
 | |
|   if (draw_direction < 0)
 | |
|     {
 | |
|       int tmp;
 | |
|       tmp = start_y;
 | |
|       start_y = end_y;
 | |
|       end_y = tmp;
 | |
|       start_y--;
 | |
|       end_y--;
 | |
|     }
 | |
| 
 | |
|   for(cur_y = start_y; cur_y != end_y; 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);
 | |
|     }
 | |
| 
 | |
| }
 | |
| 
 | |
| 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;
 | |
| 
 | |
|   if (draw_direction < 0)
 | |
|     {
 | |
|       int tmp;
 | |
|       tmp = start_y;
 | |
|       start_y = end_y;
 | |
|       end_y = tmp;
 | |
|       start_y--;
 | |
|       end_y--;
 | |
|       
 | |
|       tmp = start_x;
 | |
|       start_x = end_x;
 | |
|       end_x = tmp;
 | |
|       start_x--;
 | |
|       end_x--;
 | |
|     }
 | |
| 
 | |
|   for (y = start_y; y != end_y; y+=draw_direction)
 | |
|     {
 | |
|       for (x = start_x; x != end_x; x+=draw_direction)
 | |
| 	{
 | |
| 	  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;
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
| }
 | |
| 
 | |
| /*************************************
 | |
|  * gc->fill_rectangle() implementations
 | |
|  *************************************/
 | |
| 
 | |
| void
 | |
| gdk_fb_fill_rectangle_generic (GdkDrawable    *drawable,
 | |
| 			       GdkGC          *gc,
 | |
| 			       GdkRectangle   *rect,
 | |
| 			       GdkColor       *color)
 | |
| {
 | |
|   GdkDrawableFBData *private;
 | |
|   GdkSpan *spans;
 | |
|   int i;
 | |
| 
 | |
|   private = GDK_DRAWABLE_FBDATA (drawable);
 | |
| 
 | |
|   spans = g_new (GdkSpan, rect->height);
 | |
|   for (i = 0; i < rect->height; i++)
 | |
|     {
 | |
|       spans[i].x = rect->x - private->abs_x;
 | |
|       spans[i].y = rect->y+i - private->abs_y;
 | |
|       spans[i].width = rect->width;
 | |
|     }
 | |
|   gdk_fb_fill_spans (drawable, gc, spans, rect->height, TRUE);
 | |
|   g_free (spans);
 | |
| }
 | |
| 
 | |
| void
 | |
| gdk_fb_fill_rectangle_simple_16 (GdkDrawable    *drawable,
 | |
| 				 GdkGC          *gc,
 | |
| 				 GdkRectangle   *rect,
 | |
| 				 GdkColor       *color)
 | |
| {
 | |
|   GdkGCFBData *gc_private;
 | |
|   GdkDrawableFBData *private;
 | |
|   guchar *ptr;
 | |
|   guint rowstride;
 | |
|   int n;
 | |
|   gboolean extra;
 | |
|   int i;
 | |
|   guint32 pixel;
 | |
|   gint height;
 | |
|   
 | |
|   private = GDK_DRAWABLE_FBDATA (drawable);
 | |
|   gc_private = GDK_GC_FBDATA (gc);
 | |
| 
 | |
|   rowstride = private->rowstride - rect->width*2;
 | |
|   ptr = (guchar *)private->mem + rect->y * private->rowstride + rect->x*2;
 | |
| 
 | |
|   extra = rect->width&1;
 | |
|   n = rect->width>>1;
 | |
|     
 | |
|   pixel = (color->pixel << 16) | color->pixel;
 | |
| 
 | |
|   height = rect->height;
 | |
|   while (height>0)
 | |
|     {
 | |
|       i = n;
 | |
|       while (i>0)
 | |
| 	{
 | |
| 	  *(guint32 *)ptr = pixel;
 | |
| 	  ptr += 4;
 | |
| 	  i--;
 | |
| 	}
 | |
|       if (extra)
 | |
| 	{
 | |
| 	  *(guint16 *)ptr = color->pixel;
 | |
| 	  ptr += 2;
 | |
| 	}
 | |
|       ptr += rowstride;
 | |
|       height--; 
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| gdk_fb_fill_rectangle_simple_32 (GdkDrawable    *drawable,
 | |
| 				 GdkGC          *gc,
 | |
| 				 GdkRectangle   *rect,
 | |
| 				 GdkColor       *color)
 | |
| {
 | |
|   GdkGCFBData *gc_private;
 | |
|   GdkDrawableFBData *private;
 | |
|   guchar *ptr;
 | |
|   guint rowstride;
 | |
|   int n;
 | |
|   int i;
 | |
|   guint32 pixel;
 | |
|   gint height;
 | |
|   
 | |
|   private = GDK_DRAWABLE_FBDATA (drawable);
 | |
|   gc_private = GDK_GC_FBDATA (gc);
 | |
| 
 | |
|   rowstride = private->rowstride - rect->width*4;
 | |
|   ptr = (guchar *)private->mem + rect->y * private->rowstride + rect->x*4;
 | |
| 
 | |
|   n = rect->width;
 | |
|     
 | |
|   pixel = color->pixel;
 | |
| 
 | |
|   height = rect->height;
 | |
|   while (height>0)
 | |
|     {
 | |
|       i = n;
 | |
|       while (i>0)
 | |
| 	{
 | |
| 	  *(guint32 *)ptr = pixel;
 | |
| 	  ptr += 4;
 | |
| 	  i--;
 | |
| 	}
 | |
|       ptr += rowstride;
 | |
|       height--; 
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| /*************************************
 | |
|  * GC state calculation
 | |
|  *************************************/
 | |
| 
 | |
| 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_generic;
 | |
|   gc_private->fill_rectangle = gdk_fb_fill_rectangle_generic;
 | |
| 
 | |
|   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_set_pixel_1;
 | |
| 	gc_private->get_color = gdk_fb_get_color_1;
 | |
| 	break;
 | |
|       case 8:
 | |
| 	gc_private->set_pixel = gdk_fb_set_pixel_8;
 | |
| 	gc_private->get_color = gdk_fb_get_color_8;
 | |
| 	break;
 | |
|       case 16:
 | |
| 	gc_private->set_pixel = gdk_fb_set_pixel_16;
 | |
| 	gc_private->get_color = gdk_fb_get_color_16;
 | |
| 	break;
 | |
|       case 24:
 | |
| 	gc_private->set_pixel = gdk_fb_set_pixel_24;
 | |
| 	gc_private->get_color = gdk_fb_get_color_24;
 | |
| 	break;
 | |
|       case 32:
 | |
| 	gc_private->set_pixel = gdk_fb_set_pixel_32;
 | |
| 	gc_private->get_color = gdk_fb_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:
 | |
| 	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_COPY)
 | |
|     {
 | |
|       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;
 | |
| 	  gc_private->fill_rectangle = gdk_fb_fill_rectangle_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;
 | |
| 	  gc_private->fill_rectangle = gdk_fb_fill_rectangle_simple_32;
 | |
| 	  break;
 | |
| 	default:
 | |
| 	  g_assert_not_reached ();
 | |
| 	  break;
 | |
| 	}
 | |
|     }
 | |
| }
 | |
| 
 | |
| #ifdef ENABLE_SHADOW_FB
 | |
| static void
 | |
| gdk_shadow_fb_copy_rect_0 (gint x, gint y, gint width, gint height)
 | |
| {
 | |
|   guchar *dst, *src;
 | |
|   gint depth;
 | |
| 
 | |
|   depth = gdk_display->modeinfo.bits_per_pixel / 8;
 | |
| 
 | |
|   dst = gdk_display->fb_mmap + x * depth + gdk_display->sinfo.line_length * y;
 | |
|   src = gdk_display->fb_mem + x * depth + gdk_display->fb_stride * y;
 | |
| 
 | |
|   width = width*depth;
 | |
|   while (height>0)
 | |
|     {
 | |
|       memcpy (dst, src, width);
 | |
|       dst += gdk_display->sinfo.line_length;
 | |
|       src += gdk_display->fb_stride;
 | |
|       height--;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static void
 | |
| gdk_shadow_fb_copy_rect_90 (gint x, gint y, gint width, gint height)
 | |
| {
 | |
|   guchar *dst, *src, *pdst;
 | |
|   gint depth;
 | |
|   gint w;
 | |
|   gint i;
 | |
| 
 | |
|   depth = gdk_display->modeinfo.bits_per_pixel / 8;
 | |
| 
 | |
|   src = gdk_display->fb_mem + x * depth + gdk_display->fb_stride * y;
 | |
|   dst = gdk_display->fb_mmap + y * depth + gdk_display->sinfo.line_length * (gdk_display->fb_width - x - 1);
 | |
| 
 | |
|   while (height>0)
 | |
|     {
 | |
|       w = width;
 | |
|       pdst = dst;
 | |
|       while (w>0) {
 | |
| 	for (i = 0; i < depth; i++)
 | |
| 	  *pdst++ = *src++;
 | |
| 	pdst -= gdk_display->sinfo.line_length + depth;
 | |
| 	w--;
 | |
|       }
 | |
|       dst += depth;
 | |
|       src += gdk_display->fb_stride - width * depth;
 | |
|       height--;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static void
 | |
| gdk_shadow_fb_copy_rect_180 (gint x, gint y, gint width, gint height)
 | |
| {
 | |
|   guchar *dst, *src, *pdst;
 | |
|   gint depth;
 | |
|   gint w;
 | |
|   gint i;
 | |
| 
 | |
|   depth = gdk_display->modeinfo.bits_per_pixel / 8;
 | |
| 
 | |
|   src = gdk_display->fb_mem + x * depth + gdk_display->fb_stride * y;
 | |
|   dst = gdk_display->fb_mmap + (gdk_display->fb_width - x - 1) * depth + gdk_display->sinfo.line_length * (gdk_display->fb_height - y - 1) ;
 | |
| 
 | |
|   while (height>0)
 | |
|     {
 | |
|       w = width;
 | |
|       pdst = dst;
 | |
|       while (w>0) {
 | |
| 	for (i = 0; i < depth; i++)
 | |
| 	  *pdst++ = *src++;
 | |
| 	pdst -= 2 * depth;
 | |
| 	w--;
 | |
|       }
 | |
|       dst -= gdk_display->sinfo.line_length;
 | |
|       src += gdk_display->fb_stride - width * depth;
 | |
|       height--;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static void
 | |
| gdk_shadow_fb_copy_rect_270 (gint x, gint y, gint width, gint height)
 | |
| {
 | |
|   guchar *dst, *src, *pdst;
 | |
|   gint depth;
 | |
|   gint w;
 | |
|   gint i;
 | |
| 
 | |
|   depth = gdk_display->modeinfo.bits_per_pixel / 8;
 | |
| 
 | |
|   src = gdk_display->fb_mem + x * depth + gdk_display->fb_stride * y;
 | |
|   dst = gdk_display->fb_mmap + (gdk_display->fb_height - y - 1) * depth + gdk_display->sinfo.line_length * x;
 | |
| 
 | |
|   while (height>0)
 | |
|     {
 | |
|       w = width;
 | |
|       pdst = dst;
 | |
|       while (w>0) {
 | |
| 	for (i = 0; i < depth; i++)
 | |
| 	  *pdst++ = *src++;
 | |
| 	pdst += gdk_display->sinfo.line_length - depth;
 | |
| 	w--;
 | |
|       }
 | |
|       dst -= depth;
 | |
|       src += gdk_display->fb_stride - width * depth;
 | |
|       height--;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static void (*shadow_copy_rect[4]) (gint x, gint y, gint width, gint height);
 | |
| 
 | |
| volatile gint refresh_queued = 0;
 | |
| volatile gint refresh_x1, refresh_y1;
 | |
| volatile gint refresh_x2, refresh_y2;
 | |
| 
 | |
| static void
 | |
| gdk_shadow_fb_refresh (int signum)
 | |
| {
 | |
|   gint minx, miny, maxx, maxy;
 | |
| 
 | |
|   if (!refresh_queued)
 | |
|     {
 | |
|       struct itimerval timeout;
 | |
|       /* Stop the timer */ 
 | |
|       timeout.it_value.tv_sec = 0;
 | |
|       timeout.it_value.tv_usec = 0;
 | |
|       timeout.it_interval.tv_sec = 0;
 | |
|       timeout.it_interval.tv_usec = 0;
 | |
|       setitimer (ITIMER_REAL, &timeout, NULL);
 | |
|       return;
 | |
|     }
 | |
|  
 | |
|   
 | |
|   minx = refresh_x1;
 | |
|   miny = refresh_y1;
 | |
|   maxx = refresh_x2;
 | |
|   maxy = refresh_y2;
 | |
|   refresh_queued = 0;
 | |
| 
 | |
|   /* clip x */
 | |
|   if (minx < 0) {
 | |
|     minx = 0;
 | |
|     maxx = MAX (maxx, 0);
 | |
|   }
 | |
|   if (maxx >= gdk_display->fb_width) {
 | |
|     maxx = gdk_display->fb_width-1;
 | |
|     minx = MIN (minx, maxx);
 | |
|   }
 | |
|   /* clip y */
 | |
|   if (miny < 0) {
 | |
|     miny = 0;
 | |
|     maxy = MAX (maxy, 0);
 | |
|   }
 | |
|   if (maxy >= gdk_display->fb_height) {
 | |
|     maxy = gdk_display->fb_height-1;
 | |
|     miny = MIN (miny, maxy);
 | |
|   }
 | |
|   
 | |
|   (*shadow_copy_rect[_gdk_fb_screen_angle]) (minx, miny, maxx - minx + 1, maxy - miny + 1);
 | |
| }
 | |
| 
 | |
| void
 | |
| gdk_shadow_fb_stop_updates (void)
 | |
| {
 | |
|   struct itimerval timeout;
 | |
| 
 | |
|   refresh_queued = 0;
 | |
| 
 | |
|   /* Stop the timer */ 
 | |
|   timeout.it_value.tv_sec = 0;
 | |
|   timeout.it_value.tv_usec = 0;
 | |
|   timeout.it_interval.tv_sec = 0;
 | |
|   timeout.it_interval.tv_usec = 0;
 | |
|   setitimer (ITIMER_REAL, &timeout, NULL);
 | |
| 
 | |
|   refresh_queued = 0;
 | |
| }
 | |
| 
 | |
| void
 | |
| gdk_shadow_fb_init (void)
 | |
| {
 | |
|   struct sigaction action;
 | |
| 
 | |
|   action.sa_handler = gdk_shadow_fb_refresh;
 | |
|   sigemptyset (&action.sa_mask);
 | |
|   action.sa_flags = 0;
 | |
|   
 | |
|   sigaction (SIGALRM, &action, NULL);
 | |
| 
 | |
|   shadow_copy_rect[GDK_FB_0_DEGREES] = gdk_shadow_fb_copy_rect_0;
 | |
|   shadow_copy_rect[GDK_FB_90_DEGREES] = gdk_shadow_fb_copy_rect_90;
 | |
|   shadow_copy_rect[GDK_FB_180_DEGREES] = gdk_shadow_fb_copy_rect_180;
 | |
|   shadow_copy_rect[GDK_FB_270_DEGREES] = gdk_shadow_fb_copy_rect_270;
 | |
| }
 | |
| 
 | |
| /* maxx and maxy are included */
 | |
| void
 | |
| gdk_shadow_fb_update (gint minx, gint miny, gint maxx, gint maxy)
 | |
| {
 | |
|   struct itimerval timeout;
 | |
|   
 | |
|   g_assert (minx <= maxx);
 | |
|   g_assert (miny <= maxy);
 | |
| 
 | |
|   if (refresh_queued)
 | |
|     {
 | |
|       refresh_x1 = MIN (refresh_x1, minx);
 | |
|       refresh_y1 = MIN (refresh_y1, miny);
 | |
|       refresh_x2 = MAX (refresh_x2, maxx);
 | |
|       refresh_y2 = MAX (refresh_y2, maxy);
 | |
|       refresh_queued = 1;
 | |
|     }
 | |
|   else
 | |
|     {
 | |
|       refresh_x1 = minx;
 | |
|       refresh_y1 = miny;
 | |
|       refresh_x2 = maxx;
 | |
|       refresh_y2 = maxy;
 | |
|       refresh_queued = 1;
 | |
| 
 | |
|       getitimer (ITIMER_REAL, &timeout);
 | |
|       if (timeout.it_value.tv_usec == 0)
 | |
| 	{
 | |
| 	  timeout.it_value.tv_sec = 0;
 | |
| 	  timeout.it_value.tv_usec = 20000; /* 20 ms => 50 fps */
 | |
| 	  timeout.it_interval.tv_sec = 0;
 | |
| 	  timeout.it_interval.tv_usec = 20000; /* 20 ms => 50 fps */
 | |
| 	  setitimer (ITIMER_REAL, &timeout, NULL);
 | |
| 	}
 | |
|     }
 | |
|   
 | |
| }
 | |
| #else
 | |
| 
 | |
| void
 | |
| gdk_shadow_fb_update (gint minx, gint miny, gint maxx, gint maxy)
 | |
| {
 | |
| }
 | |
| 
 | |
| void
 | |
| gdk_shadow_fb_init (void)
 | |
| {
 | |
| }
 | |
| 
 | |
| #endif
 | |
| 
 |