diff options
author | Alexander Larsson <alexl@redhat.com> | 2001-01-11 16:39:21 +0000 |
---|---|---|
committer | Alexander Larsson <alexl@src.gnome.org> | 2001-01-11 16:39:21 +0000 |
commit | b29eece81f4b4457a15397b0476fec6e036f72e8 (patch) | |
tree | 685bd8045b3bed3605c64497a250376d049d95ad /gdk | |
parent | d2c345480b590bbd2f95e8e92687bce18fd4c289 (diff) | |
download | gtk+-b29eece81f4b4457a15397b0476fec6e036f72e8.tar.gz |
Added ENABLE_SHADOW_FB
2001-01-11 Alexander Larsson <alexl@redhat.com>
* acconfig.h:
Added ENABLE_SHADOW_FB
* configure.in:
Added --disable-shadowfb
* gdk/linux-fb/gdkcursor-fb.c:
Update shadowfb when updating cursor
* gdk/linux-fb/gdkdrawable-fb2.c:
Added wrappers for shadowfb that calls the normal drawable
methods, but calls gdk_shadow_fb_update(bounding box) when
GdkWindows are drawed to.
Moved gdk_draw_glyphs implementation to _gdk_draw_glyphs
which also returns the bounding box.
* gdk/linux-fb/gdkfb.h:
Added GdkFBAngle type and gdk_fb_set_rotation declaration.
* gdk/linux-fb/gdkgeometry-fb.c:
Update shadowfb when scrolling window.
* gdk/linux-fb/gdkglobals-fb.c:
Add _gdk_fb_screen_angle.
* gdk/linux-fb/gdkkeyboard-fb.c:
Test code for screen rotation. Shift-F2 in the xlate driver
rotates the screen.
* gdk/linux-fb/gdkmain-fb.c:
Handle shadowfb. Add gdk_fb_set_rotation(). Remove CM and RP.
* gdk/linux-fb/gdkmouse-fb.c:
Use fb_width/height instead of modeinfo.xres/yres.
* gdk/linux-fb/gdkprivate-fb.h:
Added fb_men, fb_width, fb_height & fb_stride. When using
shadow fb these can differ from the framebuffer stuff.
Declarations for gdk_shadow_fb_update, gdk_shadow_fb_init,
gdk_shadow_fb_stop_updates, gdk_fb_recompute_all,
_gdk_fb_screen_angle. Removed CM, RP.
* gdk/linux-fb/gdkrender-fb.c:
Added code for shadowfb handling and screen rotation using
shadowfb.
* gdk/linux-fb/gdkwindow-fb.c:
Use fb_mem, fb_stride, fb_width, fb_height.
Added recompute_rowstride to reset the rowstride of all windows.
Added gdk_fb_recompute_all() which recomputes rootwindow size,
window abs positions and window rowstrides. Usefull when the
rotation has changed.
Diffstat (limited to 'gdk')
-rw-r--r-- | gdk/linux-fb/gdkcursor-fb.c | 6 | ||||
-rw-r--r-- | gdk/linux-fb/gdkdrawable-fb2.c | 466 | ||||
-rw-r--r-- | gdk/linux-fb/gdkfb.h | 10 | ||||
-rw-r--r-- | gdk/linux-fb/gdkgeometry-fb.c | 3 | ||||
-rw-r--r-- | gdk/linux-fb/gdkglobals-fb.c | 1 | ||||
-rw-r--r-- | gdk/linux-fb/gdkkeyboard-fb.c | 10 | ||||
-rw-r--r-- | gdk/linux-fb/gdkmain-fb.c | 117 | ||||
-rw-r--r-- | gdk/linux-fb/gdkmouse-fb.c | 8 | ||||
-rw-r--r-- | gdk/linux-fb/gdkprivate-fb.h | 28 | ||||
-rw-r--r-- | gdk/linux-fb/gdkrender-fb.c | 248 | ||||
-rw-r--r-- | gdk/linux-fb/gdkwindow-fb.c | 44 |
11 files changed, 851 insertions, 90 deletions
diff --git a/gdk/linux-fb/gdkcursor-fb.c b/gdk/linux-fb/gdkcursor-fb.c index 9aefc0abda..fd5288e688 100644 --- a/gdk/linux-fb/gdkcursor-fb.c +++ b/gdk/linux-fb/gdkcursor-fb.c @@ -337,6 +337,9 @@ gdk_fb_cursor_hide (void) last_location.y, last_contents_size.x, last_contents_size.y); + gdk_shadow_fb_update (last_location.x, last_location.y, + last_location.x + last_contents_size.x, + last_location.y + last_contents_size.y); } } @@ -409,6 +412,9 @@ gdk_fb_cursor_unhide() last_location.x, last_location.y, pixmap_last->width, pixmap_last->height); + gdk_shadow_fb_update (last_location.x, last_location.y, + last_location.x + pixmap_last->width, + last_location.y + pixmap_last->height); } else gdk_fb_cursor_invalidate (); diff --git a/gdk/linux-fb/gdkdrawable-fb2.c b/gdk/linux-fb/gdkdrawable-fb2.c index dd3f45d48b..b531580233 100644 --- a/gdk/linux-fb/gdkdrawable-fb2.c +++ b/gdk/linux-fb/gdkdrawable-fb2.c @@ -1,3 +1,4 @@ +#include "config.h" #include "gdkprivate-fb.h" #include "mi.h" #include <string.h> @@ -76,6 +77,10 @@ static void gdk_fb_draw_segments (GdkDrawable *drawable, GdkGC *gc, GdkSegment *segs, gint nsegs); +static void gdk_fb_draw_lines (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints); static GdkColormap* gdk_fb_get_colormap (GdkDrawable *drawable); static void gdk_fb_set_colormap (GdkDrawable *drawable, GdkColormap *colormap); @@ -83,6 +88,81 @@ static gint gdk_fb_get_depth (GdkDrawable *drawable); static GdkVisual* gdk_fb_get_visual (GdkDrawable *drawable); static void gdk_fb_drawable_finalize (GObject *object); +#ifdef ENABLE_SHADOW_FB +static void gdk_shadow_fb_draw_rectangle (GdkDrawable *drawable, + GdkGC *gc, + gint filled, + gint x, + gint y, + gint width, + gint height); +static void gdk_shadow_fb_draw_arc (GdkDrawable *drawable, + GdkGC *gc, + gint filled, + gint x, + gint y, + gint width, + gint height, + gint angle1, + gint angle2); +static void gdk_shadow_fb_draw_polygon (GdkDrawable *drawable, + GdkGC *gc, + gint filled, + GdkPoint *points, + gint npoints); +static void gdk_shadow_fb_draw_text (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const gchar *text, + gint text_length); +static void gdk_shadow_fb_draw_text_wc (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const GdkWChar *text, + gint text_length); +static void gdk_shadow_fb_draw_glyphs (GdkDrawable *drawable, + GdkGC *gc, + PangoFont *font, + gint x, + gint y, + PangoGlyphString *glyphs); +static void gdk_shadow_fb_draw_drawable (GdkDrawable *drawable, + GdkGC *gc, + GdkPixmap *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height); +static void gdk_shadow_fb_draw_image (GdkDrawable *drawable, + GdkGC *gc, + GdkImage *image, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height); +static void gdk_shadow_fb_draw_points (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints); +static void gdk_shadow_fb_draw_segments (GdkDrawable *drawable, + GdkGC *gc, + GdkSegment *segs, + gint nsegs); +static void gdk_shadow_fb_draw_lines (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints); +#endif + + static gpointer parent_class = NULL; static void @@ -105,6 +185,20 @@ gdk_drawable_impl_fb_class_init (GdkDrawableFBClass *klass) object_class->finalize = gdk_fb_drawable_finalize; drawable_class->create_gc = _gdk_fb_gc_new; + +#ifdef ENABLE_SHADOW_FB + drawable_class->draw_rectangle = gdk_shadow_fb_draw_rectangle; + drawable_class->draw_arc = gdk_shadow_fb_draw_arc; + drawable_class->draw_polygon = gdk_shadow_fb_draw_polygon; + drawable_class->draw_text = gdk_shadow_fb_draw_text; + drawable_class->draw_text_wc = gdk_shadow_fb_draw_text_wc; + drawable_class->draw_drawable = gdk_shadow_fb_draw_drawable; + drawable_class->draw_points = gdk_shadow_fb_draw_points; + drawable_class->draw_segments = gdk_shadow_fb_draw_segments; + drawable_class->draw_lines = gdk_shadow_fb_draw_lines; + drawable_class->draw_glyphs = gdk_shadow_fb_draw_glyphs; + drawable_class->draw_image = gdk_shadow_fb_draw_image; +#else drawable_class->draw_rectangle = gdk_fb_draw_rectangle; drawable_class->draw_arc = gdk_fb_draw_arc; drawable_class->draw_polygon = gdk_fb_draw_polygon; @@ -116,6 +210,7 @@ gdk_drawable_impl_fb_class_init (GdkDrawableFBClass *klass) drawable_class->draw_lines = gdk_fb_draw_lines; drawable_class->draw_glyphs = gdk_fb_draw_glyphs; drawable_class->draw_image = gdk_fb_draw_image; +#endif drawable_class->set_colormap = gdk_fb_set_colormap; drawable_class->get_colormap = gdk_fb_get_colormap; @@ -185,7 +280,6 @@ static void gdk_fb_set_colormap (GdkDrawable *drawable, GdkColormap *colormap) { - GdkColormap *old_cmap; GdkDrawableFBData *private; private = GDK_DRAWABLE_FBDATA (drawable); @@ -854,7 +948,7 @@ gdk_fb_draw_polygon (GdkDrawable *drawable, } } -void +static void gdk_fb_draw_lines (GdkDrawable *drawable, GdkGC *gc, GdkPoint *points, @@ -913,21 +1007,23 @@ gdk_fb_drawable_clear (GdkDrawable *d) } static void -gdk_fb_draw_glyphs (GdkDrawable *drawable, - GdkGC *gc, - PangoFont *font, - gint x, - gint y, - PangoGlyphString *glyphs) +_gdk_fb_draw_glyphs (GdkDrawable *drawable, + GdkGC *gc, + PangoFont *font, + gint x, + gint y, + PangoGlyphString *glyphs, + GdkRectangle *bbox) { GdkFBDrawingContext fbdc; - FT_Bitmap bitmap; GdkPixmapFBData pixmap; PangoFT2Subfont subfont_index; PangoGlyphInfo *gi; FT_Face face; FT_UInt glyph_index; int i, xpos; + int maxy, miny; + int topy; g_return_if_fail (font); @@ -938,6 +1034,8 @@ gdk_fb_draw_glyphs (GdkDrawable *drawable, pixmap.drawable_data.abs_x = 0; pixmap.drawable_data.abs_y = 0; pixmap.drawable_data.depth = 78; + + maxy = miny = 0; gi = glyphs->glyphs; for (i = 0, xpos = 0; i < glyphs->num_glyphs; i++, gi++) @@ -959,12 +1057,15 @@ gdk_fb_draw_glyphs (GdkDrawable *drawable, pixmap.drawable_data.rowstride = face->glyph->bitmap.pitch; pixmap.drawable_data.width = face->glyph->bitmap.width; pixmap.drawable_data.height = face->glyph->bitmap.rows; - + + topy = y - face->glyph->bitmap_top + 1; + miny = MIN (miny, topy); + maxy = MAX (maxy, topy + face->glyph->bitmap.rows); gdk_fb_draw_drawable_3 (drawable, gc, (GdkPixmap *)&pixmap, &fbdc, 0, 0, x + PANGO_PIXELS (xpos) + face->glyph->bitmap_left, - y - face->glyph->bitmap_top + 1, + topy, face->glyph->bitmap.width, face->glyph->bitmap.rows); } } @@ -972,8 +1073,26 @@ gdk_fb_draw_glyphs (GdkDrawable *drawable, } gdk_fb_drawing_context_finalize (&fbdc); + + if (bbox) + { + bbox->x = x; + bbox->y = miny; + bbox->width = xpos; + bbox->height = maxy - miny; + } } +static void +gdk_fb_draw_glyphs (GdkDrawable *drawable, + GdkGC *gc, + PangoFont *font, + gint x, + gint y, + PangoGlyphString *glyphs) +{ + _gdk_fb_draw_glyphs (drawable, gc, font, x, y, glyphs, NULL); +} static void gdk_fb_draw_image (GdkDrawable *drawable, @@ -1021,3 +1140,328 @@ gdk_fb_get_visual (GdkDrawable *drawable) { return gdk_visual_get_system(); } + +#ifdef ENABLE_SHADOW_FB +static void +gdk_shadow_fb_draw_rectangle (GdkDrawable *drawable, + GdkGC *gc, + gint filled, + gint x, + gint y, + gint width, + gint height) +{ + GdkDrawableFBData *private; + + gdk_fb_draw_rectangle (drawable, gc, filled, x, y, width, height); + + private = GDK_DRAWABLE_FBDATA (drawable); + if (GDK_IS_WINDOW (private->wrapper)) + { + gint minx, miny, maxx, maxy; + gint extra_width; + + minx = x + private->abs_x; + miny = y + private->abs_y; + maxx = x + width + private->abs_x; + maxy = y + height + private->abs_y; + + if (!filled) + { + extra_width = (GDK_GC_FBDATA (gc)->values.line_width + 1) / 2; + + minx -= extra_width; + miny -= extra_width; + maxx += extra_width; + maxy += extra_width; + } + gdk_shadow_fb_update (minx, miny, maxx, maxy); + } +} + +static void +gdk_shadow_fb_draw_arc (GdkDrawable *drawable, + GdkGC *gc, + gint filled, + gint x, + gint y, + gint width, + gint height, + gint angle1, + gint angle2) +{ + GdkDrawableFBData *private; + + gdk_fb_draw_arc (drawable, gc, filled, x, y, width, height, angle1, angle2); + + private = GDK_DRAWABLE_FBDATA (drawable); + if (GDK_IS_WINDOW (private->wrapper)) + { + gint minx, miny, maxx, maxy; + gint extra_width; + + minx = x + private->abs_x; + miny = x + private->abs_y; + maxx = x + width + private->abs_x; + maxy = y + height + private->abs_x; + + if (!filled) + { + extra_width = (GDK_GC_FBDATA (gc)->values.line_width + 1) / 2; + + minx -= extra_width; + miny -= extra_width; + maxx += extra_width; + maxy += extra_width; + } + gdk_shadow_fb_update (minx, miny, maxx, maxy); + } +} + +static void +gdk_shadow_fb_draw_polygon (GdkDrawable *drawable, + GdkGC *gc, + gint filled, + GdkPoint *points, + gint npoints) +{ + GdkDrawableFBData *private; + + gdk_fb_draw_polygon (drawable, gc, filled, points, npoints); + + private = GDK_DRAWABLE_FBDATA (drawable); + if (GDK_IS_WINDOW (private->wrapper)) + { + gint minx, miny, maxx, maxy; + gint extra_width; + int i; + + minx = maxx = points[0].x; + miny = maxy = points[0].y; + + for (i=1;i<npoints;i++) + { + minx = MIN(minx, points[i].x); + maxx = MAX(maxx, points[i].x); + miny = MIN(miny, points[i].y); + maxy = MAX(maxy, points[i].y); + } + + if (!filled) + { + extra_width = (GDK_GC_FBDATA (gc)->values.line_width + 1) / 2; + + minx -= extra_width; + miny -= extra_width; + maxx += extra_width; + maxy += extra_width; + } + gdk_shadow_fb_update (minx + private->abs_x, miny + private->abs_y, + maxx + private->abs_x, maxy + private->abs_y); + } +} + +static void +gdk_shadow_fb_draw_text (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const gchar *text, + gint text_length) +{ + gdk_fb_draw_text (drawable, font, gc, x, y, text, text_length); +} + +static void +gdk_shadow_fb_draw_text_wc (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const GdkWChar *text, + gint text_length) +{ + gdk_fb_draw_text_wc (drawable, font, gc, x, y, text, text_length); +} + +static void +gdk_shadow_fb_draw_glyphs (GdkDrawable *drawable, + GdkGC *gc, + PangoFont *font, + gint x, + gint y, + PangoGlyphString *glyphs) +{ + GdkDrawableFBData *private; + GdkRectangle bbox; + + _gdk_fb_draw_glyphs (drawable, gc, font, x, y, glyphs, &bbox); + + private = GDK_DRAWABLE_FBDATA (drawable); + if (GDK_IS_WINDOW (private->wrapper)) + gdk_shadow_fb_update (bbox.x + private->abs_x, bbox.y + private->abs_y, + bbox.x + private->abs_x + bbox.width, bbox.y + private->abs_y + bbox.height); +} + +static void +gdk_shadow_fb_draw_drawable (GdkDrawable *drawable, + GdkGC *gc, + GdkPixmap *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height) +{ + GdkDrawableFBData *private; + + gdk_fb_draw_drawable (drawable, gc, src, xsrc, ysrc, xdest, ydest, width, height); + + private = GDK_DRAWABLE_FBDATA (drawable); + if (GDK_IS_WINDOW (private->wrapper)) + gdk_shadow_fb_update (xdest + private->abs_x, ydest + private->abs_y, + xdest + private->abs_x + width, ydest + private->abs_y + height); +} + +static void +gdk_shadow_fb_draw_image (GdkDrawable *drawable, + GdkGC *gc, + GdkImage *image, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height) +{ + GdkDrawableFBData *private; + + gdk_fb_draw_image (drawable, gc, image, xsrc, ysrc, xdest, ydest, width, height); + + private = GDK_DRAWABLE_FBDATA (drawable); + if (GDK_IS_WINDOW (private->wrapper)) + gdk_shadow_fb_update (xdest + private->abs_x, ydest + private->abs_y, + xdest + private->abs_x + width, ydest + private->abs_y + height); +} + +static void +gdk_shadow_fb_draw_points (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints) +{ + GdkDrawableFBData *private; + + gdk_fb_draw_points (drawable, gc, points, npoints); + + private = GDK_DRAWABLE_FBDATA (drawable); + if (GDK_IS_WINDOW (private->wrapper)) + { + gint minx, miny, maxx, maxy; + int i; + + minx = maxx = points[0].x; + miny = maxy = points[0].y; + + for (i=1;i<npoints;i++) + { + minx = MIN(minx, points[i].x); + maxx = MAX(maxx, points[i].x); + miny = MIN(miny, points[i].y); + maxy = MAX(maxy, points[i].y); + } + + gdk_shadow_fb_update (minx + private->abs_x, miny + private->abs_y, + maxx + private->abs_x, maxy + private->abs_y); + } +} + +static void +gdk_shadow_fb_draw_segments (GdkDrawable *drawable, + GdkGC *gc, + GdkSegment *segs, + gint nsegs) +{ + GdkDrawableFBData *private; + + gdk_fb_draw_segments (drawable, gc, segs, nsegs); + + private = GDK_DRAWABLE_FBDATA (drawable); + if (GDK_IS_WINDOW (private->wrapper)) + { + gint minx, miny, maxx, maxy; + gint extra_width; + int i; + + minx = maxx = segs[0].x1; + miny = maxy = segs[0].y1; + + for (i=0;i<nsegs;i++) + { + minx = MIN(minx, segs[i].x1); + maxx = MAX(maxx, segs[i].x1); + minx = MIN(minx, segs[i].x2); + maxx = MAX(maxx, segs[i].x2); + + miny = MIN(miny, segs[i].y1); + maxy = MAX(maxy, segs[i].y1); + miny = MIN(miny, segs[i].y2); + maxy = MAX(maxy, segs[i].y2); + + } + + extra_width = (GDK_GC_FBDATA (gc)->values.line_width + 1) / 2; + + minx -= extra_width; + miny -= extra_width; + maxx += extra_width; + maxy += extra_width; + + gdk_shadow_fb_update (minx + private->abs_x, miny + private->abs_y, + maxx + private->abs_x, maxy + private->abs_y); + } +} + +static void +gdk_shadow_fb_draw_lines (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints) +{ + GdkDrawableFBData *private; + + gdk_fb_draw_lines (drawable, gc, points, npoints); + + private = GDK_DRAWABLE_FBDATA (drawable); + if (GDK_IS_WINDOW (private->wrapper)) + { + gint minx, miny, maxx, maxy; + gint extra_width; + int i; + + minx = maxx = points[0].x; + miny = maxy = points[0].y; + + for (i=1;i<npoints;i++) + { + minx = MIN(minx, points[i].x); + maxx = MAX(maxx, points[i].x); + miny = MIN(miny, points[i].y); + maxy = MAX(maxy, points[i].y); + } + + extra_width = (GDK_GC_FBDATA (gc)->values.line_width + 1) / 2; + + minx -= extra_width; + miny -= extra_width; + maxx += extra_width; + maxy += extra_width; + + gdk_shadow_fb_update (minx + private->abs_x, miny + private->abs_y, + maxx + private->abs_x, maxy + private->abs_y); + } +} + +#endif diff --git a/gdk/linux-fb/gdkfb.h b/gdk/linux-fb/gdkfb.h index 7478b8c71e..71d97e448b 100644 --- a/gdk/linux-fb/gdkfb.h +++ b/gdk/linux-fb/gdkfb.h @@ -22,6 +22,13 @@ extern const char *gdk_progclass; extern GdkAtom gdk_selection_property; +typedef enum { + GDK_FB_0_DEGREES, + GDK_FB_90_DEGREES, + GDK_FB_180_DEGREES, + GDK_FB_270_DEGREES +} GdkFBAngle; + /* FB specific functions: */ typedef gboolean (*GdkWindowChildChanged) (GdkWindow *window, @@ -36,4 +43,7 @@ void gdk_fb_window_set_child_handler (GdkWindow *window, GdkWindowChildChanged changed, GdkWindowChildGetPos get_pos, gpointer user_data); + +void gdk_fb_set_rotation (GdkFBAngle angle); + #endif /* GDKFB_H */ diff --git a/gdk/linux-fb/gdkgeometry-fb.c b/gdk/linux-fb/gdkgeometry-fb.c index ace62c6f1f..3161b18cf9 100644 --- a/gdk/linux-fb/gdkgeometry-fb.c +++ b/gdk/linux-fb/gdkgeometry-fb.c @@ -48,6 +48,9 @@ gdk_window_scroll (GdkWindow *window, dest_rect.x, dest_rect.y, dest_rect.width, dest_rect.height, FALSE, FALSE); + gdk_shadow_fb_update (dest_rect.x - dx, dest_rect.y - dy, + dest_rect.x - dx + dest_rect.width, + dest_rect.y - dy + dest_rect.height); } gdk_window_invalidate_region (window, invalidate_region, TRUE); diff --git a/gdk/linux-fb/gdkglobals-fb.c b/gdk/linux-fb/gdkglobals-fb.c index 06fbd78209..cab2c87383 100644 --- a/gdk/linux-fb/gdkglobals-fb.c +++ b/gdk/linux-fb/gdkglobals-fb.c @@ -41,3 +41,4 @@ GdkFBDisplay *gdk_display = NULL; GdkCursor *_gdk_fb_pointer_grab_cursor; GdkGC *_gdk_fb_screen_gc = NULL; GdkAtom gdk_selection_property; +GdkFBAngle _gdk_fb_screen_angle = GDK_FB_0_DEGREES; diff --git a/gdk/linux-fb/gdkkeyboard-fb.c b/gdk/linux-fb/gdkkeyboard-fb.c index 1c76236c60..812694701a 100644 --- a/gdk/linux-fb/gdkkeyboard-fb.c +++ b/gdk/linux-fb/gdkkeyboard-fb.c @@ -768,6 +768,16 @@ xlate_io (GIOChannel *gioc, (xlate_codes[j].modifier & GDK_SHIFT_MASK)) gdk_fb_redraw_all (); + if ((xlate_codes[j].code == GDK_F2) && + (xlate_codes[j].modifier & GDK_SHIFT_MASK)) + { + static gint deg = 0; + deg = (deg + 1) % 4; + + gdk_fb_set_rotation (deg); + } + + gdk_fb_handle_key (xlate_codes[j].code, xlate_codes[j].code, xlate_codes[j].modifier, diff --git a/gdk/linux-fb/gdkmain-fb.c b/gdk/linux-fb/gdkmain-fb.c index 24be099a4e..54b2e67efd 100644 --- a/gdk/linux-fb/gdkmain-fb.c +++ b/gdk/linux-fb/gdkmain-fb.c @@ -580,13 +580,13 @@ gdk_fb_display_new () ioctl (display->fb_fd, FBIOBLANK, 0); /* We used to use sinfo.smem_len, but that seemed to be broken in many cases */ - display->fbmem = mmap (NULL, - display->modeinfo.yres * display->sinfo.line_length, - PROT_READ|PROT_WRITE, - MAP_SHARED, - display->fb_fd, - 0); - g_assert (display->fbmem != MAP_FAILED); + display->fb_mmap = mmap (NULL, + display->modeinfo.yres * display->sinfo.line_length, + PROT_READ|PROT_WRITE, + MAP_SHARED, + display->fb_fd, + 0); + g_assert (display->fb_mmap != MAP_FAILED); if (display->sinfo.visual == FB_VISUAL_TRUECOLOR) { @@ -595,6 +595,27 @@ gdk_fb_display_new () display->blue_byte = display->modeinfo.blue.offset >> 3; } +#ifdef ENABLE_SHADOW_FB + if (_gdk_fb_screen_angle % 2 == 0) + { + display->fb_width = display->modeinfo.xres; + display->fb_height = display->modeinfo.yres; + } + else + { + display->fb_width = display->modeinfo.yres; + display->fb_height = display->modeinfo.xres; + } + display->fb_stride = + display->fb_width * (display->modeinfo.bits_per_pixel / 8); + display->fb_mem = g_malloc(display->fb_height * display->fb_stride); +#else + display->fb_mem = display->fb_mmap; + display->fb_width = display->modeinfo.xres; + display->fb_height = display->modeinfo.yres; + display->fb_stride = display->sinfo.line_length; +#endif + return display; } @@ -607,7 +628,7 @@ gdk_fb_display_destroy (GdkFBDisplay *display) /* Enable normal text on the console */ ioctl (display->fb_fd, KDSETMODE, KD_TEXT); - munmap (display->fbmem, display->modeinfo.yres * display->sinfo.line_length); + munmap (display->fb_mmap, display->modeinfo.yres * display->sinfo.line_length); close (display->fb_fd); ioctl (display->console_fd, VT_ACTIVATE, display->start_vt); @@ -634,6 +655,8 @@ _gdk_windowing_init_check (int argc, char **argv) if (!gdk_display) return FALSE; + gdk_shadow_fb_init (); + if (!gdk_fb_keyboard_open ()) { g_warning ("Failed to initialize keyboard"); @@ -893,7 +916,7 @@ gdk_keyboard_ungrab (guint32 time) gint gdk_screen_width (void) { - return gdk_display->modeinfo.xres; + return gdk_display->fb_width; } /* @@ -914,7 +937,7 @@ gdk_screen_width (void) gint gdk_screen_height (void) { - return gdk_display->modeinfo.yres; + return gdk_display->fb_height; } /* @@ -1195,59 +1218,39 @@ gdk_event_make (GdkWindow *window, return NULL; } -/* Debug hack. Call to find malloc area overwrites: */ -void CM (void) +void +gdk_fb_set_rotation (GdkFBAngle angle) { - static gpointer mymem = NULL; - gpointer arry[256]; - int i; - - return; - - free (mymem); - - for(i = 0; i < sizeof(arry)/sizeof(arry[0]); i++) - arry[i] = malloc (i+1); - for(i = 0; i < sizeof(arry)/sizeof(arry[0]); i++) - free (arry[i]); - - mymem = malloc (256); -} - -/* XXX badhack */ -typedef struct _GdkWindowPaint GdkWindowPaint; + if (angle == _gdk_fb_screen_angle) + return; + +#ifdef ENABLE_SHADOW_FB + if (gdk_display) + { + gdk_shadow_fb_stop_updates (); -struct _GdkWindowPaint -{ - GdkRegion *region; - GdkPixmap *pixmap; - gint x_offset; - gint y_offset; -}; + _gdk_fb_screen_angle = angle; -void RP (GdkDrawable *d) -{ -#if 0 - if (GDK_DRAWABLE_TYPE(d) == GDK_DRAWABLE_PIXMAP) - { - if (!GDK_PIXMAP_FBDATA(d)->no_free_mem) + if (angle % 2 == 0) { - guchar *oldmem = GDK_DRAWABLE_FBDATA(d)->mem; - guint len = ((GDK_DRAWABLE_IMPL_FBDATA(d)->width * GDK_DRAWABLE_IMPL_FBDATA(d)->depth + 7) / 8) * GDK_DRAWABLE_IMPL_FBDATA(d)->height; - GDK_DRAWABLE_IMPL_FBDATA(d)->mem = g_malloc(len); - memcpy(GDK_DRAWABLE_IMPL_FBDATA(d)->mem, oldmem, len); - g_free(oldmem); - } - } - else - { - GSList *priv = GDK_WINDOW_P(d)->paint_stack; - for(; priv; priv = priv->next) + gdk_display->fb_width = gdk_display->modeinfo.xres; + gdk_display->fb_height = gdk_display->modeinfo.yres; + } + else { - GdkWindowPaint *p = priv->data; - - RP(p->pixmap); + gdk_display->fb_width = gdk_display->modeinfo.yres; + gdk_display->fb_height = gdk_display->modeinfo.xres; } + gdk_display->fb_stride = + gdk_display->fb_width * (gdk_display->modeinfo.bits_per_pixel / 8); + + gdk_fb_recompute_all(); + gdk_fb_redraw_all (); } + else + _gdk_fb_screen_angle = angle; +#else + g_warning ("Screen rotation without shadow fb not supported."); #endif } + diff --git a/gdk/linux-fb/gdkmouse-fb.c b/gdk/linux-fb/gdkmouse-fb.c index 63e8897c73..b4908f45d3 100644 --- a/gdk/linux-fb/gdkmouse-fb.c +++ b/gdk/linux-fb/gdkmouse-fb.c @@ -286,8 +286,8 @@ gdk_fb_mouse_open (void) mouse->dev = device; - mouse->x = gdk_display->modeinfo.xres / 2; - mouse->y = gdk_display->modeinfo.yres / 2; + mouse->x = gdk_display->fb_width / 2; + mouse->y = gdk_display->fb_height / 2; if (!device->open(mouse)) { @@ -645,8 +645,8 @@ gdk_fb_mouse_fidmour_packet (GdkFBMouse *mouse, if (y > 8192) y -= 16384; /* Now map touchscreen coords to screen coords */ - x *= ((double)gdk_display->modeinfo.xres)/4096.0; - y *= ((double)gdk_display->modeinfo.yres)/4096.0; + x *= ((double)gdk_display->fb_width)/4096.0; + y *= ((double)gdk_display->fb_height)/4096.0; } if (n) diff --git a/gdk/linux-fb/gdkprivate-fb.h b/gdk/linux-fb/gdkprivate-fb.h index 44d8e57f53..2d69755a80 100644 --- a/gdk/linux-fb/gdkprivate-fb.h +++ b/gdk/linux-fb/gdkprivate-fb.h @@ -40,7 +40,6 @@ #include <stdio.h> #include <freetype/freetype.h> - #define GDK_TYPE_DRAWABLE_IMPL_FBDATA (gdk_drawable_impl_fb_get_type ()) #define GDK_DRAWABLE_IMPL_FBDATA(win) ((GdkDrawableFBData *)((GdkWindowObject *)(win))->impl) #define GDK_IS_DRAWABLE_IMPL_FBDATA(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_DRAWABLE_IMPL_FBDATA)) @@ -126,9 +125,15 @@ struct _GdkFBDisplay int tty_fd; int console_fd; int vt, start_vt; - + + /* Used by rendering code: */ + guchar *fb_mem; + gint fb_width; /* In pixels */ + gint fb_height; /* In pixels */ + gint fb_stride; /* In bytes */ + int fb_fd; - guchar *fbmem; + guchar *fb_mmap; gpointer active_cmap; gulong mem_len; struct fb_fix_screeninfo sinfo; @@ -361,11 +366,20 @@ GdkGrabStatus gdk_fb_pointer_grab (GdkWindow *window, GdkCursor *cursor, guint32 time, gboolean implicit_grab); -void gdk_fb_pointer_ungrab (guint32 time, +void gdk_fb_pointer_ungrab (guint32 time, gboolean implicit_grab); -guint32 gdk_fb_get_time (void); +guint32 gdk_fb_get_time (void); +void gdk_shadow_fb_update (gint minx, + gint miny, + gint maxx, + gint maxy); +void gdk_shadow_fb_init (void); +void gdk_shadow_fb_stop_updates (void); +void gdk_fb_recompute_all (void); + +extern GdkFBAngle _gdk_fb_screen_angle; extern GdkWindow *_gdk_fb_pointer_grab_window, *_gdk_fb_pointer_grab_window_events, *_gdk_fb_keyboard_grab_window, *_gdk_fb_pointer_grab_confine; extern GdkEventMask _gdk_fb_pointer_grab_events, _gdk_fb_keyboard_grab_events; @@ -394,8 +408,4 @@ void gdk_fb_mouse_get_info (gint *x, gint *y, GdkModifierType *mask); - -extern void CM(void); /* Check for general mem corruption */ -extern void RP(GdkDrawable *drawable); /* Same, for pixmaps */ - #endif /* __GDK_PRIVATE_FB_H__ */ diff --git a/gdk/linux-fb/gdkrender-fb.c b/gdk/linux-fb/gdkrender-fb.c index b431c7d2fa..1535aa805b 100644 --- a/gdk/linux-fb/gdkrender-fb.c +++ b/gdk/linux-fb/gdkrender-fb.c @@ -1,5 +1,8 @@ +#include "config.h" #include "gdkprivate-fb.h" #include <string.h> +#include <signal.h> +#include <sys/time.h> /* * Reading pixel values from a generic drawable. @@ -1200,6 +1203,251 @@ _gdk_fb_gc_calc_state (GdkGC *gc, 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 + diff --git a/gdk/linux-fb/gdkwindow-fb.c b/gdk/linux-fb/gdkwindow-fb.c index ec656dd92f..2030036d94 100644 --- a/gdk/linux-fb/gdkwindow-fb.c +++ b/gdk/linux-fb/gdkwindow-fb.c @@ -209,8 +209,8 @@ gdk_window_new (GdkWindow *parent, impl->drawable_data.width = (attributes->width > 1) ? (attributes->width) : (1); impl->drawable_data.height = (attributes->height > 1) ? (attributes->height) : (1); private->window_type = impl->drawable_data.window_type = attributes->window_type; - impl->drawable_data.mem = gdk_display->fbmem; - impl->drawable_data.rowstride = gdk_display->sinfo.line_length; + impl->drawable_data.mem = gdk_display->fb_mem; + impl->drawable_data.rowstride = gdk_display->fb_stride; gdk_window_move_resize (window, x, y, impl->drawable_data.width, impl->drawable_data.height); @@ -775,9 +775,6 @@ gdk_window_hide (GdkWindow *window) private->mapped = FALSE; - if (private->parent == GDK_WINDOW_P(gdk_parent_root)) - gdk_fb_drawable_clear(gdk_parent_root); - mousewin = gdk_window_at_pointer (NULL, NULL); gdk_fb_window_send_crossing_events (mousewin, GDK_CROSSING_NORMAL); @@ -909,6 +906,33 @@ recompute_abs_positions(GdkDrawable *drawable, } static void +recompute_rowstride(GdkDrawable *drawable) +{ + GList *l; + GdkWindowObject *private; + + g_return_if_fail (GDK_IS_WINDOW (drawable)); + + private = GDK_WINDOW_P (drawable); + + GDK_DRAWABLE_IMPL_FBDATA (private)->rowstride = gdk_display->fb_stride; + for (l = private->children; l; l = l->next) + recompute_rowstride (l->data); +} + +void +gdk_fb_recompute_all (void) +{ + GDK_DRAWABLE_IMPL_FBDATA (gdk_parent_root)->width = gdk_display->fb_width; + GDK_DRAWABLE_IMPL_FBDATA (gdk_parent_root)->height = gdk_display->fb_height; + + recompute_abs_positions (gdk_parent_root, + 0, 0, 0, 0, + gdk_display->fb_width, gdk_display->fb_height); + recompute_rowstride (gdk_parent_root); +} + +static void recompute_drawable (GdkDrawable *drawable) { if (GDK_IS_WINDOW (drawable)) @@ -1035,7 +1059,9 @@ gdk_fb_window_move_resize (GdkWindow *window, } gdk_fb_drawing_context_finalize (&fbdc); } - + gdk_shadow_fb_update (region->extents.x1, region->extents.y1, + region->extents.x2, region->extents.y2); + gdk_region_union (new_region, old_region); gdk_region_subtract (new_region, region); gdk_region_destroy (region); @@ -1197,7 +1223,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), _gdk_fb_screen_gc, TRUE, x, y, width, height); + gdk_draw_rectangle (window, _gdk_fb_screen_gc, TRUE, x, y, width, height); } /* What's the diff? */ @@ -1489,8 +1515,8 @@ gdk_window_fb_get_visible_region (GdkDrawable *drawable) screen_rect.x = -priv->abs_x; screen_rect.y = -priv->abs_y; - screen_rect.width = gdk_display->modeinfo.xres; - screen_rect.height = gdk_display->modeinfo.yres; + screen_rect.width = gdk_display->fb_width; + screen_rect.height = gdk_display->fb_width; gdk_rectangle_intersect (&result_rect, &screen_rect, &result_rect); |