gtk/gdk/linux-fb/gdkwindow-fb.c

2013 lines
50 KiB
C
Raw Normal View History

2000-05-31 21:50:38 +00:00
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
2000-05-31 21:50:38 +00:00
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
2000-05-31 21:50:38 +00:00
*
* You should have received a copy of the GNU Lesser General Public
2000-05-31 21:50:38 +00:00
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
2000-05-31 21:50:38 +00:00
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "gdk.h"
#include "config.h"
#include "gdkwindow.h"
#include "gdkinputprivate.h"
#include "gdkprivate-fb.h"
#include "gdkinternals.h"
#include <limits.h>
/* Global variables: */
static GdkWindow *gdk_fb_window_containing_pointer = NULL;
static gpointer parent_class = NULL;
2000-05-31 21:50:38 +00:00
static void recompute_drawable (GdkDrawable *drawable);
static void gdk_fb_window_raise (GdkWindow *window);
static GdkRegion* gdk_window_fb_get_visible_region (GdkDrawable *drawable);
typedef struct
{
GdkWindowChildChanged changed;
GdkWindowChildGetPos get_pos;
gpointer user_data;
} GdkWindowChildHandlerData;
2000-05-31 21:50:38 +00:00
static void
g_free_2nd (gpointer a, gpointer b, gpointer data)
2000-05-31 21:50:38 +00:00
{
g_free (b);
2000-05-31 21:50:38 +00:00
}
static void
gdk_window_impl_fb_finalize (GObject *object)
2000-05-31 21:50:38 +00:00
{
GdkWindowFBData *fbd = GDK_WINDOW_FBDATA (object);
2000-05-31 21:50:38 +00:00
if (GDK_WINDOW_P (fbd->drawable_data.wrapper)->mapped)
gdk_window_hide (fbd->drawable_data.wrapper);
2000-05-31 21:50:38 +00:00
if (fbd->cursor)
gdk_cursor_unref (fbd->cursor);
2000-05-31 21:50:38 +00:00
if (fbd->properties)
2000-05-31 21:50:38 +00:00
{
g_hash_table_foreach (fbd->properties, g_free_2nd, NULL);
g_hash_table_destroy (fbd->properties);
2000-05-31 21:50:38 +00:00
}
G_OBJECT_CLASS (parent_class)->finalize (object);
2000-05-31 21:50:38 +00:00
}
static void
gdk_window_impl_fb_class_init (GdkWindowFBClass *klass)
2000-05-31 21:50:38 +00:00
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
2000-05-31 21:50:38 +00:00
parent_class = g_type_class_peek_parent (klass);
2000-05-31 21:50:38 +00:00
object_class->finalize = gdk_window_impl_fb_finalize;
/* Visible and clip regions are the same */
drawable_class->get_clip_region = gdk_window_fb_get_visible_region;
drawable_class->get_visible_region = gdk_window_fb_get_visible_region;
}
2000-05-31 21:50:38 +00:00
static void
gdk_window_impl_fb_init (GdkWindowFBData *impl)
{
impl->drawable_data.depth = gdk_display->modeinfo.bits_per_pixel;
impl->drawable_data.colormap = gdk_colormap_get_system ();
impl->event_mask = GDK_STRUCTURE_MASK;
impl->shape = NULL;
}
2000-05-31 21:50:38 +00:00
GType
_gdk_window_impl_get_type (void)
{
static GType object_type = 0;
2000-05-31 21:50:38 +00:00
if (!object_type)
{
static const GTypeInfo object_info =
{
sizeof (GdkWindowFBClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gdk_window_impl_fb_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GdkWindowFBData),
0, /* n_preallocs */
(GInstanceInitFunc) gdk_window_impl_fb_init,
};
object_type = g_type_register_static (gdk_drawable_impl_fb_get_type(),
"GdkWindowFB",
&object_info,
0);
}
return object_type;
2000-05-31 21:50:38 +00:00
}
void
_gdk_windowing_window_init (void)
2000-05-31 21:50:38 +00:00
{
GdkWindowAttr attr;
2000-05-31 21:50:38 +00:00
GdkCursor *cursor;
GdkWindowObject *private;
attr.width = gdk_screen_width ();
attr.height = gdk_screen_height ();
attr.window_type = GDK_WINDOW_ROOT;
Huge GtkFB patch with lots of small bugfixes and initial selections implementation. 2000-11-23 Alexander Larsson <alexl@redhat.com> * gdk/linux-fb/gdkselection-fb.c: Initial selection implementation. * gtk/gtkselection.c: if GDK_WINDOWING_FB defined, include linux-fb/gdkfb.h and look up requestor in gtk_selection_request. * gdk/linux-fb/gdkfb.h, gdk/linux-fb/gdkglobals-fb.c: Added gdk_selection_property atom. * gdk/linux-fb/gdkprivate-fb.h: Export _gdk_selection_window_destroyed. Removed mask_off_x/y from GdkCursorPrivateFB. Removed hbearing, added top, left to PangoFBGlyphInfo. * gdk/linux-fb/gdkwindow-fb.c (_gdk_windowing_window_destroy): Call _gdk_selection_window_destroyed (_gdk_windowing_window_init): Don't call gdk_cursor_new() before the root window has been created. (static_dx_hack, static_dy_hack, compare_draw_rects, gdk_fb_window_move_resize): Remove unnecessary sort of rectangles in region. They are already sorted. Instead just traverse them in reverse if draw_direction < 0. * gdk/linux-fb/gdkinput-ps2.c (send_button_event): Double-clicks must be sent after the normal button_press. (gdk_fb_cursor_unhide): Remove usage of mask_off_x/y. Clean up. * gdk/linux-fb/gdkgeometry-fb.c (gdk_window_scroll): Pass _gdk_fb_screen_gc instead of NULL. * gdk/linux-fb/gdkmain-fb.c (_gdk_windowing_init_check): Initialize gdk_selection_property. (gdk_event_make): Remove unused code. * gdk/linux-fb/gdkcursor-fb.c: Make the pixmap for the cursor the same size as the mask. Also remove the mask_off_x/y fields in GdkCursorPrivateFB and combine _gdk_cursor_new_from_pixmap() and gdk_cursor_new_from_pixmap() Now the whole cursor is visible. * gdk/linux-fb/gdkdrawable-fb2.c (gdk_fb_draw_drawable_3): Fix bug where xdest+height instead of ydest+height was used to calculate if the source and dest overlapped. This fixes the redraw bug when the main window in testgtk was scrolled when partially covered by a tall window. Copy rectangles in region in order depending on draw_direction. Also moved the draw_direction flipping of start_y and end_y into the gc functions, as this might not be what all of them want. (gdk_fb_draw_lines): Support dashed lines. (gdk_fb_draw_glyphs): Clean up glyph placement. Also fix positioning so that the text is positioned correctly (was 1 pixel high). gdk/linux-fb/gdkgc-fb.c: Initialize cap_style to GTK_CAP_BUTT. This fixes a problem where all lines were drawn a pixel to short. Also checked the default of the rest of the values, and they're the same as X now. * gdk/linux-fb/gdkpango-fb.c (pango_fb_font_get_glyph_info): Clean up pixel positioning of the glyphs. Just use bgy->top and bgy->left. Also used PANGO_PIXEL where appropriate and added 0.5 to all divisions to get correct rounding behaviour. * gdk/linux-fb/gdkrender-fb.c (gdk_fb_draw_drawable_generic, gdk_fb_draw_drawable_memmove, gdk_fb_draw_drawable_aa_24): Moved start_y/end_y flip into draw_drawable implementations. Flip also x rendering when draw_direction < 0. Remove unneccesary multiply with draw_direction.
2000-11-25 15:44:35 +00:00
attr.cursor = NULL;
attr.event_mask = GDK_EXPOSURE_MASK;
attr.wclass = GDK_INPUT_OUTPUT;
gdk_parent_root = gdk_window_new (NULL, &attr, GDK_WA_CURSOR);
private = (GdkWindowObject *)gdk_parent_root;
2000-05-31 21:50:38 +00:00
private->mapped = TRUE;
2000-05-31 21:50:38 +00:00
GDK_DRAWABLE_IMPL_FBDATA (gdk_parent_root)->lim_x = attr.width;
GDK_DRAWABLE_IMPL_FBDATA (gdk_parent_root)->lim_y = attr.height;
_gdk_fb_screen_gc = gdk_gc_new (gdk_parent_root);
Huge GtkFB patch with lots of small bugfixes and initial selections implementation. 2000-11-23 Alexander Larsson <alexl@redhat.com> * gdk/linux-fb/gdkselection-fb.c: Initial selection implementation. * gtk/gtkselection.c: if GDK_WINDOWING_FB defined, include linux-fb/gdkfb.h and look up requestor in gtk_selection_request. * gdk/linux-fb/gdkfb.h, gdk/linux-fb/gdkglobals-fb.c: Added gdk_selection_property atom. * gdk/linux-fb/gdkprivate-fb.h: Export _gdk_selection_window_destroyed. Removed mask_off_x/y from GdkCursorPrivateFB. Removed hbearing, added top, left to PangoFBGlyphInfo. * gdk/linux-fb/gdkwindow-fb.c (_gdk_windowing_window_destroy): Call _gdk_selection_window_destroyed (_gdk_windowing_window_init): Don't call gdk_cursor_new() before the root window has been created. (static_dx_hack, static_dy_hack, compare_draw_rects, gdk_fb_window_move_resize): Remove unnecessary sort of rectangles in region. They are already sorted. Instead just traverse them in reverse if draw_direction < 0. * gdk/linux-fb/gdkinput-ps2.c (send_button_event): Double-clicks must be sent after the normal button_press. (gdk_fb_cursor_unhide): Remove usage of mask_off_x/y. Clean up. * gdk/linux-fb/gdkgeometry-fb.c (gdk_window_scroll): Pass _gdk_fb_screen_gc instead of NULL. * gdk/linux-fb/gdkmain-fb.c (_gdk_windowing_init_check): Initialize gdk_selection_property. (gdk_event_make): Remove unused code. * gdk/linux-fb/gdkcursor-fb.c: Make the pixmap for the cursor the same size as the mask. Also remove the mask_off_x/y fields in GdkCursorPrivateFB and combine _gdk_cursor_new_from_pixmap() and gdk_cursor_new_from_pixmap() Now the whole cursor is visible. * gdk/linux-fb/gdkdrawable-fb2.c (gdk_fb_draw_drawable_3): Fix bug where xdest+height instead of ydest+height was used to calculate if the source and dest overlapped. This fixes the redraw bug when the main window in testgtk was scrolled when partially covered by a tall window. Copy rectangles in region in order depending on draw_direction. Also moved the draw_direction flipping of start_y and end_y into the gc functions, as this might not be what all of them want. (gdk_fb_draw_lines): Support dashed lines. (gdk_fb_draw_glyphs): Clean up glyph placement. Also fix positioning so that the text is positioned correctly (was 1 pixel high). gdk/linux-fb/gdkgc-fb.c: Initialize cap_style to GTK_CAP_BUTT. This fixes a problem where all lines were drawn a pixel to short. Also checked the default of the rest of the values, and they're the same as X now. * gdk/linux-fb/gdkpango-fb.c (pango_fb_font_get_glyph_info): Clean up pixel positioning of the glyphs. Just use bgy->top and bgy->left. Also used PANGO_PIXEL where appropriate and added 0.5 to all divisions to get correct rounding behaviour. * gdk/linux-fb/gdkrender-fb.c (gdk_fb_draw_drawable_generic, gdk_fb_draw_drawable_memmove, gdk_fb_draw_drawable_aa_24): Moved start_y/end_y flip into draw_drawable implementations. Flip also x rendering when draw_direction < 0. Remove unneccesary multiply with draw_direction.
2000-11-25 15:44:35 +00:00
gdk_fb_drawable_clear (gdk_parent_root);
Huge GtkFB patch with lots of small bugfixes and initial selections implementation. 2000-11-23 Alexander Larsson <alexl@redhat.com> * gdk/linux-fb/gdkselection-fb.c: Initial selection implementation. * gtk/gtkselection.c: if GDK_WINDOWING_FB defined, include linux-fb/gdkfb.h and look up requestor in gtk_selection_request. * gdk/linux-fb/gdkfb.h, gdk/linux-fb/gdkglobals-fb.c: Added gdk_selection_property atom. * gdk/linux-fb/gdkprivate-fb.h: Export _gdk_selection_window_destroyed. Removed mask_off_x/y from GdkCursorPrivateFB. Removed hbearing, added top, left to PangoFBGlyphInfo. * gdk/linux-fb/gdkwindow-fb.c (_gdk_windowing_window_destroy): Call _gdk_selection_window_destroyed (_gdk_windowing_window_init): Don't call gdk_cursor_new() before the root window has been created. (static_dx_hack, static_dy_hack, compare_draw_rects, gdk_fb_window_move_resize): Remove unnecessary sort of rectangles in region. They are already sorted. Instead just traverse them in reverse if draw_direction < 0. * gdk/linux-fb/gdkinput-ps2.c (send_button_event): Double-clicks must be sent after the normal button_press. (gdk_fb_cursor_unhide): Remove usage of mask_off_x/y. Clean up. * gdk/linux-fb/gdkgeometry-fb.c (gdk_window_scroll): Pass _gdk_fb_screen_gc instead of NULL. * gdk/linux-fb/gdkmain-fb.c (_gdk_windowing_init_check): Initialize gdk_selection_property. (gdk_event_make): Remove unused code. * gdk/linux-fb/gdkcursor-fb.c: Make the pixmap for the cursor the same size as the mask. Also remove the mask_off_x/y fields in GdkCursorPrivateFB and combine _gdk_cursor_new_from_pixmap() and gdk_cursor_new_from_pixmap() Now the whole cursor is visible. * gdk/linux-fb/gdkdrawable-fb2.c (gdk_fb_draw_drawable_3): Fix bug where xdest+height instead of ydest+height was used to calculate if the source and dest overlapped. This fixes the redraw bug when the main window in testgtk was scrolled when partially covered by a tall window. Copy rectangles in region in order depending on draw_direction. Also moved the draw_direction flipping of start_y and end_y into the gc functions, as this might not be what all of them want. (gdk_fb_draw_lines): Support dashed lines. (gdk_fb_draw_glyphs): Clean up glyph placement. Also fix positioning so that the text is positioned correctly (was 1 pixel high). gdk/linux-fb/gdkgc-fb.c: Initialize cap_style to GTK_CAP_BUTT. This fixes a problem where all lines were drawn a pixel to short. Also checked the default of the rest of the values, and they're the same as X now. * gdk/linux-fb/gdkpango-fb.c (pango_fb_font_get_glyph_info): Clean up pixel positioning of the glyphs. Just use bgy->top and bgy->left. Also used PANGO_PIXEL where appropriate and added 0.5 to all divisions to get correct rounding behaviour. * gdk/linux-fb/gdkrender-fb.c (gdk_fb_draw_drawable_generic, gdk_fb_draw_drawable_memmove, gdk_fb_draw_drawable_aa_24): Moved start_y/end_y flip into draw_drawable implementations. Flip also x rendering when draw_direction < 0. Remove unneccesary multiply with draw_direction.
2000-11-25 15:44:35 +00:00
/* Must be done after root is created, since gdk_cursor_new()
* references gdk_parent_root.
*/
cursor = gdk_cursor_new (GDK_LEFT_PTR);
gdk_window_set_cursor (gdk_parent_root, cursor);
2000-05-31 21:50:38 +00:00
}
GdkWindow*
gdk_window_new (GdkWindow *parent,
GdkWindowAttr *attributes,
gint attributes_mask)
{
GdkWindow *window;
GdkWindowObject *private;
GdkWindowObject *parent_private;
2000-05-31 21:50:38 +00:00
GdkVisual *visual;
GdkWindowFBData *impl;
2000-05-31 21:50:38 +00:00
int x, y, depth;
g_return_val_if_fail (attributes != NULL, NULL);
if (!parent || attributes->window_type != GDK_WINDOW_CHILD)
parent = gdk_parent_root;
parent_private = (GdkWindowObject*) parent;
2000-05-31 21:50:38 +00:00
window = (GdkWindow *)g_object_new (GDK_TYPE_WINDOW, NULL);
private = (GdkWindowObject *)window;
2000-05-31 21:50:38 +00:00
private->parent = parent_private;
2000-05-31 21:50:38 +00:00
if (attributes_mask & GDK_WA_X)
x = attributes->x;
else
x = 0;
if (attributes_mask & GDK_WA_Y)
y = attributes->y;
else
y = 0;
gdk_window_set_events (window, attributes->event_mask);
2000-05-31 21:50:38 +00:00
if (attributes_mask & GDK_WA_VISUAL)
visual = attributes->visual;
else
visual = gdk_visual_get_system ();
2000-05-31 21:50:38 +00:00
impl = (GdkWindowFBData *)private->impl;
impl->drawable_data.wrapper = window;
2000-05-31 21:50:38 +00:00
private->x = x;
private->y = y;
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;
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.
2001-01-11 16:39:21 +00:00
impl->drawable_data.mem = gdk_display->fb_mem;
impl->drawable_data.rowstride = gdk_display->fb_stride;
2000-05-31 21:50:38 +00:00
gdk_window_move_resize (window, x, y,
impl->drawable_data.width, impl->drawable_data.height);
2000-05-31 21:50:38 +00:00
if (attributes->wclass == GDK_INPUT_OUTPUT)
{
depth = visual->depth;
private->input_only = FALSE;
private->depth = impl->drawable_data.depth;
2000-05-31 21:50:38 +00:00
if ((attributes_mask & GDK_WA_COLORMAP) &&
attributes->colormap)
impl->drawable_data.colormap = attributes->colormap;
else
impl->drawable_data.colormap = gdk_colormap_get_system ();
2000-05-31 21:50:38 +00:00
switch (impl->drawable_data.window_type)
2000-05-31 21:50:38 +00:00
{
case GDK_WINDOW_TOPLEVEL:
case GDK_WINDOW_CHILD:
case GDK_WINDOW_DIALOG:
case GDK_WINDOW_TEMP:
default:
2000-05-31 21:50:38 +00:00
break;
case GDK_WINDOW_ROOT:
if (gdk_parent_root)
g_error ("cannot make windows of type GDK_WINDOW_ROOT");
2000-05-31 21:50:38 +00:00
break;
case GDK_DRAWABLE_PIXMAP:
g_error ("cannot make windows of type GDK_DRAWABLE_PIXMAP (use gdk_pixmap_new)");
2000-05-31 21:50:38 +00:00
break;
}
}
else
{
depth = 0;
private->input_only = TRUE;
impl->drawable_data.colormap = NULL;
2000-05-31 21:50:38 +00:00
}
gdk_drawable_ref (window);
if (impl->drawable_data.colormap)
gdk_colormap_ref (impl->drawable_data.colormap);
2000-05-31 21:50:38 +00:00
gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
(attributes->cursor) :
NULL));
2000-05-31 21:50:38 +00:00
if (parent_private)
parent_private->children = g_list_prepend (parent_private->children, window);
2000-05-31 21:50:38 +00:00
return window;
}
/* This function is called when the XWindow is really gone. */
2000-05-31 21:50:38 +00:00
void
_gdk_windowing_window_destroy (GdkWindow *window,
gboolean recursing,
gboolean foreign_destroy)
2000-05-31 21:50:38 +00:00
{
GdkWindowObject *private;
GdkRectangle r;
private = (GdkWindowObject*) window;
2000-05-31 21:50:38 +00:00
_gdk_selection_window_destroyed (window);
r.x = private->x;
r.y = private->y;
r.width = GDK_DRAWABLE_IMPL_FBDATA (window)->width;
r.height = GDK_DRAWABLE_IMPL_FBDATA (window)->height;
/* Clear the root window, as it might be visible under
the destroyed window */
gdk_window_clear_area (gdk_parent_root,
r.x,
r.y,
r.width,
r.height);
/* Invalidate the rect */
gdk_window_invalidate_rect ((GdkWindow *)private->parent, &r, TRUE);
}
2000-05-31 21:50:38 +00:00
static gboolean
all_parents_shown (GdkWindowObject *private)
2000-05-31 21:50:38 +00:00
{
while (private->mapped)
2000-05-31 21:50:38 +00:00
{
if (private->parent)
private = (GdkWindowObject *)private->parent;
2000-05-31 21:50:38 +00:00
else
return TRUE;
}
return FALSE;
}
static void
send_map_events (GdkWindowObject *private, gboolean is_map)
2000-05-31 21:50:38 +00:00
{
GList *l;
GdkWindow *parent = (GdkWindow *)private->parent;
2000-05-31 21:50:38 +00:00
g_assert (is_map);
if (!private->mapped)
2000-05-31 21:50:38 +00:00
return;
if (is_map)
gdk_event_make ((GdkWindow *)private, GDK_MAP, TRUE);
2000-05-31 21:50:38 +00:00
if (private->input_only)
2000-05-31 21:50:38 +00:00
return;
if (!parent)
2000-05-31 21:50:38 +00:00
parent = (GdkWindow *)private;
if (((GDK_DRAWABLE_IMPL_FBDATA (private)->abs_x > GDK_DRAWABLE_IMPL_FBDATA (parent)->lim_x) ||
(GDK_DRAWABLE_IMPL_FBDATA (private)->abs_y > GDK_DRAWABLE_IMPL_FBDATA (parent)->lim_y) ||
(GDK_DRAWABLE_IMPL_FBDATA (private)->lim_x < GDK_DRAWABLE_IMPL_FBDATA (parent)->llim_x) ||
(GDK_DRAWABLE_IMPL_FBDATA (private)->lim_y < GDK_DRAWABLE_IMPL_FBDATA (parent)->llim_y)))
2000-05-31 21:50:38 +00:00
return;
if (is_map)
gdk_window_clear ((GdkWindow *)private);
2000-05-31 21:50:38 +00:00
for (l = private->children; l; l = l->next)
send_map_events (l->data, is_map);
2000-05-31 21:50:38 +00:00
}
/* Cut & paste versions of the stuff in gdkwindow.c, with the addition of clearing the newly exposed region. */
2000-05-31 21:50:38 +00:00
void
gdk_window_invalidate_region_clear(GdkWindow *window,
GdkRegion *region)
2000-05-31 21:50:38 +00:00
{
int i;
GdkWindowObject *private = GDK_WINDOW_P (window);
if (private->input_only || !private->mapped)
return;
if (private->bg_pixmap != GDK_NO_BG)
for (i = 0; i < region->numRects; i++)
gdk_window_clear_area (window,
region->rects[i].x1,
region->rects[i].y1,
region->rects[i].x2 - region->rects[i].x1,
region->rects[i].y2 - region->rects[i].y1);
gdk_window_invalidate_region (window, region, FALSE);
{
GList *tmp_list;
GdkRectangle child_rect;
GdkRegion *child_region;
tmp_list = private->children;
while (tmp_list)
{
GdkWindowObject *child = tmp_list->data;
tmp_list = tmp_list->next;
if (!child->input_only)
{
gint width, height;
gdk_drawable_get_size (GDK_DRAWABLE (child),
&width, &height);
child_rect.x = child->x;
child_rect.y = child->y;
child_rect.width = width;
child_rect.height = height;
child_region = gdk_region_rectangle (&child_rect);
gdk_region_intersect (child_region, region);
if (!gdk_region_empty (child_region))
{
gdk_region_offset (child_region, - child_rect.x, - child_rect.y);
gdk_window_invalidate_region_clear ((GdkWindow *)child, child_region);
}
gdk_region_destroy (child_region);
}
}
}
2000-05-31 21:50:38 +00:00
}
void
gdk_window_invalidate_rect_clear (GdkWindow *window,
GdkRectangle *rect)
2000-05-31 21:50:38 +00:00
{
GdkWindowObject *private = GDK_WINDOW_P (window);
2000-05-31 21:50:38 +00:00
if (private->input_only || !private->mapped)
return;
2000-05-31 21:50:38 +00:00
if (GDK_WINDOW_P (window)->bg_pixmap != GDK_NO_BG)
gdk_window_clear_area (window, rect->x, rect->y, rect->width, rect->height);
gdk_window_invalidate_rect (window, rect, FALSE);
{
GList *tmp_list;
GdkRectangle child_rect, new_rect;
tmp_list = private->children;
while (tmp_list)
{
GdkWindowObject *child = tmp_list->data;
tmp_list = tmp_list->next;
if (!child->input_only)
{
gint width, height;
width = GDK_DRAWABLE_IMPL_FBDATA (child)->width;
height = GDK_DRAWABLE_IMPL_FBDATA (child)->height;
child_rect.x = child->x;
child_rect.y = child->y;
child_rect.width = width;
child_rect.height = height;
if (gdk_rectangle_intersect (rect, &child_rect, &new_rect))
{
new_rect.x -= child_rect.x;
new_rect.y -= child_rect.y;
gdk_window_invalidate_rect_clear ((GdkWindow *)child, &new_rect);
}
}
}
}
}
2000-05-31 21:50:38 +00:00
void
gdk_fb_redraw_all (void)
{
GdkRectangle r;
r.x = r.y = 0;
r.width = GDK_DRAWABLE_IMPL_FBDATA (gdk_parent_root)->width;
r.height = GDK_DRAWABLE_IMPL_FBDATA (gdk_parent_root)->height;
gdk_window_invalidate_rect_clear (gdk_parent_root, &r);
gdk_window_process_all_updates ();
2000-05-31 21:50:38 +00:00
}
/* Focus follows pointer */
GdkWindow *
_gdk_fb_window_find_focus (GdkWindow *window_with_mouse)
{
if (_gdk_fb_keyboard_grab_window)
return _gdk_fb_keyboard_grab_window;
else if (window_with_mouse)
{
GdkWindowObject *priv = (GdkWindowObject *)window_with_mouse;
while (priv != (GdkWindowObject *)gdk_parent_root)
{
if ((priv->parent == (GdkWindowObject *)gdk_parent_root) && priv->mapped)
return (GdkWindow *)priv;
priv = priv->parent;
}
}
return gdk_parent_root;
}
GdkWindow *
gdk_fb_window_find_focus (void)
{
return _gdk_fb_window_find_focus (gdk_fb_window_containing_pointer);
}
static void
gdk_fb_send_focus_change (GdkWindow *old_window_containing_pointer,
GdkWindow *new_window_containing_pointer)
{
GdkEventFocus *event;
GdkWindow *old_win, *new_win;
old_win = _gdk_fb_window_find_focus (old_window_containing_pointer);
new_win = _gdk_fb_window_find_focus (new_window_containing_pointer);
if (old_win != new_win)
{
event = (GdkEventFocus *)gdk_event_make (old_win, GDK_FOCUS_CHANGE, TRUE);
if (event)
event->in = FALSE;
event = (GdkEventFocus *)gdk_event_make (new_win, GDK_FOCUS_CHANGE, TRUE);
if (event)
event->in = TRUE;
}
}
static GdkWindow *
gdk_fb_find_common_ancestor (GdkWindow *win1,
GdkWindow *win2)
{
GdkWindowObject *tmp;
GList *path1 = NULL, *path2 = NULL;
GList *list1, *list2;
tmp = GDK_WINDOW_OBJECT (win1);
while (tmp)
{
path1 = g_list_prepend(path1, tmp);
tmp = tmp->parent;
}
tmp = GDK_WINDOW_OBJECT (win2);
while (tmp)
{
path2 = g_list_prepend(path2, tmp);
tmp = tmp->parent;
}
list1 = path1;
list2 = path2;
tmp = NULL;
while (list1 && list2 && (list1->data == list2->data))
{
tmp = (GdkWindowObject *)list1->data;
list1 = g_list_next (list1);
list2 = g_list_next (list2);
}
g_list_free (path1);
g_list_free (path2);
return GDK_WINDOW (tmp);
}
void
gdk_fb_window_send_crossing_events (GdkWindow *dest,
GdkCrossingMode mode)
{
GdkWindow *c;
GdkWindow *win, *last, *next;
GdkEvent *event;
gint x, y, x_int, y_int;
GdkModifierType my_mask;
GList *path, *list;
gboolean non_linear;
gboolean only_grabbed_window;
GdkWindow *a;
GdkWindow *b;
if ((mode == GDK_CROSSING_NORMAL) &&
(dest == gdk_fb_window_containing_pointer))
return;
if (gdk_fb_window_containing_pointer == NULL)
gdk_fb_window_containing_pointer = gdk_window_ref (gdk_parent_root);
if (mode == GDK_CROSSING_UNGRAB)
a = _gdk_fb_pointer_grab_window;
else
a = gdk_fb_window_containing_pointer;
b = dest;
/* When grab in progress only send normal crossing events about
* the grabbed window.
*/
only_grabbed_window = (_gdk_fb_pointer_grab_window_events != NULL) &&
(mode == GDK_CROSSING_NORMAL);
if (a==b)
return;
gdk_fb_mouse_get_info (&x, &y, &my_mask);
c = gdk_fb_find_common_ancestor (a, b);
non_linear = (c != a) && (c != b);
if (!only_grabbed_window || (a == _gdk_fb_pointer_grab_window))
event = gdk_event_make (a, GDK_LEAVE_NOTIFY, TRUE);
else
event = NULL;
if (event)
{
event->crossing.subwindow = NULL;
gdk_window_get_root_origin (a, &x_int, &y_int);
event->crossing.x = x - x_int;
event->crossing.y = y - y_int;
event->crossing.x_root = x;
event->crossing.y_root = y;
event->crossing.mode = mode;
if (non_linear)
event->crossing.detail = GDK_NOTIFY_NONLINEAR;
else if (c==a)
event->crossing.detail = GDK_NOTIFY_INFERIOR;
else
event->crossing.detail = GDK_NOTIFY_ANCESTOR;
event->crossing.focus = FALSE;
event->crossing.state = my_mask;
}
/* Traverse up from a to (excluding) c */
if (c != a)
{
last = a;
win = GDK_WINDOW (GDK_WINDOW_OBJECT (a)->parent);
while (win != c)
{
if (!only_grabbed_window || (win == _gdk_fb_pointer_grab_window))
event = gdk_event_make (win, GDK_LEAVE_NOTIFY, TRUE);
else
event = NULL;
if (event)
{
event->crossing.subwindow = gdk_window_ref (last);
gdk_window_get_root_origin (win, &x_int, &y_int);
event->crossing.x = x - x_int;
event->crossing.y = y - y_int;
event->crossing.x_root = x;
event->crossing.y_root = y;
event->crossing.mode = mode;
if (non_linear)
event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
else
event->crossing.detail = GDK_NOTIFY_VIRTUAL;
event->crossing.focus = FALSE;
event->crossing.state = my_mask;
}
last = win;
win = GDK_WINDOW (GDK_WINDOW_OBJECT (win)->parent);
}
}
/* Traverse down from c to b */
if (c != b)
{
path = NULL;
win = GDK_WINDOW( GDK_WINDOW_OBJECT (b)->parent);
while (win != c)
{
path = g_list_prepend (path, win);
win = GDK_WINDOW( GDK_WINDOW_OBJECT (win)->parent);
}
list = path;
while (list)
{
win = (GdkWindow *)list->data;
list = g_list_next (list);
if (list)
next = (GdkWindow *)list->data;
else
next = b;
if (!only_grabbed_window || (win == _gdk_fb_pointer_grab_window))
event = gdk_event_make (win, GDK_ENTER_NOTIFY, TRUE);
else
event = NULL;
if (event)
{
event->crossing.subwindow = gdk_window_ref (next);
gdk_window_get_root_origin (win, &x_int, &y_int);
event->crossing.x = x - x_int;
event->crossing.y = y - y_int;
event->crossing.x_root = x;
event->crossing.y_root = y;
event->crossing.mode = mode;
if (non_linear)
event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
else
event->crossing.detail = GDK_NOTIFY_VIRTUAL;
event->crossing.focus = FALSE;
event->crossing.state = my_mask;
}
}
g_list_free (path);
}
if (!only_grabbed_window || (b == _gdk_fb_pointer_grab_window))
event = gdk_event_make (b, GDK_ENTER_NOTIFY, TRUE);
else
event = NULL;
if (event)
{
event->crossing.subwindow = NULL;
gdk_window_get_root_origin (b, &x_int, &y_int);
event->crossing.x = x - x_int;
event->crossing.y = y - y_int;
event->crossing.x_root = x;
event->crossing.y_root = y;
event->crossing.mode = mode;
if (non_linear)
event->crossing.detail = GDK_NOTIFY_NONLINEAR;
else if (c==a)
event->crossing.detail = GDK_NOTIFY_ANCESTOR;
else
event->crossing.detail = GDK_NOTIFY_INFERIOR;
event->crossing.focus = FALSE;
event->crossing.state = my_mask;
}
if ((mode != GDK_CROSSING_GRAB) &&
(b != gdk_fb_window_containing_pointer) &&
!only_grabbed_window)
{
gdk_fb_send_focus_change (gdk_fb_window_containing_pointer, b);
gdk_window_unref (gdk_fb_window_containing_pointer);
gdk_fb_window_containing_pointer = gdk_window_ref (b);
}
}
2000-05-31 21:50:38 +00:00
void
gdk_window_show (GdkWindow *window)
{
GdkWindowObject *private;
GdkWindow *mousewin;
2000-05-31 21:50:38 +00:00
g_return_if_fail (window != NULL);
private = (GdkWindowObject*) window;
2000-05-31 21:50:38 +00:00
if (!private->destroyed && !private->mapped)
2000-05-31 21:50:38 +00:00
{
private->mapped = TRUE;
gdk_fb_window_raise (window);
if (all_parents_shown ((GdkWindowObject *)private->parent))
2000-05-31 21:50:38 +00:00
{
GdkRectangle rect;
recompute_drawable ((GdkDrawable *)window);
send_map_events (private, TRUE);
2000-05-31 21:50:38 +00:00
mousewin = gdk_window_at_pointer (NULL, NULL);
gdk_fb_window_send_crossing_events (mousewin,
GDK_CROSSING_NORMAL);
2000-05-31 21:50:38 +00:00
if (private->input_only)
return;
2000-05-31 21:50:38 +00:00
rect.x = GDK_DRAWABLE_IMPL_FBDATA (window)->llim_x;
rect.y = GDK_DRAWABLE_IMPL_FBDATA (window)->llim_y;
rect.width = GDK_DRAWABLE_IMPL_FBDATA (window)->lim_x - rect.x;
rect.height = GDK_DRAWABLE_IMPL_FBDATA (window)->lim_y - rect.y;
gdk_window_invalidate_rect (gdk_parent_root, &rect, TRUE);
}
2000-05-31 21:50:38 +00:00
}
}
void
gdk_window_hide (GdkWindow *window)
{
GdkWindowObject *private;
GdkWindow *mousewin;
2000-05-31 21:50:38 +00:00
g_return_if_fail (window != NULL);
private = (GdkWindowObject*) window;
2000-05-31 21:50:38 +00:00
if (!private->destroyed && private->mapped)
2000-05-31 21:50:38 +00:00
{
GdkEvent *event;
GdkRectangle r;
gboolean do_hide;
2000-05-31 21:50:38 +00:00
event = gdk_event_make (window, GDK_UNMAP, TRUE);
2000-05-31 21:50:38 +00:00
r.x = GDK_DRAWABLE_IMPL_FBDATA (window)->llim_x;
r.y = GDK_DRAWABLE_IMPL_FBDATA (window)->llim_y;
r.width = GDK_DRAWABLE_IMPL_FBDATA (window)->lim_x - r.x;
r.height = GDK_DRAWABLE_IMPL_FBDATA (window)->lim_y - r.y;
2000-05-31 21:50:38 +00:00
private->mapped = FALSE;
mousewin = gdk_window_at_pointer (NULL, NULL);
gdk_fb_window_send_crossing_events (mousewin,
GDK_CROSSING_NORMAL);
do_hide = gdk_fb_cursor_need_hide (&r);
if (do_hide)
gdk_fb_cursor_hide ();
if (window == _gdk_fb_pointer_grab_window)
gdk_pointer_ungrab (GDK_CURRENT_TIME);
if (window == _gdk_fb_keyboard_grab_window)
gdk_keyboard_ungrab (GDK_CURRENT_TIME);
/* Clear the root window, as it might be visible under
the hidden window*/
gdk_window_clear_area (gdk_parent_root,
r.x,
r.y,
r.width,
r.height);
/* Invalidate the rect */
gdk_window_invalidate_rect (gdk_parent_root, &r, TRUE);
if (do_hide)
gdk_fb_cursor_unhide ();
2000-05-31 21:50:38 +00:00
}
}
void
gdk_window_withdraw (GdkWindow *window)
{
gdk_window_hide (window);
2000-05-31 21:50:38 +00:00
}
void
gdk_window_move (GdkWindow *window,
gint x,
gint y)
{
GdkWindowObject *private = (GdkWindowObject *)window;
2000-05-31 21:50:38 +00:00
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
gdk_window_move_resize (window, x, y,
GDK_DRAWABLE_IMPL_FBDATA (private)->width,
GDK_DRAWABLE_IMPL_FBDATA (private)->height);
2000-05-31 21:50:38 +00:00
}
void
gdk_window_resize (GdkWindow *window,
gint width,
gint height)
{
GdkWindowObject *private;
gint x, y;
2000-05-31 21:50:38 +00:00
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
private = (GdkWindowObject*) window;
2000-05-31 21:50:38 +00:00
if (width < 1)
width = 1;
if (height < 1)
height = 1;
x = private->x;
y = private->y;
if (private->parent && (private->parent->window_type != GDK_WINDOW_CHILD))
{
GdkWindowChildHandlerData *data;
data = g_object_get_data (G_OBJECT (private->parent), "gdk-window-child-handler");
if (data)
(*data->get_pos) (window, &x, &y, data->user_data);
}
gdk_window_move_resize (window, x, y, width, height);
2000-05-31 21:50:38 +00:00
}
static void
recompute_abs_positions(GdkDrawable *drawable,
gint parent_x, gint parent_y,
2000-05-31 21:50:38 +00:00
gint parent_llim_x, gint parent_llim_y,
gint parent_lim_x, gint parent_lim_y)
{
GList *l;
if (GDK_IS_WINDOW (drawable))
2000-05-31 21:50:38 +00:00
{
GdkWindowObject *private = GDK_WINDOW_P (drawable);
int x, y;
2000-05-31 21:50:38 +00:00
if (!private->mapped)
2000-05-31 21:50:38 +00:00
return;
GDK_DRAWABLE_IMPL_FBDATA (private)->abs_x = parent_x + private->x;
GDK_DRAWABLE_IMPL_FBDATA (private)->abs_y = parent_y + private->y;
x = MAX (parent_llim_x, GDK_DRAWABLE_IMPL_FBDATA (private)->abs_x);
x = MIN (x, parent_lim_x);
GDK_DRAWABLE_IMPL_FBDATA (private)->llim_x = x;
y = MAX (parent_llim_y, GDK_DRAWABLE_IMPL_FBDATA (private)->abs_y);
y = MIN (y, parent_lim_y);
GDK_DRAWABLE_IMPL_FBDATA (private)->llim_y = y;
x = MIN (parent_lim_x,
GDK_DRAWABLE_IMPL_FBDATA (private)->abs_x + GDK_DRAWABLE_IMPL_FBDATA (private)->width);
x = MAX (x, GDK_DRAWABLE_IMPL_FBDATA (private)->llim_x);
GDK_DRAWABLE_IMPL_FBDATA (private)->lim_x = x;
y = MIN (parent_lim_y,
GDK_DRAWABLE_IMPL_FBDATA (private)->abs_y + GDK_DRAWABLE_IMPL_FBDATA (private)->height);
y = MAX (y, GDK_DRAWABLE_IMPL_FBDATA (private)->llim_y);
GDK_DRAWABLE_IMPL_FBDATA (private)->lim_y = y;
g_assert (GDK_DRAWABLE_IMPL_FBDATA (private)->llim_x <= GDK_DRAWABLE_IMPL_FBDATA (private)->lim_x);
g_assert (GDK_DRAWABLE_IMPL_FBDATA (private)->llim_y <= GDK_DRAWABLE_IMPL_FBDATA (private)->lim_y);
for (l = private->children; l; l = l->next)
recompute_abs_positions (l->data,
GDK_DRAWABLE_IMPL_FBDATA (private)->abs_x,
GDK_DRAWABLE_IMPL_FBDATA (private)->abs_y,
GDK_DRAWABLE_IMPL_FBDATA (private)->llim_x,
GDK_DRAWABLE_IMPL_FBDATA (private)->llim_y,
GDK_DRAWABLE_IMPL_FBDATA (private)->lim_x,
GDK_DRAWABLE_IMPL_FBDATA (private)->lim_y);
2000-05-31 21:50:38 +00:00
}
else
{
GDK_DRAWABLE_IMPL_FBDATA (drawable)->abs_x = 0;
GDK_DRAWABLE_IMPL_FBDATA (drawable)->abs_y = 0;
GDK_DRAWABLE_IMPL_FBDATA (drawable)->llim_x = 0;
GDK_DRAWABLE_IMPL_FBDATA (drawable)->llim_y = 0;
GDK_DRAWABLE_IMPL_FBDATA (drawable)->lim_x = GDK_DRAWABLE_IMPL_FBDATA (drawable)->width;
GDK_DRAWABLE_IMPL_FBDATA (drawable)->lim_y = GDK_DRAWABLE_IMPL_FBDATA (drawable)->height;
2000-05-31 21:50:38 +00:00
}
}
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.
2001-01-11 16:39:21 +00:00
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);
}
2000-05-31 21:50:38 +00:00
static void
recompute_drawable (GdkDrawable *drawable)
2000-05-31 21:50:38 +00:00
{
if (GDK_IS_WINDOW (drawable))
2000-05-31 21:50:38 +00:00
{
GdkWindowObject *private = GDK_WINDOW_P (drawable);
2000-05-31 21:50:38 +00:00
GdkWindow *parent;
parent = (GdkWindow *)private->parent;
if (!parent)
2000-05-31 21:50:38 +00:00
parent = gdk_parent_root;
recompute_abs_positions (drawable,
GDK_DRAWABLE_IMPL_FBDATA (parent)->abs_x,
GDK_DRAWABLE_IMPL_FBDATA (parent)->abs_y,
GDK_DRAWABLE_IMPL_FBDATA (parent)->llim_x,
GDK_DRAWABLE_IMPL_FBDATA (parent)->llim_y,
GDK_DRAWABLE_IMPL_FBDATA (parent)->lim_x,
GDK_DRAWABLE_IMPL_FBDATA (parent)->lim_y);
2000-05-31 21:50:38 +00:00
}
else
recompute_abs_positions (drawable, 0, 0, 0, 0, INT_MAX, INT_MAX);
2000-05-31 21:50:38 +00:00
}
void
gdk_fb_window_move_resize (GdkWindow *window,
gint x,
gint y,
gint width,
gint height,
gboolean send_expose_events)
2000-05-31 21:50:38 +00:00
{
GdkWindowObject *private;
gint dx, dy, dw, dh;
Huge GtkFB patch with lots of small bugfixes and initial selections implementation. 2000-11-23 Alexander Larsson <alexl@redhat.com> * gdk/linux-fb/gdkselection-fb.c: Initial selection implementation. * gtk/gtkselection.c: if GDK_WINDOWING_FB defined, include linux-fb/gdkfb.h and look up requestor in gtk_selection_request. * gdk/linux-fb/gdkfb.h, gdk/linux-fb/gdkglobals-fb.c: Added gdk_selection_property atom. * gdk/linux-fb/gdkprivate-fb.h: Export _gdk_selection_window_destroyed. Removed mask_off_x/y from GdkCursorPrivateFB. Removed hbearing, added top, left to PangoFBGlyphInfo. * gdk/linux-fb/gdkwindow-fb.c (_gdk_windowing_window_destroy): Call _gdk_selection_window_destroyed (_gdk_windowing_window_init): Don't call gdk_cursor_new() before the root window has been created. (static_dx_hack, static_dy_hack, compare_draw_rects, gdk_fb_window_move_resize): Remove unnecessary sort of rectangles in region. They are already sorted. Instead just traverse them in reverse if draw_direction < 0. * gdk/linux-fb/gdkinput-ps2.c (send_button_event): Double-clicks must be sent after the normal button_press. (gdk_fb_cursor_unhide): Remove usage of mask_off_x/y. Clean up. * gdk/linux-fb/gdkgeometry-fb.c (gdk_window_scroll): Pass _gdk_fb_screen_gc instead of NULL. * gdk/linux-fb/gdkmain-fb.c (_gdk_windowing_init_check): Initialize gdk_selection_property. (gdk_event_make): Remove unused code. * gdk/linux-fb/gdkcursor-fb.c: Make the pixmap for the cursor the same size as the mask. Also remove the mask_off_x/y fields in GdkCursorPrivateFB and combine _gdk_cursor_new_from_pixmap() and gdk_cursor_new_from_pixmap() Now the whole cursor is visible. * gdk/linux-fb/gdkdrawable-fb2.c (gdk_fb_draw_drawable_3): Fix bug where xdest+height instead of ydest+height was used to calculate if the source and dest overlapped. This fixes the redraw bug when the main window in testgtk was scrolled when partially covered by a tall window. Copy rectangles in region in order depending on draw_direction. Also moved the draw_direction flipping of start_y and end_y into the gc functions, as this might not be what all of them want. (gdk_fb_draw_lines): Support dashed lines. (gdk_fb_draw_glyphs): Clean up glyph placement. Also fix positioning so that the text is positioned correctly (was 1 pixel high). gdk/linux-fb/gdkgc-fb.c: Initialize cap_style to GTK_CAP_BUTT. This fixes a problem where all lines were drawn a pixel to short. Also checked the default of the rest of the values, and they're the same as X now. * gdk/linux-fb/gdkpango-fb.c (pango_fb_font_get_glyph_info): Clean up pixel positioning of the glyphs. Just use bgy->top and bgy->left. Also used PANGO_PIXEL where appropriate and added 0.5 to all divisions to get correct rounding behaviour. * gdk/linux-fb/gdkrender-fb.c (gdk_fb_draw_drawable_generic, gdk_fb_draw_drawable_memmove, gdk_fb_draw_drawable_aa_24): Moved start_y/end_y flip into draw_drawable implementations. Flip also x rendering when draw_direction < 0. Remove unneccesary multiply with draw_direction.
2000-11-25 15:44:35 +00:00
gint i, draw_dir;
GdkEvent *event;
GdkWindow *mousewin;
GdkRectangle root_rect;
GdkRectangle update_rect;
2000-05-31 21:50:38 +00:00
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
if (width < 1)
width = 1;
if (height < 1)
height = 1;
private = (GdkWindowObject*) window;
2000-05-31 21:50:38 +00:00
if (private->parent && (private->parent->window_type != GDK_WINDOW_CHILD))
{
GdkWindowChildHandlerData *data;
data = g_object_get_data (G_OBJECT (private->parent), "gdk-window-child-handler");
if (data && (*data->changed) (window, x, y, width, height, data->user_data))
return;
}
if (!private->destroyed)
2000-05-31 21:50:38 +00:00
{
2000-08-07 03:26:05 +00:00
GdkRegion *old_region = NULL;
if (private->input_only)
send_expose_events = FALSE;
if (private->mapped && send_expose_events)
old_region = gdk_fb_clip_region (GDK_DRAWABLE_IMPL(window), NULL, TRUE, FALSE, FALSE);
dx = x - private->x;
dy = y - private->y;
dw = width - GDK_DRAWABLE_IMPL_FBDATA (private)->width;
dh = height - GDK_DRAWABLE_IMPL_FBDATA (private)->height;
2000-05-31 21:50:38 +00:00
private->x = x;
private->y = y;
GDK_DRAWABLE_IMPL_FBDATA (private)->width = width;
GDK_DRAWABLE_IMPL_FBDATA (private)->height = height;
2000-05-31 21:50:38 +00:00
if (private->mapped)
2000-05-31 21:50:38 +00:00
{
recompute_drawable ((GdkDrawable *)window);
2000-05-31 21:50:38 +00:00
if (send_expose_events)
{
GdkRegion *new_region, *region;
gboolean handle_cursor = FALSE;
2000-05-31 21:50:38 +00:00
new_region = gdk_fb_clip_region (GDK_DRAWABLE_IMPL (window), NULL, TRUE, FALSE, TRUE);
2000-05-31 21:50:38 +00:00
region = gdk_region_copy (old_region);
gdk_region_offset (region, dx, dy);
gdk_region_intersect (region, new_region);
if (region->numRects && ((dx != 0) || (dy != 0)))
{
GdkFBDrawingContext fbdc;
if (gdk_fb_cursor_region_need_hide (old_region) ||
gdk_fb_cursor_region_need_hide (new_region))
{
gdk_fb_cursor_hide ();
handle_cursor = TRUE;
}
gdk_fb_drawing_context_init (&fbdc, GDK_DRAWABLE_IMPL (gdk_parent_root), NULL, FALSE, FALSE);
Huge GtkFB patch with lots of small bugfixes and initial selections implementation. 2000-11-23 Alexander Larsson <alexl@redhat.com> * gdk/linux-fb/gdkselection-fb.c: Initial selection implementation. * gtk/gtkselection.c: if GDK_WINDOWING_FB defined, include linux-fb/gdkfb.h and look up requestor in gtk_selection_request. * gdk/linux-fb/gdkfb.h, gdk/linux-fb/gdkglobals-fb.c: Added gdk_selection_property atom. * gdk/linux-fb/gdkprivate-fb.h: Export _gdk_selection_window_destroyed. Removed mask_off_x/y from GdkCursorPrivateFB. Removed hbearing, added top, left to PangoFBGlyphInfo. * gdk/linux-fb/gdkwindow-fb.c (_gdk_windowing_window_destroy): Call _gdk_selection_window_destroyed (_gdk_windowing_window_init): Don't call gdk_cursor_new() before the root window has been created. (static_dx_hack, static_dy_hack, compare_draw_rects, gdk_fb_window_move_resize): Remove unnecessary sort of rectangles in region. They are already sorted. Instead just traverse them in reverse if draw_direction < 0. * gdk/linux-fb/gdkinput-ps2.c (send_button_event): Double-clicks must be sent after the normal button_press. (gdk_fb_cursor_unhide): Remove usage of mask_off_x/y. Clean up. * gdk/linux-fb/gdkgeometry-fb.c (gdk_window_scroll): Pass _gdk_fb_screen_gc instead of NULL. * gdk/linux-fb/gdkmain-fb.c (_gdk_windowing_init_check): Initialize gdk_selection_property. (gdk_event_make): Remove unused code. * gdk/linux-fb/gdkcursor-fb.c: Make the pixmap for the cursor the same size as the mask. Also remove the mask_off_x/y fields in GdkCursorPrivateFB and combine _gdk_cursor_new_from_pixmap() and gdk_cursor_new_from_pixmap() Now the whole cursor is visible. * gdk/linux-fb/gdkdrawable-fb2.c (gdk_fb_draw_drawable_3): Fix bug where xdest+height instead of ydest+height was used to calculate if the source and dest overlapped. This fixes the redraw bug when the main window in testgtk was scrolled when partially covered by a tall window. Copy rectangles in region in order depending on draw_direction. Also moved the draw_direction flipping of start_y and end_y into the gc functions, as this might not be what all of them want. (gdk_fb_draw_lines): Support dashed lines. (gdk_fb_draw_glyphs): Clean up glyph placement. Also fix positioning so that the text is positioned correctly (was 1 pixel high). gdk/linux-fb/gdkgc-fb.c: Initialize cap_style to GTK_CAP_BUTT. This fixes a problem where all lines were drawn a pixel to short. Also checked the default of the rest of the values, and they're the same as X now. * gdk/linux-fb/gdkpango-fb.c (pango_fb_font_get_glyph_info): Clean up pixel positioning of the glyphs. Just use bgy->top and bgy->left. Also used PANGO_PIXEL where appropriate and added 0.5 to all divisions to get correct rounding behaviour. * gdk/linux-fb/gdkrender-fb.c (gdk_fb_draw_drawable_generic, gdk_fb_draw_drawable_memmove, gdk_fb_draw_drawable_aa_24): Moved start_y/end_y flip into draw_drawable implementations. Flip also x rendering when draw_direction < 0. Remove unneccesary multiply with draw_direction.
2000-11-25 15:44:35 +00:00
draw_dir = 1;
if ((dy>0) || ((dy==0) && (dx>0)))
draw_dir = -1;
for (i=(draw_dir>0)?0:region->numRects-1;i >= 0 && i < region->numRects; i+=draw_dir)
{
Huge GtkFB patch with lots of small bugfixes and initial selections implementation. 2000-11-23 Alexander Larsson <alexl@redhat.com> * gdk/linux-fb/gdkselection-fb.c: Initial selection implementation. * gtk/gtkselection.c: if GDK_WINDOWING_FB defined, include linux-fb/gdkfb.h and look up requestor in gtk_selection_request. * gdk/linux-fb/gdkfb.h, gdk/linux-fb/gdkglobals-fb.c: Added gdk_selection_property atom. * gdk/linux-fb/gdkprivate-fb.h: Export _gdk_selection_window_destroyed. Removed mask_off_x/y from GdkCursorPrivateFB. Removed hbearing, added top, left to PangoFBGlyphInfo. * gdk/linux-fb/gdkwindow-fb.c (_gdk_windowing_window_destroy): Call _gdk_selection_window_destroyed (_gdk_windowing_window_init): Don't call gdk_cursor_new() before the root window has been created. (static_dx_hack, static_dy_hack, compare_draw_rects, gdk_fb_window_move_resize): Remove unnecessary sort of rectangles in region. They are already sorted. Instead just traverse them in reverse if draw_direction < 0. * gdk/linux-fb/gdkinput-ps2.c (send_button_event): Double-clicks must be sent after the normal button_press. (gdk_fb_cursor_unhide): Remove usage of mask_off_x/y. Clean up. * gdk/linux-fb/gdkgeometry-fb.c (gdk_window_scroll): Pass _gdk_fb_screen_gc instead of NULL. * gdk/linux-fb/gdkmain-fb.c (_gdk_windowing_init_check): Initialize gdk_selection_property. (gdk_event_make): Remove unused code. * gdk/linux-fb/gdkcursor-fb.c: Make the pixmap for the cursor the same size as the mask. Also remove the mask_off_x/y fields in GdkCursorPrivateFB and combine _gdk_cursor_new_from_pixmap() and gdk_cursor_new_from_pixmap() Now the whole cursor is visible. * gdk/linux-fb/gdkdrawable-fb2.c (gdk_fb_draw_drawable_3): Fix bug where xdest+height instead of ydest+height was used to calculate if the source and dest overlapped. This fixes the redraw bug when the main window in testgtk was scrolled when partially covered by a tall window. Copy rectangles in region in order depending on draw_direction. Also moved the draw_direction flipping of start_y and end_y into the gc functions, as this might not be what all of them want. (gdk_fb_draw_lines): Support dashed lines. (gdk_fb_draw_glyphs): Clean up glyph placement. Also fix positioning so that the text is positioned correctly (was 1 pixel high). gdk/linux-fb/gdkgc-fb.c: Initialize cap_style to GTK_CAP_BUTT. This fixes a problem where all lines were drawn a pixel to short. Also checked the default of the rest of the values, and they're the same as X now. * gdk/linux-fb/gdkpango-fb.c (pango_fb_font_get_glyph_info): Clean up pixel positioning of the glyphs. Just use bgy->top and bgy->left. Also used PANGO_PIXEL where appropriate and added 0.5 to all divisions to get correct rounding behaviour. * gdk/linux-fb/gdkrender-fb.c (gdk_fb_draw_drawable_generic, gdk_fb_draw_drawable_memmove, gdk_fb_draw_drawable_aa_24): Moved start_y/end_y flip into draw_drawable implementations. Flip also x rendering when draw_direction < 0. Remove unneccesary multiply with draw_direction.
2000-11-25 15:44:35 +00:00
GdkRegionBox *reg = &region->rects[i];
gdk_fb_draw_drawable_3 (GDK_DRAWABLE_IMPL(gdk_parent_root),
_gdk_fb_screen_gc,
GDK_DRAWABLE_IMPL(gdk_parent_root),
&fbdc,
(reg->x1 - dx),
(reg->y1 - dy),
(reg->x1),
(reg->y1),
(reg->x2 - reg->x1),
(reg->y2 - reg->y1));
}
gdk_fb_drawing_context_finalize (&fbdc);
}
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.
2001-01-11 16:39:21 +00:00
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);
/* Clear the root window in new_region */
root_rect.x = 0;
root_rect.y = 0;
root_rect.width = gdk_screen_width();
root_rect.height = gdk_screen_height();
gdk_region_get_clipbox (new_region, &update_rect);
if (gdk_rectangle_intersect (&update_rect, &root_rect, &update_rect))
gdk_window_clear_area (gdk_parent_root,
update_rect.x,
update_rect.y,
update_rect.width,
update_rect.height);
/* Invalidate regions in new_region */
gdk_window_invalidate_region (gdk_parent_root, new_region, TRUE);
if (handle_cursor)
gdk_fb_cursor_unhide ();
gdk_region_destroy (old_region);
gdk_region_destroy (new_region);
}
/* Send GdkEventConfigure for toplevel windows */
if (private->window_type != GDK_WINDOW_CHILD)
{
event = gdk_event_make (window, GDK_CONFIGURE, TRUE);
if (event)
{
event->configure.x = private->x;
event->configure.y = private->y;
event->configure.width = GDK_DRAWABLE_IMPL_FBDATA (private)->width;
event->configure.height = GDK_DRAWABLE_IMPL_FBDATA (private)->height;
}
}
/* The window the pointer is in might have changed */
mousewin = gdk_window_at_pointer (NULL, NULL);
gdk_fb_window_send_crossing_events (mousewin,
GDK_CROSSING_NORMAL);
2000-05-31 21:50:38 +00:00
}
}
}
void
gdk_window_move_resize (GdkWindow *window,
gint x,
gint y,
gint width,
gint height)
{
gdk_fb_window_move_resize (window, x, y, width, height, TRUE);
}
2000-05-31 21:50:38 +00:00
void
gdk_window_reparent (GdkWindow *window,
GdkWindow *new_parent,
gint x,
gint y)
{
GdkWindowObject *window_private;
GdkWindowObject *parent_private;
GdkWindowObject *old_parent_private;
2000-05-31 21:50:38 +00:00
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
g_return_if_fail (new_parent != NULL);
g_return_if_fail (GDK_IS_WINDOW (new_parent));
if (!new_parent)
new_parent = gdk_parent_root;
window_private = (GdkWindowObject*) window;
old_parent_private = (GdkWindowObject*)window_private->parent;
parent_private = (GdkWindowObject*) new_parent;
2000-05-31 21:50:38 +00:00
g_assert(GDK_DRAWABLE_IMPL_FBDATA (window_private)->colormap);
2000-05-31 21:50:38 +00:00
window_private->parent = (GdkWindowObject *)new_parent;
2000-05-31 21:50:38 +00:00
if (old_parent_private)
old_parent_private->children = g_list_remove (old_parent_private->children, window);
parent_private->children = g_list_prepend (parent_private->children, window);
if (window_private->mapped)
{
GdkRectangle r;
GdkRegion *region;
r.x = GDK_DRAWABLE_IMPL_FBDATA (window)->llim_x;
r.y = GDK_DRAWABLE_IMPL_FBDATA (window)->llim_y;
r.width = GDK_DRAWABLE_IMPL_FBDATA (window)->lim_x - r.x;
r.height = GDK_DRAWABLE_IMPL_FBDATA (window)->lim_y - r.y;
region = gdk_region_rectangle (&r);
recompute_drawable ((GdkDrawable *)window);
r.x = GDK_DRAWABLE_IMPL_FBDATA (window)->llim_x;
r.y = GDK_DRAWABLE_IMPL_FBDATA (window)->llim_y;
r.width = GDK_DRAWABLE_IMPL_FBDATA (window)->lim_x - r.x;
r.height = GDK_DRAWABLE_IMPL_FBDATA (window)->lim_y - r.y;
gdk_region_union_with_rect (region, &r);
gdk_window_invalidate_region (gdk_parent_root, region, TRUE);
gdk_region_destroy (region);
}
2000-05-31 21:50:38 +00:00
}
void
_gdk_windowing_window_clear_area (GdkWindow *window,
gint x,
gint y,
gint width,
gint height)
{
GdkPixmap *bgpm;
GdkWindow *relto;
if (GDK_WINDOW_P (window)->input_only)
2000-05-31 21:50:38 +00:00
return;
bgpm = GDK_WINDOW_P (window)->bg_pixmap;
if (width == 0)
width = GDK_DRAWABLE_IMPL_FBDATA (window)->width - x;
if (height == 0)
height = GDK_DRAWABLE_IMPL_FBDATA (window)->height - y;
#if 0
for (relto = window; bgpm == GDK_PARENT_RELATIVE_BG && relto; relto = (GdkWindow *)GDK_WINDOW_P(relto)->parent)
bgpm = GDK_WINDOW_P (relto)->bg_pixmap;
#endif
2000-05-31 21:50:38 +00:00
if (bgpm && bgpm != GDK_NO_BG)
2000-05-31 21:50:38 +00:00
{
int curx, cury;
int xtrans, ytrans;
int xstep, ystep;
GdkFBDrawingContext fbdc;
2000-05-31 21:50:38 +00:00
return; /* Don't bother doing this - gtk+ will do it itself using GC tiles. If removing this line,
then also remove the #if 0 stuff */
2000-05-31 21:50:38 +00:00
gdk_fb_drawing_context_init (&fbdc, window, NULL, FALSE, TRUE);
xtrans = GDK_DRAWABLE_IMPL_FBDATA (relto)->abs_x - GDK_DRAWABLE_IMPL_FBDATA (window)->abs_x;
ytrans = GDK_DRAWABLE_IMPL_FBDATA (relto)->abs_y - GDK_DRAWABLE_IMPL_FBDATA (window)->abs_y;
2000-05-31 21:50:38 +00:00
for (cury = y - ytrans; cury < (y - ytrans + height); cury += ystep)
2000-05-31 21:50:38 +00:00
{
int drawh = cury % GDK_DRAWABLE_FBDATA (bgpm)->height;
ystep = GDK_DRAWABLE_FBDATA (bgpm)->height - drawh;
2000-05-31 21:50:38 +00:00
for(curx = x - xtrans; curx < (x - xtrans + width); curx += xstep)
{
int draww = curx % GDK_DRAWABLE_IMPL_FBDATA (bgpm)->width;
xstep = GDK_DRAWABLE_IMPL_FBDATA (bgpm)->width - draww;
gdk_fb_draw_drawable_3 (GDK_DRAWABLE_IMPL (window),
_gdk_fb_screen_gc,
GDK_DRAWABLE_IMPL (bgpm),
&fbdc,
draww, drawh,
curx + xtrans, cury + ytrans,
xstep, ystep);
2000-05-31 21:50:38 +00:00
}
}
gdk_fb_drawing_context_finalize (&fbdc);
2000-05-31 21:50:38 +00:00
}
else if (!bgpm)
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.
2001-01-11 16:39:21 +00:00
gdk_draw_rectangle (window, _gdk_fb_screen_gc, TRUE, x, y, width, height);
2000-05-31 21:50:38 +00:00
}
/* What's the diff? */
void
_gdk_windowing_window_clear_area_e (GdkWindow *window,
gint x,
gint y,
gint width,
gint height)
{
_gdk_windowing_window_clear_area (window, x, y, width, height);
2000-05-31 21:50:38 +00:00
}
static void
gdk_fb_window_raise (GdkWindow *window)
2000-05-31 21:50:38 +00:00
{
GdkWindowObject *parent;
parent = GDK_WINDOW_OBJECT (window)->parent;
parent->children = g_list_remove (parent->children, window);
parent->children = g_list_prepend (parent->children, window);
2000-05-31 21:50:38 +00:00
}
static void
gdk_fb_window_lower (GdkWindow *window)
2000-05-31 21:50:38 +00:00
{
GdkWindowObject *parent;
2000-05-31 21:50:38 +00:00
parent = GDK_WINDOW_OBJECT (window)->parent;
2000-05-31 21:50:38 +00:00
parent->children = g_list_remove (parent->children, window);
parent->children = g_list_append (parent->children, window);
2000-05-31 21:50:38 +00:00
}
2000-05-31 21:50:38 +00:00
void
gdk_window_raise (GdkWindow *window)
{
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
gdk_fb_window_raise (window);
if (GDK_WINDOW_OBJECT (window)->parent)
gdk_window_invalidate_rect (window, NULL, TRUE);
2000-05-31 21:50:38 +00:00
}
void
gdk_window_lower (GdkWindow *window)
{
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
gdk_fb_window_lower (window);
if (GDK_WINDOW_OBJECT (window)->parent)
gdk_window_invalidate_rect (window, NULL, TRUE);
2000-05-31 21:50:38 +00:00
}
void
gdk_window_set_hints (GdkWindow *window,
gint x,
gint y,
gint min_width,
gint min_height,
gint max_width,
gint max_height,
gint flags)
{
}
void
gdk_window_set_geometry_hints (GdkWindow *window,
GdkGeometry *geometry,
GdkWindowHints geom_mask)
{
}
void
gdk_window_set_title (GdkWindow *window,
const gchar *title)
{
}
void
gdk_window_set_role (GdkWindow *window,
const gchar *role)
{
}
void
gdk_window_set_transient_for (GdkWindow *window,
GdkWindow *parent)
{
GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
GdkWindowObject *root = GDK_WINDOW_OBJECT (gdk_parent_root);
int i;
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
g_return_if_fail (parent != NULL);
g_return_if_fail (GDK_IS_WINDOW (parent));
g_return_if_fail ((GdkWindow *)private->parent == gdk_parent_root);
g_return_if_fail ((GdkWindow *)GDK_WINDOW_OBJECT (parent)->parent == gdk_parent_root);
root->children = g_list_remove (root->children, window);
i = g_list_index (root->children, parent);
if (i<0)
root->children = g_list_prepend (root->children, window);
else
root->children = g_list_insert (root->children, window, i);
2000-05-31 21:50:38 +00:00
}
void
gdk_window_set_background (GdkWindow *window,
GdkColor *color)
{
GdkWindowObject *private = (GdkWindowObject *)window;
2000-05-31 21:50:38 +00:00
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
private->bg_color = *color;
if (private->bg_pixmap &&
private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
private->bg_pixmap != GDK_NO_BG)
{
gdk_pixmap_unref (private->bg_pixmap);
private->bg_pixmap = NULL;
}
}
void
gdk_window_set_back_pixmap (GdkWindow *window,
GdkPixmap *pixmap,
gboolean parent_relative)
{
GdkWindowObject *private = (GdkWindowObject *)window;
2000-05-31 21:50:38 +00:00
GdkPixmap *old_pixmap;
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
g_return_if_fail (pixmap == NULL || !parent_relative);
old_pixmap = private->bg_pixmap;
if (parent_relative)
{
private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
}
else
{
if (pixmap)
{
gdk_pixmap_ref (pixmap);
private->bg_pixmap = pixmap;
}
else
{
private->bg_pixmap = GDK_NO_BG;
}
}
if (old_pixmap &&
old_pixmap != GDK_PARENT_RELATIVE_BG &&
old_pixmap != GDK_NO_BG)
gdk_pixmap_unref (old_pixmap);
}
void
gdk_window_set_cursor (GdkWindow *window,
GdkCursor *cursor)
{
GdkCursor *old_cursor = GDK_WINDOW_IMPL_FBDATA(window)->cursor;
GdkRectangle window_reg;
2000-05-31 21:50:38 +00:00
GDK_WINDOW_IMPL_FBDATA (window)->cursor = cursor ? gdk_cursor_ref (cursor) : NULL;
2000-05-31 21:50:38 +00:00
if (old_cursor)
gdk_cursor_unref (old_cursor);
window_reg.x = GDK_DRAWABLE_IMPL_FBDATA (window)->llim_x;
window_reg.y = GDK_DRAWABLE_IMPL_FBDATA (window)->llim_y;
window_reg.width = GDK_DRAWABLE_IMPL_FBDATA (window)->lim_x - window_reg.x;
window_reg.height = GDK_DRAWABLE_IMPL_FBDATA (window)->lim_y - window_reg.y;
if (gdk_fb_cursor_need_hide (&window_reg))
gdk_fb_cursor_reset ();
2000-05-31 21:50:38 +00:00
}
void
gdk_window_get_geometry (GdkWindow *window,
gint *x,
gint *y,
gint *width,
gint *height,
gint *depth)
{
GdkWindowObject *private = (GdkWindowObject *)window;
2000-05-31 21:50:38 +00:00
g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
if (!window)
window = gdk_parent_root;
if (!private->destroyed)
2000-05-31 21:50:38 +00:00
{
if (x)
*x = private->x;
if (y)
*y = private->y;
if (width)
*width = GDK_DRAWABLE_IMPL_FBDATA (window)->width;
2000-05-31 21:50:38 +00:00
if (height)
*height = GDK_DRAWABLE_IMPL_FBDATA (window)->height;
2000-05-31 21:50:38 +00:00
if (depth)
*depth = gdk_display->modeinfo.bits_per_pixel;
}
}
gboolean
gdk_window_get_origin (GdkWindow *window,
gint *x,
gint *y)
{
g_return_val_if_fail (window != NULL, 0);
if (x)
*x = GDK_DRAWABLE_IMPL_FBDATA (window)->abs_x;
2000-05-31 21:50:38 +00:00
if (y)
*y = GDK_DRAWABLE_IMPL_FBDATA (window)->abs_y;
2000-05-31 21:50:38 +00:00
return TRUE;
}
gboolean
gdk_window_get_deskrelative_origin (GdkWindow *window,
gint *x,
gint *y)
{
gint tx = 0;
gint ty = 0;
gboolean return_val;
g_return_val_if_fail (window != NULL, 0);
if (!GDK_WINDOW_DESTROYED (window))
2000-05-31 21:50:38 +00:00
{
tx = GDK_DRAWABLE_IMPL_FBDATA (window)->abs_x;
ty = GDK_DRAWABLE_IMPL_FBDATA (window)->abs_y;
2000-05-31 21:50:38 +00:00
return_val = TRUE;
}
else
return_val = FALSE;
if (x)
*x = tx;
if (y)
*y = ty;
return return_val;
}
void
gdk_window_get_root_origin (GdkWindow *window,
gint *x,
gint *y)
{
gdk_window_get_deskrelative_origin (window, x, y);
2000-05-31 21:50:38 +00:00
}
static GdkRegion*
gdk_window_fb_get_visible_region (GdkDrawable *drawable)
{
GdkDrawableFBData *priv = GDK_DRAWABLE_FBDATA (drawable);
GdkRectangle result_rect;
GdkRectangle screen_rect;
result_rect.x = 0;
result_rect.y = 0;
result_rect.width = priv->width;
result_rect.height = priv->height;
screen_rect.x = -priv->abs_x;
screen_rect.y = -priv->abs_y;
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.
2001-01-11 16:39:21 +00:00
screen_rect.width = gdk_display->fb_width;
screen_rect.height = gdk_display->fb_width;
gdk_rectangle_intersect (&result_rect, &screen_rect, &result_rect);
return gdk_region_rectangle (&result_rect);
}
2000-05-31 21:50:38 +00:00
GdkWindow*
gdk_window_get_pointer (GdkWindow *window,
gint *x,
gint *y,
GdkModifierType *mask)
{
GdkWindow *return_val;
int winx = 0;
int winy = 0;
int x_int, y_int;
gint shape_dx, shape_dy;
2000-05-31 21:50:38 +00:00
GdkModifierType my_mask;
GdkRegion *shape;
2000-05-31 21:50:38 +00:00
g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
if (!window)
window = gdk_parent_root;
gdk_window_get_root_origin (window, &x_int, &y_int);
gdk_fb_mouse_get_info (&winx, &winy, &my_mask);
2000-05-31 21:50:38 +00:00
winx -= x_int;
winy -= y_int;
if (x)
*x = winx;
if (y)
*y = winy;
if (mask)
*mask = my_mask;
return_val = NULL;
shape = gdk_fb_window_peek_shape (window, &shape_dx, &shape_dy);
if ((winx >= 0) && (winx < GDK_DRAWABLE_IMPL_FBDATA (window)->width) &&
(winy >= 0) && (winy < GDK_DRAWABLE_IMPL_FBDATA (window)->height) &&
(!shape || gdk_region_point_in (shape, winx - shape_dx, winy - shape_dy)))
2000-05-31 21:50:38 +00:00
{
GdkWindowObject *private;
GdkWindowObject *sub;
2000-05-31 21:50:38 +00:00
int subx = winx, suby = winy;
for (private = sub = (GdkWindowObject *)window; sub; private = sub)
2000-05-31 21:50:38 +00:00
{
GList *ltmp;
for (ltmp = private->children; ltmp; ltmp = ltmp->next)
2000-05-31 21:50:38 +00:00
{
sub = ltmp->data;
if (!sub->mapped)
2000-05-31 21:50:38 +00:00
continue;
shape = gdk_fb_window_peek_shape (GDK_WINDOW (sub),
&shape_dx, &shape_dy);
if (subx >= sub->x &&
(subx < (GDK_DRAWABLE_IMPL_FBDATA (sub)->width + sub->x)) &&
(suby >= sub->y) &&
(suby < (GDK_DRAWABLE_IMPL_FBDATA (sub)->height + sub->y)) &&
(!shape || gdk_region_point_in (shape, subx - sub->x - shape_dx, suby - sub->y - shape_dy)))
2000-05-31 21:50:38 +00:00
{
subx -= sub->x;
suby -= sub->y;
break;
}
}
if (!ltmp)
2000-05-31 21:50:38 +00:00
{
sub = NULL;
break;
}
}
return_val = (GdkWindow *)private;
}
if (!return_val)
2000-05-31 21:50:38 +00:00
return_val = gdk_parent_root;
return return_val;
}
GdkWindow*
gdk_window_at_pointer (gint *win_x,
gint *win_y)
{
gint rx, ry;
GdkWindow *retval = gdk_window_get_pointer (NULL, win_x, win_y, NULL);
2000-05-31 21:50:38 +00:00
if (retval)
2000-05-31 21:50:38 +00:00
{
gdk_window_get_origin (retval, &ry, &rx);
if (win_x)
2000-05-31 21:50:38 +00:00
(*win_x) -= rx;
if (win_y)
2000-05-31 21:50:38 +00:00
(*win_y) -= ry;
}
return retval;
}
GdkEventMask
gdk_window_get_events (GdkWindow *window)
{
g_return_val_if_fail (window != NULL, 0);
g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
if (GDK_WINDOW_DESTROYED (window))
2000-05-31 21:50:38 +00:00
return 0;
else
return GDK_WINDOW_IMPL_FBDATA (window)->event_mask;
2000-05-31 21:50:38 +00:00
}
void
gdk_window_set_events (GdkWindow *window,
GdkEventMask event_mask)
{
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
if (!GDK_WINDOW_DESTROYED (window))
GDK_WINDOW_IMPL_FBDATA (window)->event_mask = event_mask;
2000-05-31 21:50:38 +00:00
}
void
gdk_window_add_colormap_windows (GdkWindow *window)
{
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
/* N/A */
}
GdkRegion*
gdk_fb_region_create_from_bitmap (GdkBitmap *bitmap)
{
GdkDrawableFBData *private;
GdkRegion *region;
GdkRectangle rect;
gboolean in_rect;
gint x;
guchar bit_mask;
guchar *src;
g_return_val_if_fail(bitmap != NULL, NULL);
g_return_val_if_fail(GDK_IS_PIXMAP(bitmap), NULL);
private = GDK_DRAWABLE_IMPL_FBDATA (bitmap);
g_return_val_if_fail(private->depth == 1, NULL);
region = gdk_region_new();
rect.height = 1;
in_rect = FALSE; /* Haven't started a rectangle yet */
for (rect.y = 0; rect.y < private->height; (rect.y)++)
{
src = private->mem + rect.y * private->rowstride;
bit_mask = 1;
for (x = 0; x < private->width; x++)
{
if ((*src & bit_mask) && !in_rect)
{
/* Start of rect */
in_rect = TRUE;
rect.x = x;
}
else if (!(*src & bit_mask) && in_rect)
{
/* End of rect */
in_rect = FALSE;
rect.width = x - rect.x;
gdk_region_union_with_rect (region, &rect);
}
if (bit_mask == 1<<7)
{
bit_mask = 1;
src++;
}
else
bit_mask <<= 1;
}
if (in_rect)
{
/* Past end of line */
in_rect = FALSE;
rect.width = x - rect.x;
gdk_region_union_with_rect (region, &rect);
}
}
return region;
}
GdkRegion *
gdk_fb_window_peek_shape (GdkDrawable *window, gint *dx, gint *dy)
{
gint x, y;
if (!GDK_IS_WINDOW (window))
return NULL;
if (GDK_WINDOW_IMPL_FBDATA (window)->shape == NULL)
return NULL;
x = y = 0;
while (GDK_WINDOW_IMPL_FBDATA (window)->shape == GDK_FB_USE_CHILD_SHAPE)
{
GList *children;
children = ((GdkWindowObject*)window)->children;
if (children)
{
window = (GdkDrawable *)children->data;
x += GDK_WINDOW_P(window)->x;
y += GDK_WINDOW_P(window)->y;
}
else
return NULL;
}
*dx = x;
*dy = y;
return GDK_WINDOW_IMPL_FBDATA (window)->shape;
}
GdkRegion *
gdk_fb_window_get_abs_shape (GdkDrawable *window)
{
GdkRegion *shape;
if (!GDK_IS_WINDOW (window))
return NULL;
if (GDK_WINDOW_IMPL_FBDATA (window)->shape == NULL)
return NULL;
if (GDK_WINDOW_IMPL_FBDATA (window)->shape == GDK_FB_USE_CHILD_SHAPE)
{
GList *children;
children = ((GdkWindowObject*)window)->children;
if (children)
return gdk_fb_window_get_abs_shape ((GdkDrawable *)children->data);
else
return NULL;
}
shape = gdk_region_copy (GDK_WINDOW_IMPL_FBDATA (window)->shape);
gdk_region_offset (shape,
GDK_DRAWABLE_IMPL_FBDATA (window)->abs_x,
GDK_DRAWABLE_IMPL_FBDATA (window)->abs_y);
return shape;
}
2000-05-31 21:50:38 +00:00
void
gdk_window_shape_combine_mask (GdkWindow *window,
GdkBitmap *mask,
gint x, gint y)
{
GdkWindowFBData *private;
2000-05-31 21:50:38 +00:00
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
private = GDK_WINDOW_IMPL_FBDATA (window);
if (private->shape && private->shape != GDK_FB_USE_CHILD_SHAPE)
gdk_region_destroy (private->shape);
/* Warning. HUGE hack */
if (mask == GDK_FB_USE_CHILD_SHAPE)
private->shape = GDK_FB_USE_CHILD_SHAPE;
else if (mask)
{
private->shape = gdk_fb_region_create_from_bitmap (mask);
gdk_region_offset (private->shape, x, y);
}
else
private->shape = NULL;
2000-05-31 21:50:38 +00:00
}
void
gdk_window_set_override_redirect (GdkWindow *window,
gboolean override_redirect)
{
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
/* N/A */
}
void
gdk_window_set_icon (GdkWindow *window,
GdkWindow *icon_window,
GdkPixmap *pixmap,
GdkBitmap *mask)
{
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
/* N/A */
}
void
gdk_window_set_icon_name (GdkWindow *window,
const gchar * name)
{
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
/* N/A */
}
void
gdk_window_set_group (GdkWindow *window,
GdkWindow *leader)
{
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
g_return_if_fail (leader != NULL);
g_return_if_fail (GDK_IS_WINDOW (leader));
/* N/A */
}
void
gdk_fb_window_set_child_handler (GdkWindow *window,
GdkWindowChildChanged changed,
GdkWindowChildGetPos get_pos,
gpointer user_data)
{
GdkWindowChildHandlerData *data;
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
data = g_new (GdkWindowChildHandlerData, 1);
data->changed = changed;
data->get_pos = get_pos;
data->user_data = user_data;
g_object_set_data_full (G_OBJECT (window), "gdk-window-child-handler",
data, (GDestroyNotify) g_free);
}
2000-05-31 21:50:38 +00:00
void
gdk_window_set_decorations (GdkWindow *window,
GdkWMDecoration decorations)
{
GdkWMDecoration *dec;
2000-05-31 21:50:38 +00:00
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
dec = g_new (GdkWMDecoration, 1);
*dec = decorations;
g_object_set_data_full (G_OBJECT (window), "gdk-window-decorations",
dec, (GDestroyNotify) g_free);
}
gboolean
gdk_window_get_decorations(GdkWindow *window,
GdkWMDecoration *decorations)
{
GdkWMDecoration *dec;
g_return_val_if_fail (window != NULL, FALSE);
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
dec = g_object_get_data (G_OBJECT (window), "gdk-window-decorations");
if (dec)
{
*decorations = *dec;
return TRUE;
}
return FALSE;
2000-05-31 21:50:38 +00:00
}
void
gdk_window_set_functions (GdkWindow *window,
GdkWMFunction functions)
{
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
/* N/A */
}
void
gdk_window_set_child_shapes (GdkWindow *window)
{
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
}
void
gdk_window_merge_child_shapes (GdkWindow *window)
{
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
}
/*************************************************************
* gdk_window_set_static_gravities:
* Set the bit gravity of the given window to static,
* and flag it so all children get static subwindow
* gravity.
* arguments:
* window: window for which to set static gravity
* use_static: Whether to turn static gravity on or off.
* results:
* Does the XServer support static gravity?
*************************************************************/
gboolean
gdk_window_set_static_gravities (GdkWindow *window,
gboolean use_static)
{
g_return_val_if_fail (window != NULL, FALSE);
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
return TRUE;
}
void
_gdk_windowing_window_get_offsets (GdkWindow *window,
gint *x_offset,
gint *y_offset)
{
*x_offset = *y_offset = 0;
}
gboolean
_gdk_windowing_window_queue_antiexpose (GdkWindow *window,
GdkRegion *area)
{
return FALSE;
}