summaryrefslogtreecommitdiff
path: root/gdk
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2001-01-11 16:39:21 +0000
committerAlexander Larsson <alexl@src.gnome.org>2001-01-11 16:39:21 +0000
commitb29eece81f4b4457a15397b0476fec6e036f72e8 (patch)
tree685bd8045b3bed3605c64497a250376d049d95ad /gdk
parentd2c345480b590bbd2f95e8e92687bce18fd4c289 (diff)
downloadgtk+-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.c6
-rw-r--r--gdk/linux-fb/gdkdrawable-fb2.c466
-rw-r--r--gdk/linux-fb/gdkfb.h10
-rw-r--r--gdk/linux-fb/gdkgeometry-fb.c3
-rw-r--r--gdk/linux-fb/gdkglobals-fb.c1
-rw-r--r--gdk/linux-fb/gdkkeyboard-fb.c10
-rw-r--r--gdk/linux-fb/gdkmain-fb.c117
-rw-r--r--gdk/linux-fb/gdkmouse-fb.c8
-rw-r--r--gdk/linux-fb/gdkprivate-fb.h28
-rw-r--r--gdk/linux-fb/gdkrender-fb.c248
-rw-r--r--gdk/linux-fb/gdkwindow-fb.c44
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);