mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 08:00:42 -05:00
move xcompmgr code in here (minus drop shadows), untested since Keith's
2003-11-23 Havoc Pennington <hp@redhat.com> * src/compositor.c: move xcompmgr code in here (minus drop shadows), untested since Keith's server just crashes at the moment. "It compiles"
This commit is contained in:
parent
d538690bd4
commit
927a6def1b
@ -1,3 +1,9 @@
|
|||||||
|
2003-11-23 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* src/compositor.c: move xcompmgr code in here (minus drop
|
||||||
|
shadows), untested since Keith's server just crashes at the
|
||||||
|
moment. "It compiles"
|
||||||
|
|
||||||
2003-11-20 Havoc Pennington <hp@redhat.com>
|
2003-11-20 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
* src/window.c (meta_window_new_with_attrs): new function
|
* src/window.c (meta_window_new_with_attrs): new function
|
||||||
|
554
src/compositor.c
554
src/compositor.c
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2003 Red Hat, Inc.
|
* Copyright (C) 2003 Red Hat, Inc.
|
||||||
|
* Copyright (C) 2003 Keith Packard
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License as
|
* modify it under the terms of the GNU General Public License as
|
||||||
@ -21,13 +22,14 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include "compositor.h"
|
#include "compositor.h"
|
||||||
|
#include "screen.h"
|
||||||
|
#include "errors.h"
|
||||||
|
|
||||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
#include <X11/extensions/Xcomposite.h>
|
#include <X11/extensions/Xcomposite.h>
|
||||||
#include <X11/extensions/Xdamage.h>
|
#include <X11/extensions/Xdamage.h>
|
||||||
#include <X11/extensions/Xrender.h>
|
#include <X11/extensions/Xrender.h>
|
||||||
|
|
||||||
|
|
||||||
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||||
|
|
||||||
/* Unlike MetaWindow, there's one of these for _all_ toplevel windows,
|
/* Unlike MetaWindow, there's one of these for _all_ toplevel windows,
|
||||||
@ -41,16 +43,29 @@ typedef struct
|
|||||||
{
|
{
|
||||||
Window xwindow;
|
Window xwindow;
|
||||||
|
|
||||||
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
|
MetaCompositor *compositor;
|
||||||
|
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int border_width;
|
||||||
|
|
||||||
|
Damage damage;
|
||||||
|
XserverRegion last_painted_extents;
|
||||||
|
|
||||||
|
Picture picture;
|
||||||
|
XserverRegion border_size;
|
||||||
|
|
||||||
|
unsigned int managed : 1;
|
||||||
|
unsigned int damaged : 1;
|
||||||
|
|
||||||
|
unsigned int screen_index : 8;
|
||||||
|
|
||||||
|
#endif
|
||||||
} MetaCompositorWindow;
|
} MetaCompositorWindow;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GList *windows;
|
|
||||||
|
|
||||||
} MetaCompositorScreen;
|
|
||||||
|
|
||||||
struct MetaCompositor
|
struct MetaCompositor
|
||||||
{
|
{
|
||||||
MetaDisplay *display;
|
MetaDisplay *display;
|
||||||
@ -64,11 +79,34 @@ struct MetaCompositor
|
|||||||
int render_error_base;
|
int render_error_base;
|
||||||
int render_event_base;
|
int render_event_base;
|
||||||
|
|
||||||
GSList *screens;
|
GHashTable *window_hash;
|
||||||
|
|
||||||
|
guint repair_idle;
|
||||||
|
|
||||||
guint enabled : 1;
|
guint enabled : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
|
static void
|
||||||
|
meta_compositor_window_free (MetaCompositorWindow *cwindow)
|
||||||
|
{
|
||||||
|
XDamageDestroy (cwindow->compositor->display->xdisplay,
|
||||||
|
cwindow->damage);
|
||||||
|
|
||||||
|
g_free (cwindow);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||||
|
|
||||||
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
|
static void
|
||||||
|
free_window_hash_value (void *v)
|
||||||
|
{
|
||||||
|
MetaCompositorWindow *cwindow = v;
|
||||||
|
|
||||||
|
meta_compositor_window_free (cwindow);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||||
|
|
||||||
MetaCompositor*
|
MetaCompositor*
|
||||||
meta_compositor_new (MetaDisplay *display)
|
meta_compositor_new (MetaDisplay *display)
|
||||||
{
|
{
|
||||||
@ -137,6 +175,11 @@ meta_compositor_new (MetaDisplay *display)
|
|||||||
return compositor;
|
return compositor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compositor->window_hash = g_hash_table_new_full (meta_unsigned_long_hash,
|
||||||
|
meta_unsigned_long_equal,
|
||||||
|
NULL,
|
||||||
|
free_window_hash_value);
|
||||||
|
|
||||||
compositor->enabled = TRUE;
|
compositor->enabled = TRUE;
|
||||||
|
|
||||||
return compositor;
|
return compositor;
|
||||||
@ -145,6 +188,18 @@ meta_compositor_new (MetaDisplay *display)
|
|||||||
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
|
static void
|
||||||
|
remove_repair_idle (MetaCompositor *compositor)
|
||||||
|
{
|
||||||
|
if (compositor->repair_idle != 0)
|
||||||
|
{
|
||||||
|
g_source_remove (compositor->repair_idle);
|
||||||
|
compositor->repair_idle = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_compositor_unref (MetaCompositor *compositor)
|
meta_compositor_unref (MetaCompositor *compositor)
|
||||||
{
|
{
|
||||||
@ -152,27 +207,385 @@ meta_compositor_unref (MetaCompositor *compositor)
|
|||||||
/* There isn't really a refcount at the moment since
|
/* There isn't really a refcount at the moment since
|
||||||
* there's no ref()
|
* there's no ref()
|
||||||
*/
|
*/
|
||||||
|
remove_repair_idle (compositor);
|
||||||
|
|
||||||
|
g_hash_table_destroy (compositor->window_hash);
|
||||||
|
|
||||||
g_free (compositor);
|
g_free (compositor);
|
||||||
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
|
static XserverRegion
|
||||||
|
window_extents (MetaCompositorWindow *cwindow)
|
||||||
|
{
|
||||||
|
XRectangle r;
|
||||||
|
|
||||||
|
r.x = cwindow->x;
|
||||||
|
r.y = cwindow->y;
|
||||||
|
r.width = cwindow->width;
|
||||||
|
r.height = cwindow->height;
|
||||||
|
|
||||||
|
return XFixesCreateRegion (cwindow->compositor->display->xdisplay, &r, 1);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||||
|
|
||||||
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
|
static void
|
||||||
|
paint_screen (MetaCompositor *compositor,
|
||||||
|
MetaScreen *screen,
|
||||||
|
XserverRegion damage_region)
|
||||||
|
{
|
||||||
|
XserverRegion region;
|
||||||
|
Picture buffer_picture;
|
||||||
|
Pixmap buffer_pixmap;
|
||||||
|
Display *xdisplay;
|
||||||
|
XRenderPictFormat *format;
|
||||||
|
GList *tmp;
|
||||||
|
|
||||||
|
xdisplay = screen->display->xdisplay;
|
||||||
|
|
||||||
|
if (damage_region == None)
|
||||||
|
{
|
||||||
|
XRectangle r;
|
||||||
|
|
||||||
|
r.x = 0;
|
||||||
|
r.y = 0;
|
||||||
|
r.width = screen->width;
|
||||||
|
r.height = screen->height;
|
||||||
|
|
||||||
|
region = XFixesCreateRegion (xdisplay, &r, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
region = XFixesCreateRegion (xdisplay, NULL, 0);
|
||||||
|
|
||||||
|
XFixesCopyRegion (compositor->display->xdisplay,
|
||||||
|
region,
|
||||||
|
damage_region);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer_pixmap = XCreatePixmap (xdisplay, None,
|
||||||
|
screen->width,
|
||||||
|
screen->height,
|
||||||
|
DefaultDepth (xdisplay,
|
||||||
|
screen->number));
|
||||||
|
|
||||||
|
format = XRenderFindVisualFormat (xdisplay,
|
||||||
|
DefaultVisual (xdisplay,
|
||||||
|
screen->number));
|
||||||
|
|
||||||
|
buffer_picture = XRenderCreatePicture (xdisplay,
|
||||||
|
buffer_pixmap,
|
||||||
|
format,
|
||||||
|
0, 0);
|
||||||
|
|
||||||
|
/* set clip on the root window */
|
||||||
|
XFixesSetPictureClipRegion (xdisplay,
|
||||||
|
screen->root_picture, 0, 0, region);
|
||||||
|
|
||||||
|
/* draw windows from bottom to top */
|
||||||
|
meta_error_trap_push (compositor->display);
|
||||||
|
tmp = g_list_last (screen->compositor_windows);
|
||||||
|
while (tmp != NULL)
|
||||||
|
{
|
||||||
|
MetaCompositorWindow *cwindow = tmp->data;
|
||||||
|
|
||||||
|
if (cwindow->picture == None) /* InputOnly */
|
||||||
|
goto next;
|
||||||
|
|
||||||
|
if (cwindow->last_painted_extents)
|
||||||
|
XFixesDestroyRegion (xdisplay,
|
||||||
|
cwindow->last_painted_extents);
|
||||||
|
|
||||||
|
cwindow->last_painted_extents = window_extents (cwindow);
|
||||||
|
|
||||||
|
XFixesSetPictureClipRegion (xdisplay,
|
||||||
|
buffer_picture, 0, 0,
|
||||||
|
region);
|
||||||
|
|
||||||
|
/* XFixesSubtractRegion (dpy, region, region, 0, 0, w->borderSize, 0, 0); */
|
||||||
|
|
||||||
|
XRenderComposite (xdisplay,
|
||||||
|
PictOpSrc, /* PictOpOver for alpha */
|
||||||
|
cwindow->picture,
|
||||||
|
None, buffer_picture,
|
||||||
|
0, 0, 0, 0,
|
||||||
|
cwindow->x + cwindow->border_width,
|
||||||
|
cwindow->y + cwindow->border_width,
|
||||||
|
cwindow->width,
|
||||||
|
cwindow->height);
|
||||||
|
|
||||||
|
next:
|
||||||
|
tmp = tmp->prev;
|
||||||
|
}
|
||||||
|
meta_error_trap_pop (compositor->display, FALSE);
|
||||||
|
|
||||||
|
/* Copy buffer to root window */
|
||||||
|
|
||||||
|
XFixesSetPictureClipRegion (xdisplay, buffer_picture, 0, 0, None);
|
||||||
|
XRenderComposite (xdisplay, PictOpSrc, buffer_picture, None,
|
||||||
|
screen->root_picture,
|
||||||
|
0, 0, 0, 0, 0, 0,
|
||||||
|
screen->width, screen->height);
|
||||||
|
|
||||||
|
XFixesDestroyRegion (xdisplay, region);
|
||||||
|
XFreePixmap (xdisplay, buffer_pixmap);
|
||||||
|
XRenderFreePicture (xdisplay, buffer_picture);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||||
|
|
||||||
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
|
static gboolean
|
||||||
|
repair_idle_func (void *data)
|
||||||
|
{
|
||||||
|
GSList *tmp;
|
||||||
|
|
||||||
|
MetaCompositor *compositor = data;
|
||||||
|
|
||||||
|
tmp = compositor->display->screens;
|
||||||
|
while (tmp != NULL)
|
||||||
|
{
|
||||||
|
MetaScreen *s = tmp->data;
|
||||||
|
|
||||||
|
if (s->damage_region != None)
|
||||||
|
{
|
||||||
|
paint_screen (compositor, s,
|
||||||
|
s->damage_region);
|
||||||
|
XFixesDestroyRegion (s->display->xdisplay,
|
||||||
|
s->damage_region);
|
||||||
|
s->damage_region = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
compositor->repair_idle = 0;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||||
|
|
||||||
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
|
static MetaScreen*
|
||||||
|
meta_compositor_window_get_screen (MetaCompositorWindow *cwindow)
|
||||||
|
{
|
||||||
|
MetaScreen *screen;
|
||||||
|
GSList *tmp;
|
||||||
|
|
||||||
|
screen = NULL;
|
||||||
|
tmp = cwindow->compositor->display->screens;
|
||||||
|
while (tmp != NULL)
|
||||||
|
{
|
||||||
|
MetaScreen *s = tmp->data;
|
||||||
|
|
||||||
|
if (s->number == cwindow->screen_index)
|
||||||
|
{
|
||||||
|
screen = s;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
g_assert (screen != NULL);
|
||||||
|
|
||||||
|
return screen;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||||
|
|
||||||
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
|
static void
|
||||||
|
ensure_repair_idle (MetaCompositor *compositor)
|
||||||
|
{
|
||||||
|
if (compositor->repair_idle != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
compositor->repair_idle = g_idle_add (repair_idle_func, compositor);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||||
|
|
||||||
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
|
static void
|
||||||
|
merge_and_destroy_damage_region (MetaCompositor *compositor,
|
||||||
|
MetaScreen *screen,
|
||||||
|
XserverRegion region)
|
||||||
|
{
|
||||||
|
if (screen->damage_region != None)
|
||||||
|
{
|
||||||
|
XFixesCopyRegion (compositor->display->xdisplay,
|
||||||
|
screen->damage_region,
|
||||||
|
region);
|
||||||
|
XFixesDestroyRegion (compositor->display->xdisplay,
|
||||||
|
region);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
screen->damage_region = region;
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_repair_idle (compositor);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||||
|
|
||||||
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
|
static void
|
||||||
|
merge_damage_region (MetaCompositor *compositor,
|
||||||
|
MetaScreen *screen,
|
||||||
|
XserverRegion region)
|
||||||
|
{
|
||||||
|
if (screen->damage_region == None)
|
||||||
|
screen->damage_region =
|
||||||
|
XFixesCreateRegion (compositor->display->xdisplay, NULL, 0);
|
||||||
|
|
||||||
|
XFixesCopyRegion (compositor->display->xdisplay,
|
||||||
|
screen->damage_region,
|
||||||
|
region);
|
||||||
|
|
||||||
|
ensure_repair_idle (compositor);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||||
|
|
||||||
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
|
static void
|
||||||
|
process_damage_notify (MetaCompositor *compositor,
|
||||||
|
XDamageNotifyEvent *event)
|
||||||
|
{
|
||||||
|
MetaCompositorWindow *cwindow;
|
||||||
|
XserverRegion region;
|
||||||
|
MetaScreen *screen;
|
||||||
|
|
||||||
|
cwindow = g_hash_table_lookup (compositor->window_hash,
|
||||||
|
&event->drawable);
|
||||||
|
if (cwindow == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
region = XFixesCreateRegion (compositor->display->xdisplay, NULL, 0);
|
||||||
|
|
||||||
|
/* translate region to screen */
|
||||||
|
XDamageSubtract (compositor->display->xdisplay,
|
||||||
|
cwindow->damage, None, region);
|
||||||
|
|
||||||
|
XFixesTranslateRegion (compositor->display->xdisplay,
|
||||||
|
region,
|
||||||
|
cwindow->x,
|
||||||
|
cwindow->y);
|
||||||
|
|
||||||
|
screen = meta_compositor_window_get_screen (cwindow);
|
||||||
|
|
||||||
|
merge_and_destroy_damage_region (compositor, screen, region);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||||
|
|
||||||
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
|
static void
|
||||||
|
process_configure_notify (MetaCompositor *compositor,
|
||||||
|
XConfigureEvent *event)
|
||||||
|
{
|
||||||
|
MetaCompositorWindow *cwindow;
|
||||||
|
MetaScreen *screen;
|
||||||
|
GList *link;
|
||||||
|
Window above;
|
||||||
|
XserverRegion region;
|
||||||
|
|
||||||
|
cwindow = g_hash_table_lookup (compositor->window_hash,
|
||||||
|
&event->window);
|
||||||
|
if (cwindow == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
screen = meta_compositor_window_get_screen (cwindow);
|
||||||
|
|
||||||
|
if (cwindow->last_painted_extents)
|
||||||
|
{
|
||||||
|
merge_damage_region (compositor,
|
||||||
|
screen,
|
||||||
|
cwindow->last_painted_extents);
|
||||||
|
}
|
||||||
|
|
||||||
|
cwindow->x = event->x;
|
||||||
|
cwindow->y = event->y;
|
||||||
|
cwindow->width = event->width;
|
||||||
|
cwindow->height = event->height;
|
||||||
|
cwindow->border_width = event->border_width;
|
||||||
|
|
||||||
|
link = g_list_find (screen->compositor_windows,
|
||||||
|
cwindow);
|
||||||
|
|
||||||
|
g_assert (link != NULL);
|
||||||
|
|
||||||
|
if (link->next)
|
||||||
|
above = ((MetaCompositorWindow*) link->next)->xwindow;
|
||||||
|
else
|
||||||
|
above = None;
|
||||||
|
|
||||||
|
if (above != event->above)
|
||||||
|
{
|
||||||
|
GList *tmp;
|
||||||
|
|
||||||
|
screen->compositor_windows =
|
||||||
|
g_list_delete_link (screen->compositor_windows,
|
||||||
|
link);
|
||||||
|
link = NULL;
|
||||||
|
|
||||||
|
/* Note that event->above is None if our window is on the bottom */
|
||||||
|
tmp = screen->compositor_windows;
|
||||||
|
while (tmp != NULL)
|
||||||
|
{
|
||||||
|
MetaCompositorWindow *t = tmp->data;
|
||||||
|
|
||||||
|
if (t->xwindow == event->above)
|
||||||
|
{
|
||||||
|
/* We are above this window, i.e. earlier in list */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmp != NULL)
|
||||||
|
{
|
||||||
|
screen->compositor_windows =
|
||||||
|
g_list_insert_before (screen->compositor_windows,
|
||||||
|
tmp,
|
||||||
|
cwindow);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
screen->compositor_windows =
|
||||||
|
g_list_prepend (screen->compositor_windows,
|
||||||
|
cwindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
region = window_extents (cwindow);
|
||||||
|
merge_damage_region (compositor,
|
||||||
|
screen,
|
||||||
|
region);
|
||||||
|
XFixesDestroyRegion (compositor->display->xdisplay, region);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_compositor_process_event (MetaCompositor *compositor,
|
meta_compositor_process_event (MetaCompositor *compositor,
|
||||||
XEvent *xevent,
|
XEvent *event,
|
||||||
MetaWindow *window)
|
MetaWindow *window)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
if (!compositor->enabled)
|
if (!compositor->enabled)
|
||||||
return; /* no extension */
|
return; /* no extension */
|
||||||
|
|
||||||
|
if (event->type == (compositor->damage_event_base + XDamageNotify))
|
||||||
|
{
|
||||||
|
process_damage_notify (compositor,
|
||||||
|
(XDamageNotifyEvent*) event);
|
||||||
|
}
|
||||||
|
else if (event->type == ConfigureNotify)
|
||||||
|
{
|
||||||
|
process_configure_notify (compositor,
|
||||||
|
(XConfigureEvent*) event);
|
||||||
|
}
|
||||||
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is called when metacity does its XQueryTree() on startup
|
/* This is called when metacity does its XQueryTree() on startup
|
||||||
* and when a new window is created.
|
* and when a new window is mapped.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
meta_compositor_add_window (MetaCompositor *compositor,
|
meta_compositor_add_window (MetaCompositor *compositor,
|
||||||
@ -180,11 +593,71 @@ meta_compositor_add_window (MetaCompositor *compositor,
|
|||||||
XWindowAttributes *attrs)
|
XWindowAttributes *attrs)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
|
MetaCompositorWindow *cwindow;
|
||||||
|
MetaScreen *screen;
|
||||||
|
Damage damage;
|
||||||
|
XRenderPictFormat *format;
|
||||||
|
XRenderPictureAttributes pa;
|
||||||
|
|
||||||
g_print ("compositor adding window 0x%lx\n", xwindow);
|
g_print ("compositor adding window 0x%lx\n", xwindow);
|
||||||
|
|
||||||
if (!compositor->enabled)
|
if (!compositor->enabled)
|
||||||
return; /* no extension */
|
return; /* no extension */
|
||||||
|
|
||||||
|
screen = meta_screen_for_x_screen (attrs->screen);
|
||||||
|
g_assert (screen != NULL);
|
||||||
|
|
||||||
|
cwindow = g_hash_table_lookup (compositor->window_hash,
|
||||||
|
&xwindow);
|
||||||
|
|
||||||
|
if (cwindow != NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Create Damage object to monitor window damage */
|
||||||
|
meta_error_trap_push (compositor->display);
|
||||||
|
damage = XDamageCreate (compositor->display->xdisplay,
|
||||||
|
xwindow, XDamageReportNonEmpty);
|
||||||
|
meta_error_trap_pop (compositor->display, FALSE);
|
||||||
|
|
||||||
|
if (damage == None)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cwindow = g_new0 (MetaCompositorWindow, 1);
|
||||||
|
|
||||||
|
cwindow->compositor = compositor;
|
||||||
|
cwindow->xwindow = xwindow;
|
||||||
|
cwindow->screen_index = screen->number;
|
||||||
|
cwindow->damage = damage;
|
||||||
|
cwindow->x = attrs->x;
|
||||||
|
cwindow->y = attrs->y;
|
||||||
|
cwindow->width = attrs->width;
|
||||||
|
cwindow->height = attrs->height;
|
||||||
|
cwindow->border_width = attrs->border_width;
|
||||||
|
|
||||||
|
pa.subwindow_mode = IncludeInferiors;
|
||||||
|
|
||||||
|
if (attrs->class != InputOnly)
|
||||||
|
{
|
||||||
|
format = XRenderFindVisualFormat (compositor->display->xdisplay,
|
||||||
|
attrs->visual);
|
||||||
|
cwindow->picture = XRenderCreatePicture (compositor->display->xdisplay,
|
||||||
|
xwindow,
|
||||||
|
format,
|
||||||
|
CPSubwindowMode,
|
||||||
|
&pa);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cwindow->picture = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_hash_table_insert (compositor->window_hash,
|
||||||
|
&cwindow->xwindow, cwindow);
|
||||||
|
|
||||||
|
/* assume cwindow is at the top of the stack */
|
||||||
|
screen->compositor_windows = g_list_prepend (screen->compositor_windows,
|
||||||
|
cwindow);
|
||||||
|
|
||||||
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,11 +666,37 @@ meta_compositor_remove_window (MetaCompositor *compositor,
|
|||||||
Window xwindow)
|
Window xwindow)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
|
MetaCompositorWindow *cwindow;
|
||||||
|
MetaScreen *screen;
|
||||||
|
|
||||||
g_print ("compositor removing window 0x%lx\n", xwindow);
|
g_print ("compositor removing window 0x%lx\n", xwindow);
|
||||||
|
|
||||||
if (!compositor->enabled)
|
if (!compositor->enabled)
|
||||||
return; /* no extension */
|
return; /* no extension */
|
||||||
|
|
||||||
|
cwindow = g_hash_table_lookup (compositor->window_hash,
|
||||||
|
&xwindow);
|
||||||
|
|
||||||
|
if (cwindow == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
screen = meta_compositor_window_get_screen (cwindow);
|
||||||
|
|
||||||
|
if (cwindow->last_painted_extents)
|
||||||
|
{
|
||||||
|
merge_and_destroy_damage_region (compositor,
|
||||||
|
screen,
|
||||||
|
cwindow->last_painted_extents);
|
||||||
|
cwindow->last_painted_extents = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
screen->compositor_windows = g_list_remove (screen->compositor_windows,
|
||||||
|
cwindow);
|
||||||
|
|
||||||
|
/* Frees cwindow as side effect */
|
||||||
|
g_hash_table_remove (compositor->window_hash,
|
||||||
|
&xwindow);
|
||||||
|
|
||||||
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,9 +705,30 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
|
|||||||
MetaScreen *screen)
|
MetaScreen *screen)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||||
|
XRenderPictureAttributes pa;
|
||||||
|
|
||||||
if (!compositor->enabled)
|
if (!compositor->enabled)
|
||||||
return; /* no extension */
|
return; /* no extension */
|
||||||
|
|
||||||
|
/* FIXME we need to handle root window resize by recreating the
|
||||||
|
* root_picture
|
||||||
|
*/
|
||||||
|
|
||||||
|
g_assert (screen->root_picture == None);
|
||||||
|
|
||||||
|
pa.subwindow_mode = IncludeInferiors;
|
||||||
|
|
||||||
|
screen->root_picture =
|
||||||
|
XRenderCreatePicture (compositor->display->xdisplay,
|
||||||
|
screen->xroot,
|
||||||
|
XRenderFindVisualFormat (compositor->display->xdisplay,
|
||||||
|
DefaultVisual (compositor->display->xdisplay,
|
||||||
|
screen->number)),
|
||||||
|
CPSubwindowMode,
|
||||||
|
&pa);
|
||||||
|
|
||||||
|
g_assert (screen->root_picture != None);
|
||||||
|
|
||||||
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,6 +740,16 @@ meta_compositor_unmanage_screen (MetaCompositor *compositor,
|
|||||||
if (!compositor->enabled)
|
if (!compositor->enabled)
|
||||||
return; /* no extension */
|
return; /* no extension */
|
||||||
|
|
||||||
|
XRenderFreePicture (screen->display->xdisplay,
|
||||||
|
screen->root_picture);
|
||||||
|
screen->root_picture = None;
|
||||||
|
|
||||||
|
while (screen->compositor_windows != NULL)
|
||||||
|
{
|
||||||
|
MetaCompositorWindow *cwindow = screen->compositor_windows->data;
|
||||||
|
|
||||||
|
meta_compositor_remove_window (compositor, cwindow->xwindow);
|
||||||
|
}
|
||||||
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1299,6 +1299,10 @@ event_callback (XEvent *event,
|
|||||||
}
|
}
|
||||||
#endif /* HAVE_SHAPE */
|
#endif /* HAVE_SHAPE */
|
||||||
|
|
||||||
|
meta_compositor_process_event (display->compositor,
|
||||||
|
event,
|
||||||
|
window);
|
||||||
|
|
||||||
switch (event->type)
|
switch (event->type)
|
||||||
{
|
{
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
@ -1636,6 +1640,9 @@ event_callback (XEvent *event,
|
|||||||
case CreateNotify:
|
case CreateNotify:
|
||||||
break;
|
break;
|
||||||
case DestroyNotify:
|
case DestroyNotify:
|
||||||
|
meta_compositor_remove_window (display->compositor,
|
||||||
|
modified);
|
||||||
|
|
||||||
if (window)
|
if (window)
|
||||||
{
|
{
|
||||||
if (display->grab_op != META_GRAB_OP_NONE &&
|
if (display->grab_op != META_GRAB_OP_NONE &&
|
||||||
|
@ -559,6 +559,9 @@ meta_screen_new (MetaDisplay *display,
|
|||||||
|
|
||||||
screen->showing_desktop = FALSE;
|
screen->showing_desktop = FALSE;
|
||||||
|
|
||||||
|
screen->compositor_windows = NULL;
|
||||||
|
screen->damage_region = None;
|
||||||
|
|
||||||
{
|
{
|
||||||
XGCValues gc_values;
|
XGCValues gc_values;
|
||||||
|
|
||||||
|
@ -113,6 +113,11 @@ struct _MetaScreen
|
|||||||
|
|
||||||
/* gc for XOR on root window */
|
/* gc for XOR on root window */
|
||||||
GC root_xor_gc;
|
GC root_xor_gc;
|
||||||
|
|
||||||
|
/* Managed by compositor.c; top of stack is first in list */
|
||||||
|
GList *compositor_windows;
|
||||||
|
XID root_picture;
|
||||||
|
XID damage_region;
|
||||||
};
|
};
|
||||||
|
|
||||||
MetaScreen* meta_screen_new (MetaDisplay *display,
|
MetaScreen* meta_screen_new (MetaDisplay *display,
|
||||||
|
Loading…
Reference in New Issue
Block a user