1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 2000 Alexander Larsson
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
28 #include "gdkprivate-fb.h"
34 * Reading pixel values from a generic drawable.
38 gdk_fb_drawable_get_color (GdkDrawable *drawable,
44 GetPixelRet retval = GPR_NONE;
45 GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
46 guchar *mem = private->mem;
47 guint rowstride = private->rowstride;
49 switch (private->depth)
53 guchar foo = mem[(x >> 3) + y * rowstride];
54 if (foo & (1 << (x % 8)))
55 *spot = GDK_GC_FBDATA (gc)->values.foreground;
59 *spot = GDK_GC_FBDATA (gc)->values.background;
64 if (mem[x + y * rowstride])
65 *spot = GDK_GC_FBDATA (gc)->values.foreground;
67 *spot = GDK_GC_FBDATA (gc)->values.background;
70 retval = GPR_AA_GRAYVAL;
71 spot->pixel = mem[x + y * rowstride] << 1;
72 spot->red = spot->green = spot->blue = spot->pixel << 8;
74 case 78: /* AA mode */
75 retval = GPR_AA_GRAYVAL;
76 spot->pixel = mem[x + y * rowstride];
77 spot->red = spot->green = spot->blue = spot->pixel << 8;
80 spot->pixel = mem[x + y * rowstride];
81 *spot = private->colormap->colors[spot->pixel];
85 guint16 val16 = *((guint16 *)&mem[x*2 + y*rowstride]);
87 spot->red = (((1<<gdk_display->modeinfo.red.length) - 1) & (val16 >> gdk_display->modeinfo.red.offset)) << (16 - gdk_display->modeinfo.red.length);
88 spot->green = (((1<<gdk_display->modeinfo.green.length) - 1) & (val16 >> gdk_display->modeinfo.green.offset)) << (16 - gdk_display->modeinfo.green.length);
89 spot->blue = (((1<<gdk_display->modeinfo.blue.length) - 1) & (val16 >> gdk_display->modeinfo.blue.offset)) << (16 - gdk_display->modeinfo.blue.length);
96 guchar *smem = &mem[x*3 + y*rowstride];
97 spot->red = smem[gdk_display->red_byte] << 8;
98 spot->green = smem[gdk_display->green_byte] << 8;
99 spot->blue = smem[gdk_display->blue_byte] << 8;
100 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
101 spot->pixel = (smem[0]<<16)|(smem[1]<<8)|smem[2];
103 spot->pixel = smem[0]|(smem[1]<<8)|(smem[2]<<16);
109 guchar *smem = &mem[x*4 + y*rowstride];
110 spot->red = smem[gdk_display->red_byte] << 8;
111 spot->green = smem[gdk_display->green_byte] << 8;
112 spot->blue = smem[gdk_display->blue_byte] << 8;
113 spot->pixel = *(guint32 *)smem;
121 /*************************************
122 * gc->get_color() implementations
123 *************************************/
126 gdk_fb_get_color_1 (GdkDrawable *drawable,
132 GetPixelRet retval = GPR_NONE;
133 GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
134 guchar *mem = private->mem;
135 guint rowstride = private->rowstride;
138 g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
140 foo = mem[(x >> 3) + y * rowstride];
141 if (foo & (1 << (x % 8)))
142 *color = GDK_GC_FBDATA (gc)->values.foreground;
145 retval = GPR_USED_BG;
147 *color = GDK_GC_FBDATA (gc)->values.background;
154 gdk_fb_get_color_8 (GdkDrawable *drawable,
160 GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
161 guchar *mem = private->mem;
162 guint rowstride = private->rowstride;
165 g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
167 pixel = mem[x + y * rowstride];
168 *color = private->colormap->colors[pixel];
174 gdk_fb_get_color_16 (GdkDrawable *drawable,
180 GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
181 guchar *mem = private->mem;
182 guint rowstride = private->rowstride;
185 g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
187 val16 = *((guint16 *)&mem[x*2 + y*rowstride]);
189 color->red = (((1<<gdk_display->modeinfo.red.length) - 1) & (val16 >> gdk_display->modeinfo.red.offset)) << (16 - gdk_display->modeinfo.red.length);
190 color->green = (((1<<gdk_display->modeinfo.green.length) - 1) & (val16 >> gdk_display->modeinfo.green.offset)) << (16 - gdk_display->modeinfo.green.length);
191 color->blue = (((1<<gdk_display->modeinfo.blue.length) - 1) & (val16 >> gdk_display->modeinfo.blue.offset)) << (16 - gdk_display->modeinfo.blue.length);
193 color->pixel = val16;
199 gdk_fb_get_color_24 (GdkDrawable *drawable,
205 GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
206 guchar *mem = private->mem;
207 guint rowstride = private->rowstride;
210 g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
212 smem = &mem[x*3 + y*rowstride];
213 color->red = smem[gdk_display->red_byte] << 8;
214 color->green = smem[gdk_display->green_byte] << 8;
215 color->blue = smem[gdk_display->blue_byte] << 8;
216 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
217 color->pixel = (smem[0]<<16)|(smem[1]<<8)|smem[2];
219 color->pixel = smem[0]|(smem[1]<<8)|(smem[2]<<16);
226 gdk_fb_get_color_32 (GdkDrawable *drawable,
232 GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
233 guchar *mem = private->mem;
234 guint rowstride = private->rowstride;
237 g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
239 smem = &mem[x*4 + y*rowstride];
240 color->red = smem[gdk_display->red_byte] << 8;
241 color->green = smem[gdk_display->green_byte] << 8;
242 color->blue = smem[gdk_display->blue_byte] << 8;
243 color->pixel = *(guint32 *)smem;
248 /*************************************
249 * gc->set_pixel() implementations
250 *************************************/
253 gdk_fb_set_pixel_1(GdkDrawable *drawable,
259 GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
260 guchar *mem = private->mem;
261 guint rowstride = private->rowstride;
264 if (!_gdk_fb_is_active_vt)
267 g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
269 ptr = mem + (y*rowstride) + (x >> 3);
272 *ptr |= (1 << (x % 8));
274 *ptr &= ~(1 << (x % 8));
278 gdk_fb_set_pixel_8(GdkDrawable *drawable,
284 GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
285 guchar *mem = private->mem;
286 guint rowstride = private->rowstride;
288 if (!_gdk_fb_is_active_vt)
291 g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
293 mem[x + y*rowstride] = pixel;
297 gdk_fb_set_pixel_16(GdkDrawable *drawable,
303 GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
304 guchar *mem = private->mem;
305 guint rowstride = private->rowstride;
308 if (!_gdk_fb_is_active_vt)
311 g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
313 ptr = (guint16 *)&mem[x*2 + y*rowstride];
318 gdk_fb_set_pixel_24(GdkDrawable *drawable,
324 GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
325 guchar *mem = private->mem;
326 guint rowstride = private->rowstride;
329 if (!_gdk_fb_is_active_vt)
332 g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
334 smem = &mem[x*3 + y*rowstride];
335 smem[0] = pixel & 0xff;
336 smem[1] = (pixel >> 8) & 0xff;
337 smem[2] = (pixel >> 16) & 0xff;
341 gdk_fb_set_pixel_32(GdkDrawable *drawable,
347 GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
348 guchar *mem = private->mem;
349 guint rowstride = private->rowstride;
352 if (!_gdk_fb_is_active_vt)
355 g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
357 smem = (guint32 *)&mem[x*4 + y*rowstride];
362 /*************************************
363 * gc->fill_span() implementations
364 *************************************/
367 gdk_fb_fill_span_generic (GdkDrawable *drawable,
373 GdkColor spot = *color;
374 GdkGCFBData *gc_private;
375 GdkDrawableFBData *private;
377 int clipxoff, clipyoff; /* Amounts to add to curx & cury to get x & y in clip mask */
381 guint mask_rowstride;
382 GdkPixmap *ts = NULL;
383 GdkDrawableFBData *ts_private;
384 gboolean solid_stipple;
387 if (!_gdk_fb_is_active_vt)
390 private = GDK_DRAWABLE_FBDATA (drawable);
391 gc_private = GDK_GC_FBDATA (gc);
397 right = span->x + span->width;
399 func = gc_private->values.function;
401 cmask = gc_private->values.clip_mask;
402 clipxoff = clipyoff = tsxoff = tsyoff = 0;
404 solid_stipple = FALSE;
409 GdkDrawableFBData *cmask_private;
411 cmask_private = GDK_DRAWABLE_IMPL_FBDATA (cmask);
413 clipmem = cmask_private->mem;
414 clipxoff = cmask_private->abs_x - gc_private->values.clip_x_origin - private->abs_x;
415 clipyoff = cmask_private->abs_y - gc_private->values.clip_y_origin - private->abs_y;
416 mask_rowstride = cmask_private->rowstride;
419 if (gc_private->values.fill == GDK_TILED &&
420 gc_private->values.tile)
425 GdkFBDrawingContext *dc, dc_data;
429 gdk_fb_drawing_context_init (dc, drawable, gc, FALSE, TRUE);
431 ts = gc_private->values.tile;
432 ts_private = GDK_DRAWABLE_IMPL_FBDATA (ts);
434 rely = y - private->abs_y;
435 drawh = (rely - gc_private->values.ts_y_origin) % ts_private->height;
437 drawh += ts_private->height;
439 for (curx = left; curx < right; curx += xstep)
443 relx = curx - private->abs_x;
445 draww = (relx - gc_private->values.ts_x_origin) % ts_private->width;
447 draww += ts_private->width;
449 xstep = MIN (ts_private->width - draww, right - relx);
451 gdk_fb_draw_drawable_3 (drawable, gc, GDK_DRAWABLE_IMPL (ts),
458 gdk_fb_drawing_context_finalize (dc);
462 else if ((gc_private->values.fill == GDK_STIPPLED ||
463 gc_private->values.fill == GDK_OPAQUE_STIPPLED) &&
464 gc_private->values.stipple)
466 ts = gc_private->values.stipple;
467 tsxoff = - GDK_DRAWABLE_IMPL_FBDATA (ts)->abs_x - gc_private->values.ts_x_origin - private->abs_x;
468 tsyoff = - GDK_DRAWABLE_IMPL_FBDATA (ts)->abs_y - gc_private->values.ts_y_origin - private->abs_y;
469 solid_stipple = (gc_private->values.fill == GDK_OPAQUE_STIPPLED);
472 for (curx = left; curx < right; curx++)
474 int maskx = curx+clipxoff, masky = y + clipyoff;
479 foo = clipmem[masky*mask_rowstride + (maskx >> 3)];
481 if (!(foo & (1 << (maskx % 8))))
485 if (func == GDK_INVERT)
487 (gc_private->get_color) (drawable, gc, curx, y, &spot);
488 spot.pixel = ~spot.pixel;
489 spot.red = ~spot.red;
490 spot.green = ~spot.green;
491 spot.blue = ~spot.blue;
493 else if (func == GDK_XOR)
495 (gc_private->get_color) (drawable, gc, curx, y, &spot);
496 spot.pixel ^= gc_private->values.foreground.pixel;
498 else if (func != GDK_COPY)
500 g_warning ("Unsupported GdkFunction %d\n", func);
506 ts_private = GDK_DRAWABLE_IMPL_FBDATA (ts);
508 wid = ts_private->width;
509 hih = ts_private->height;
511 maskx = (curx+tsxoff)%wid;
512 masky = (y+tsyoff)%hih;
518 foo = ts_private->mem[(maskx >> 3) + ts_private->rowstride*masky];
519 if (foo & (1 << (maskx % 8)))
521 spot = gc_private->values.foreground;
523 else if (solid_stipple)
525 spot = gc_private->values.background;
531 (gc_private->set_pixel) (drawable, gc, curx, y, spot.pixel);
536 gdk_fb_fill_span_simple_1 (GdkDrawable *drawable,
542 GdkGCFBData *gc_private;
543 GdkDrawableFBData *private;
548 if (!_gdk_fb_is_active_vt)
551 private = GDK_DRAWABLE_FBDATA (drawable);
552 gc_private = GDK_GC_FBDATA (gc);
556 g_assert (!gc_private->values.clip_mask &&
557 !gc_private->values.tile &&
558 !gc_private->values.stipple &&
559 gc_private->values.function != GDK_INVERT);
563 right = span->x + span->width;
566 rowstride = private->rowstride;
569 int fromx = MIN ((left+7)&(~7), right);
570 int begn = fromx - left, begoff = left % 8, endn;
571 guchar begmask, endmask;
572 int body_end = right & ~7;
573 int body_len = (body_end - fromx)/8;
575 begmask = ((1 << (begn + begoff)) - 1)
576 & ~((1 << (begoff)) - 1);
577 endn = right - body_end;
578 endmask = (1 << endn) - 1;
580 ptr = mem + y*rowstride + (left >> 3);
591 ptr = mem + y*rowstride + (curx >> 3);
592 memset (ptr, color->pixel?0xFF:0, body_len);
596 ptr = mem + y*rowstride + (body_end >> 3);
607 gdk_fb_fill_span_simple_8 (GdkDrawable *drawable,
612 GdkGCFBData *gc_private;
613 GdkDrawableFBData *private;
617 if (!_gdk_fb_is_active_vt)
620 private = GDK_DRAWABLE_FBDATA (drawable);
621 gc_private = GDK_GC_FBDATA (gc);
625 g_assert (!gc_private->values.clip_mask &&
626 !gc_private->values.tile &&
627 !gc_private->values.stipple &&
628 gc_private->values.function != GDK_INVERT);
631 rowstride = private->rowstride;
633 ptr = mem + span->y*rowstride + span->x;
634 memset (ptr, color->pixel, span->width);
638 gdk_fb_fill_span_simple_16 (GdkDrawable *drawable,
643 GdkGCFBData *gc_private;
644 GdkDrawableFBData *private;
651 if (!_gdk_fb_is_active_vt)
654 private = GDK_DRAWABLE_FBDATA (drawable);
655 gc_private = GDK_GC_FBDATA (gc);
659 g_assert (!gc_private->values.clip_mask &&
660 !gc_private->values.tile &&
661 !gc_private->values.stipple &&
662 gc_private->values.function != GDK_INVERT);
665 rowstride = private->rowstride;
668 p16 = (guint16 *)(mem + span->y * rowstride + span->x*2);
669 for (i = 0; i < n; i++)
670 *(p16++) = color->pixel;
674 gdk_fb_fill_span_simple_24 (GdkDrawable *drawable,
679 GdkGCFBData *gc_private;
680 GdkDrawableFBData *private;
684 guchar redval, greenval, blueval;
685 guchar *firstline, *ptr_end;
687 if (!_gdk_fb_is_active_vt)
690 private = GDK_DRAWABLE_FBDATA (drawable);
691 gc_private = GDK_GC_FBDATA (gc);
695 g_assert (!gc_private->values.clip_mask &&
696 !gc_private->values.tile &&
697 !gc_private->values.stipple &&
698 gc_private->values.function != GDK_INVERT);
701 rowstride = private->rowstride;
703 redval = color->red>>8;
704 greenval = color->green>>8;
705 blueval = color->blue>>8;
709 firstline = ptr = mem + span->y * rowstride + span->x*3;
711 while (ptr < ptr_end)
713 ptr[gdk_display->red_byte] = redval;
714 ptr[gdk_display->green_byte] = greenval;
715 ptr[gdk_display->blue_byte] = blueval;
721 gdk_fb_fill_span_simple_32 (GdkDrawable *drawable,
726 GdkGCFBData *gc_private;
727 GdkDrawableFBData *private;
734 if (!_gdk_fb_is_active_vt)
737 private = GDK_DRAWABLE_FBDATA (drawable);
738 gc_private = GDK_GC_FBDATA (gc);
742 g_assert (!gc_private->values.clip_mask &&
743 !gc_private->values.tile &&
744 !gc_private->values.stipple &&
745 gc_private->values.function != GDK_INVERT);
748 rowstride = private->rowstride;
751 p32 = (guint32 *)(mem + span->y * rowstride + span->x*4);
752 for (i = 0; i < n; i++)
753 *(p32++) = color->pixel;
757 /*************************************
758 * gc->draw_drawable() implementations
759 *************************************/
762 gdk_fb_draw_drawable_generic (GdkDrawable *drawable,
765 GdkFBDrawingContext *dc,
774 GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
777 if (draw_direction < 0)
793 for (cur_y = start_y; cur_y != end_y; cur_y+=draw_direction)
795 for (cur_x = start_x; cur_x != end_x; cur_x+=draw_direction)
799 if (GDK_GC_FBDATA(gc)->values.clip_mask)
801 int maskx = cur_x + dc->clipxoff, masky = cur_y + dc->clipyoff;
804 foo = dc->clipmem[masky*dc->clip_rowstride + (maskx >> 3)];
806 if (!(foo & (1 << (maskx % 8))))
810 switch (gdk_fb_drawable_get_color (src, gc, cur_x + src_x_off, cur_y + src_y_off, &spot))
814 GdkColor realspot, fg;
815 guint graylevel = spot.pixel;
818 if (private->depth == 1)
820 if (spot.pixel > 192)
821 spot = GDK_GC_FBDATA (gc)->values.foreground;
823 spot = GDK_GC_FBDATA (gc)->values.background;
828 if (graylevel >= 254)
830 spot = GDK_GC_FBDATA (gc)->values.foreground;
832 else if (graylevel <= 2)
837 spot = GDK_GC_FBDATA (gc)->values.background;
841 switch ((GDK_GC_FBDATA (gc)->get_color) (drawable, gc, cur_x, cur_y, &realspot))
847 bgx = (cur_x - GDK_DRAWABLE_IMPL_FBDATA (dc->bg_relto)->abs_x) % GDK_DRAWABLE_IMPL_FBDATA (dc->bgpm)->width + private->abs_x;
848 bgy = (cur_y - GDK_DRAWABLE_IMPL_FBDATA (dc->bg_relto)->abs_y) % GDK_DRAWABLE_IMPL_FBDATA (dc->bgpm)->height + private->abs_y;
849 gdk_fb_drawable_get_color (dc->bgpm, gc, bgx, bgy, &realspot);
855 g_assert_not_reached ();
859 fg = GDK_GC_FBDATA (gc)->values.foreground;
861 /* Now figure out what 'spot' should actually look like */
866 realspot.green >>= 8;
870 tmp = (fg.red - realspot.red) * graylevel;
871 spot.red = realspot.red + ((tmp + (tmp >> 8) + 0x80) >> 8);
874 tmp = (fg.green - realspot.green) * graylevel;
875 spot.green = realspot.green + ((tmp + (tmp >> 8) + 0x80) >> 8);
878 tmp = (fg.blue - realspot.blue) * graylevel;
879 spot.blue = realspot.blue + ((tmp + (tmp >> 8) + 0x80) >> 8);
882 /* Now find the pixel for this thingie */
883 switch (private->depth)
886 if (!gdk_colormap_alloc_color (private->colormap, &spot, FALSE, TRUE))
888 g_error ("Can't allocate AA color!");
892 spot.pixel = (spot.red >> (16 - gdk_display->modeinfo.red.length)) << gdk_display->modeinfo.red.offset;
893 spot.pixel |= (spot.green >> (16 - gdk_display->modeinfo.green.length)) << gdk_display->modeinfo.green.offset;
894 spot.pixel |= (spot.blue >> (16 - gdk_display->modeinfo.blue.length)) << gdk_display->modeinfo.blue.offset;
898 spot.pixel = ((spot.red & 0xFF00) >> 8 << (gdk_display->modeinfo.red.offset))
899 | ((spot.green & 0xFF00) >> 8 << (gdk_display->modeinfo.green.offset))
900 | ((spot.blue & 0xFF00) >> 8 << (gdk_display->modeinfo.blue.offset));
914 g_assert_not_reached ();
918 (GDK_GC_FBDATA (gc)->set_pixel) (drawable, gc, cur_x, cur_y, spot.pixel);
925 gdk_fb_draw_drawable_memmove (GdkDrawable *drawable,
928 GdkFBDrawingContext *dc,
937 GdkDrawableFBData *src_private = GDK_DRAWABLE_FBDATA (src);
938 guint depth = src_private->depth;
939 guint src_rowstride = src_private->rowstride;
940 guchar *srcmem = src_private->mem;
941 int linelen = (end_x - start_x)*(depth>>3);
944 if (!_gdk_fb_is_active_vt)
947 if (draw_direction < 0)
957 for(cur_y = start_y; cur_y != end_y; cur_y += draw_direction)
959 memmove (dc->mem + (cur_y * dc->rowstride) + start_x*(depth>>3),
960 srcmem + ((cur_y + src_y_off)*src_rowstride) + (start_x + src_x_off)*(depth>>3),
967 gdk_fb_draw_drawable_aa_24 (GdkDrawable *drawable,
970 GdkFBDrawingContext *dc,
979 GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
981 GdkGCFBData *gc_private;
982 guchar *dmem = private->mem;
983 guint dst_rowstride = private->rowstride;
984 guchar *smem = GDK_DRAWABLE_FBDATA (src)->mem;
985 guint src_rowstride = GDK_DRAWABLE_FBDATA (src)->rowstride;
990 gint fg_r, fg_g, fg_b;
992 if (!_gdk_fb_is_active_vt)
995 gc_private = GDK_GC_FBDATA (gc);
997 fg = GDK_GC_FBDATA (gc)->values.foreground;
999 fg_g = fg.green >> 8;
1000 fg_b = fg.blue >> 8;
1002 if (draw_direction < 0)
1018 for (y = start_y; y != end_y; y+=draw_direction)
1020 for (x = start_x; x != end_x; x+=draw_direction)
1022 grayval = smem[x + src_x_off + (y + src_y_off) * src_rowstride];
1024 if ((grayval <= 2) && (!dc->draw_bg))
1027 dst = &dmem[x*3 + y*dst_rowstride];
1031 dst[gdk_display->red_byte] = fg_r;
1032 dst[gdk_display->green_byte] = fg_g;
1033 dst[gdk_display->blue_byte] = fg_b;
1035 else if (grayval <= 2)
1037 dst[gdk_display->red_byte] = GDK_GC_FBDATA (gc)->values.background.red >> 8;
1038 dst[gdk_display->green_byte] = GDK_GC_FBDATA (gc)->values.background.green >> 8;
1039 dst[gdk_display->blue_byte] = GDK_GC_FBDATA (gc)->values.background.blue >> 8;
1043 r = dst[gdk_display->red_byte];
1044 tmp = (fg_r - r) * (gint)grayval;
1045 r = r + ((tmp + (tmp >> 8) + 0x80) >> 8);
1046 dst[gdk_display->red_byte] = r;
1048 g = dst[gdk_display->green_byte];
1049 tmp = (fg_g - g) * (gint)grayval;
1050 g = g + ((tmp + (tmp >> 8) + 0x80) >> 8);
1051 dst[gdk_display->green_byte] = g;
1053 b = dst[gdk_display->blue_byte];
1054 tmp = (fg_b - b) * (gint)grayval;
1055 b = b + ((tmp + (tmp >> 8) + 0x80) >> 8);
1056 dst[gdk_display->blue_byte] = b;
1062 /*************************************
1063 * gc->fill_rectangle() implementations
1064 *************************************/
1067 gdk_fb_fill_rectangle_generic (GdkDrawable *drawable,
1072 GdkDrawableFBData *private;
1076 if (!_gdk_fb_is_active_vt)
1079 private = GDK_DRAWABLE_FBDATA (drawable);
1081 spans = g_new (GdkSpan, rect->height);
1082 for (i = 0; i < rect->height; i++)
1084 spans[i].x = rect->x - private->abs_x;
1085 spans[i].y = rect->y+i - private->abs_y;
1086 spans[i].width = rect->width;
1088 gdk_fb_fill_spans (drawable, gc, spans, rect->height, TRUE);
1093 gdk_fb_fill_rectangle_simple_16 (GdkDrawable *drawable,
1098 GdkGCFBData *gc_private;
1099 GdkDrawableFBData *private;
1108 if (!_gdk_fb_is_active_vt)
1111 private = GDK_DRAWABLE_FBDATA (drawable);
1112 gc_private = GDK_GC_FBDATA (gc);
1114 rowstride = private->rowstride - rect->width*2;
1115 ptr = (guchar *)private->mem + rect->y * private->rowstride + rect->x*2;
1117 extra = rect->width&1;
1120 pixel = (color->pixel << 16) | color->pixel;
1122 height = rect->height;
1128 *(guint32 *)ptr = pixel;
1134 *(guint16 *)ptr = color->pixel;
1143 gdk_fb_fill_rectangle_simple_32 (GdkDrawable *drawable,
1148 GdkGCFBData *gc_private;
1149 GdkDrawableFBData *private;
1157 if (!_gdk_fb_is_active_vt)
1160 private = GDK_DRAWABLE_FBDATA (drawable);
1161 gc_private = GDK_GC_FBDATA (gc);
1163 rowstride = private->rowstride - rect->width*4;
1164 ptr = (guchar *)private->mem + rect->y * private->rowstride + rect->x*4;
1168 pixel = color->pixel;
1170 height = rect->height;
1176 *(guint32 *)ptr = pixel;
1186 /*************************************
1187 * GC state calculation
1188 *************************************/
1191 _gdk_fb_gc_calc_state (GdkGC *gc,
1192 GdkGCValuesMask changed)
1194 GdkGCFBData *gc_private;
1197 gc_private = GDK_GC_FBDATA (gc);
1199 gc_private->fill_span = gdk_fb_fill_span_generic;
1200 gc_private->fill_rectangle = gdk_fb_fill_rectangle_generic;
1202 for (i = 0; i < GDK_NUM_FB_SRCBPP; i++)
1203 gc_private->draw_drawable[i] = gdk_fb_draw_drawable_generic;
1205 if (changed & _GDK_FB_GC_DEPTH)
1206 switch (gc_private->depth)
1209 gc_private->set_pixel = gdk_fb_set_pixel_1;
1210 gc_private->get_color = gdk_fb_get_color_1;
1213 gc_private->set_pixel = gdk_fb_set_pixel_8;
1214 gc_private->get_color = gdk_fb_get_color_8;
1217 gc_private->set_pixel = gdk_fb_set_pixel_16;
1218 gc_private->get_color = gdk_fb_get_color_16;
1221 gc_private->set_pixel = gdk_fb_set_pixel_24;
1222 gc_private->get_color = gdk_fb_get_color_24;
1225 gc_private->set_pixel = gdk_fb_set_pixel_32;
1226 gc_private->get_color = gdk_fb_get_color_32;
1229 g_assert_not_reached ();
1233 if (!gc_private->values.clip_mask)
1235 switch (gc_private->depth)
1238 gc_private->draw_drawable[GDK_FB_SRC_BPP_8] = gdk_fb_draw_drawable_memmove;
1241 gc_private->draw_drawable[GDK_FB_SRC_BPP_16] = gdk_fb_draw_drawable_memmove;
1244 gc_private->draw_drawable[GDK_FB_SRC_BPP_8_AA_GRAYVAL] = gdk_fb_draw_drawable_aa_24;
1245 gc_private->draw_drawable[GDK_FB_SRC_BPP_24] = gdk_fb_draw_drawable_memmove;
1248 gc_private->draw_drawable[GDK_FB_SRC_BPP_32] = gdk_fb_draw_drawable_memmove;
1253 if (!gc_private->values.clip_mask &&
1254 !gc_private->values.tile &&
1255 !gc_private->values.stipple &&
1256 gc_private->values.function == GDK_COPY)
1258 switch (gc_private->depth)
1261 gc_private->fill_span = gdk_fb_fill_span_simple_1;
1264 gc_private->fill_span = gdk_fb_fill_span_simple_8;
1267 gc_private->fill_span = gdk_fb_fill_span_simple_16;
1268 gc_private->fill_rectangle = gdk_fb_fill_rectangle_simple_16;
1271 gc_private->fill_span = gdk_fb_fill_span_simple_24;
1274 gc_private->fill_span = gdk_fb_fill_span_simple_32;
1275 gc_private->fill_rectangle = gdk_fb_fill_rectangle_simple_32;
1278 g_assert_not_reached ();
1284 #ifdef ENABLE_SHADOW_FB
1286 gdk_shadow_fb_copy_rect_0 (gint x, gint y, gint width, gint height)
1291 if (!_gdk_fb_is_active_vt)
1294 depth = gdk_display->modeinfo.bits_per_pixel / 8;
1296 dst = gdk_display->fb_mmap + x * depth + gdk_display->sinfo.line_length * y;
1297 src = gdk_display->fb_mem + x * depth + gdk_display->fb_stride * y;
1299 width = width*depth;
1302 memcpy (dst, src, width);
1303 dst += gdk_display->sinfo.line_length;
1304 src += gdk_display->fb_stride;
1310 gdk_shadow_fb_copy_rect_90 (gint x, gint y, gint width, gint height)
1312 guchar *dst, *src, *pdst;
1317 if (!_gdk_fb_is_active_vt)
1320 depth = gdk_display->modeinfo.bits_per_pixel / 8;
1322 src = gdk_display->fb_mem + x * depth + gdk_display->fb_stride * y;
1323 dst = gdk_display->fb_mmap + y * depth + gdk_display->sinfo.line_length * (gdk_display->fb_width - x - 1);
1330 for (i = 0; i < depth; i++)
1332 pdst -= gdk_display->sinfo.line_length + depth;
1336 src += gdk_display->fb_stride - width * depth;
1342 gdk_shadow_fb_copy_rect_180 (gint x, gint y, gint width, gint height)
1344 guchar *dst, *src, *pdst;
1349 if (!_gdk_fb_is_active_vt)
1352 depth = gdk_display->modeinfo.bits_per_pixel / 8;
1354 src = gdk_display->fb_mem + x * depth + gdk_display->fb_stride * y;
1355 dst = gdk_display->fb_mmap + (gdk_display->fb_width - x - 1) * depth + gdk_display->sinfo.line_length * (gdk_display->fb_height - y - 1) ;
1362 for (i = 0; i < depth; i++)
1367 dst -= gdk_display->sinfo.line_length;
1368 src += gdk_display->fb_stride - width * depth;
1374 gdk_shadow_fb_copy_rect_270 (gint x, gint y, gint width, gint height)
1376 guchar *dst, *src, *pdst;
1381 if (!_gdk_fb_is_active_vt)
1384 depth = gdk_display->modeinfo.bits_per_pixel / 8;
1386 src = gdk_display->fb_mem + x * depth + gdk_display->fb_stride * y;
1387 dst = gdk_display->fb_mmap + (gdk_display->fb_height - y - 1) * depth + gdk_display->sinfo.line_length * x;
1394 for (i = 0; i < depth; i++)
1396 pdst += gdk_display->sinfo.line_length - depth;
1400 src += gdk_display->fb_stride - width * depth;
1405 static void (*shadow_copy_rect[4]) (gint x, gint y, gint width, gint height);
1407 volatile gint refresh_queued = 0;
1408 volatile gint refresh_x1, refresh_y1;
1409 volatile gint refresh_x2, refresh_y2;
1412 gdk_shadow_fb_refresh (int signum)
1414 gint minx, miny, maxx, maxy;
1416 if (!refresh_queued)
1418 struct itimerval timeout;
1419 /* Stop the timer */
1420 timeout.it_value.tv_sec = 0;
1421 timeout.it_value.tv_usec = 0;
1422 timeout.it_interval.tv_sec = 0;
1423 timeout.it_interval.tv_usec = 0;
1424 setitimer (ITIMER_REAL, &timeout, NULL);
1438 maxx = MAX (maxx, 0);
1440 if (maxx >= gdk_display->fb_width) {
1441 maxx = gdk_display->fb_width-1;
1442 minx = MIN (minx, maxx);
1447 maxy = MAX (maxy, 0);
1449 if (maxy >= gdk_display->fb_height) {
1450 maxy = gdk_display->fb_height-1;
1451 miny = MIN (miny, maxy);
1454 (*shadow_copy_rect[_gdk_fb_screen_angle]) (minx, miny, maxx - minx + 1, maxy - miny + 1);
1458 gdk_shadow_fb_stop_updates (void)
1460 struct itimerval timeout;
1464 /* Stop the timer */
1465 timeout.it_value.tv_sec = 0;
1466 timeout.it_value.tv_usec = 0;
1467 timeout.it_interval.tv_sec = 0;
1468 timeout.it_interval.tv_usec = 0;
1469 setitimer (ITIMER_REAL, &timeout, NULL);
1475 gdk_shadow_fb_init (void)
1477 struct sigaction action;
1479 action.sa_handler = gdk_shadow_fb_refresh;
1480 sigemptyset (&action.sa_mask);
1481 action.sa_flags = 0;
1483 sigaction (SIGALRM, &action, NULL);
1485 shadow_copy_rect[GDK_FB_0_DEGREES] = gdk_shadow_fb_copy_rect_0;
1486 shadow_copy_rect[GDK_FB_90_DEGREES] = gdk_shadow_fb_copy_rect_90;
1487 shadow_copy_rect[GDK_FB_180_DEGREES] = gdk_shadow_fb_copy_rect_180;
1488 shadow_copy_rect[GDK_FB_270_DEGREES] = gdk_shadow_fb_copy_rect_270;
1491 /* maxx and maxy are included */
1493 gdk_shadow_fb_update (gint minx, gint miny, gint maxx, gint maxy)
1495 struct itimerval timeout;
1497 if (gdk_display->manager_blocked)
1500 g_assert (minx <= maxx);
1501 g_assert (miny <= maxy);
1505 refresh_x1 = MIN (refresh_x1, minx);
1506 refresh_y1 = MIN (refresh_y1, miny);
1507 refresh_x2 = MAX (refresh_x2, maxx);
1508 refresh_y2 = MAX (refresh_y2, maxy);
1519 getitimer (ITIMER_REAL, &timeout);
1520 if (timeout.it_value.tv_usec == 0)
1522 timeout.it_value.tv_sec = 0;
1523 timeout.it_value.tv_usec = 20000; /* 20 ms => 50 fps */
1524 timeout.it_interval.tv_sec = 0;
1525 timeout.it_interval.tv_usec = 20000; /* 20 ms => 50 fps */
1526 setitimer (ITIMER_REAL, &timeout, NULL);
1534 gdk_shadow_fb_stop_updates (void)
1539 gdk_shadow_fb_update (gint minx, gint miny, gint maxx, gint maxy)
1544 gdk_shadow_fb_init (void)