From 832968ddd619ae92120a352b4566c978911b2b69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Sandmann?= Date: Fri, 3 Mar 2006 15:53:10 +0000 Subject: [PATCH] Split the ScreenInfo data structure into separate, new files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wed Mar 3 13:25:03 2006 Søren Sandmann * src/compositor.c, src/c-screen.[ch]: Split the ScreenInfo data structure into separate, new files c-screen.[ch]. * src/errors.c (x_error_handler): Forward foreign errors to foreign displays. * src/errors.c (meta_errors_register_foreign_display): Implement this function * src/errors.h: Add new meta_errors_register_foreign_display() --- ChangeLog | 13 + src/Makefile.am | 2 + src/c-screen.c | 521 +++++++++++++++++++++++++ src/c-screen.h | 40 ++ src/compositor.c | 989 ++++++++--------------------------------------- src/compositor.h | 9 - src/display.c | 2 +- src/errors.c | 40 +- src/errors.h | 8 + src/screen.c | 6 + src/window.c | 1 + 11 files changed, 785 insertions(+), 846 deletions(-) create mode 100644 src/c-screen.c create mode 100644 src/c-screen.h diff --git a/ChangeLog b/ChangeLog index 17b5cc312..c2bdc364f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +Wed Mar 3 13:25:03 2006 Søren Sandmann + + * src/compositor.c, src/c-screen.[ch]: Split the ScreenInfo data + structure into separate, new files c-screen.[ch]. + + * src/errors.c (x_error_handler): Forward foreign errors to + foreign displays. + + * src/errors.c (meta_errors_register_foreign_display): Implement + this function + + * src/errors.h: Add new meta_errors_register_foreign_display() + Tue Feb 28 14:49:23 2006 Søren Sandmann * src/compositor.c: Put the windows in a stacker rather than diff --git a/src/Makefile.am b/src/Makefile.am index 110614e70..3565d1cba 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,6 +16,8 @@ metacity_SOURCES= \ boxes.h \ boxes.c \ common.h \ + c-screen.c \ + c-screen.h \ compositor.c \ compositor.h \ constraints.c \ diff --git a/src/c-screen.c b/src/c-screen.c new file mode 100644 index 000000000..99df4d258 --- /dev/null +++ b/src/c-screen.c @@ -0,0 +1,521 @@ +/* + * Copyright (C) 2006 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifdef HAVE_COMPOSITOR_EXTENSIONS + +#include + +#include +#include +#include +#include +#include + +#include "screen.h" +#include "c-screen.h" + +struct MetaScreenInfo +{ + WsDisplay *display; + CmStacker *stacker; + + WsWindow *gl_window; + + WsScreen *screen; + MetaScreen *meta_screen; + + GHashTable *nodes_by_xid; + + int repaint_id; + int idle_id; +}; + +#if 0 +static void +update_frame_counter (void) +{ +#define BUFSIZE 128 + static GTimer *timer; + static double buffer [BUFSIZE]; + static int next = 0; + + if (!timer) + timer = g_timer_new (); + + buffer[next++] = g_timer_elapsed (timer, NULL); + + if (next == BUFSIZE) + { + int i; + double total; + + next = 0; + + total = 0.0; + for (i = 1; i < BUFSIZE; ++i) + total += buffer[i] - buffer[i - 1]; + + g_print ("frames per second: %f\n", 1 / (total / (BUFSIZE - 1))); + } +} +#endif + +static void +dump_stacking_order (GList *nodes) +{ + GList *list; + + for (list = nodes; list != NULL; list = list->next) + { + CmDrawableNode *node = list->data; + + if (node) + g_print ("%lx, ", WS_RESOURCE_XID (node->drawable)); + } + g_print ("\n"); +} + +static gboolean +repaint (gpointer data) +{ + MetaScreenInfo *info = data; + CmState *state; + glViewport (0, 0, + info->meta_screen->rect.width, + info->meta_screen->rect.height); + + glClearColor (1.0, 0.8, 0.8, 0.0); + glClear (GL_COLOR_BUFFER_BIT); + + ws_window_raise (info->gl_window); + + state = cm_state_new (); + + cm_state_disable_depth_buffer_update (state); + + cm_node_render (CM_NODE (info->stacker), state); + + cm_state_enable_depth_buffer_update (state); + + g_object_unref (state); + + ws_window_gl_swap_buffers (info->gl_window); + glFinish(); + +#if 0 + dump_stacking_order (info->stacker->children); +#endif + + info->idle_id = 0; + return FALSE; +} + +static CmNode * +find_node (MetaScreenInfo *info, + Window xwindow) +{ + CmNode *node; + + node = g_hash_table_lookup (info->nodes_by_xid, (gpointer)xwindow); + + return node; +} + +static GList *all_screen_infos; + +MetaScreenInfo * +meta_screen_info_get_by_xwindow (Window xwindow) +{ + GList *list; + + for (list = all_screen_infos; list != NULL; list = list->next) + { + MetaScreenInfo *info = list->data; + + if (find_node (info, xwindow)) + return info; + } + + return NULL; +} + +MetaScreenInfo * +meta_screen_info_new (WsDisplay *display, + MetaScreen *screen) +{ + MetaScreenInfo *scr_info = g_new0 (MetaScreenInfo, 1); + WsRegion *region; + + scr_info->screen = ws_display_get_screen_from_number ( + display, screen->number); + scr_info->display = display; + scr_info->gl_window = ws_screen_get_gl_window (scr_info->screen); + scr_info->nodes_by_xid = g_hash_table_new (g_direct_hash, g_direct_equal); + scr_info->meta_screen = screen; + + /* FIXME: This should probably happen in libcm */ + ws_window_set_override_redirect (scr_info->gl_window, TRUE); + region = ws_region_new (scr_info->display); + ws_window_set_input_shape (scr_info->gl_window, region); + g_object_unref (G_OBJECT (region)); + + all_screen_infos = g_list_prepend (all_screen_infos, scr_info); + + return scr_info; +} + +static gboolean +claim_selection (MetaScreenInfo *info) +{ + /* FIXME: + * + * The plan here is to + * + * - Add Selections and Properties as first class objects + * in WS + * + * - Use those to + * - claim the selection + * - back off if someone else claims the selection + * - back back in if that someone else disappears + * + */ + Display *xdisplay; + char *buffer; + Atom atom; + Window current_cm_sn_owner; + WsWindow *new_cm_sn_owner; + + xdisplay = info->meta_screen->display->xdisplay; + + buffer = g_strdup_printf ("CM_S%d", info->meta_screen->number); + + atom = XInternAtom (xdisplay, buffer, False); + + current_cm_sn_owner = XGetSelectionOwner (xdisplay, atom); + + if (current_cm_sn_owner != None) + { + return FALSE; + } + + new_cm_sn_owner = ws_screen_get_root_window (info->screen); + + XSetSelectionOwner (xdisplay, atom, + WS_RESOURCE_XID (new_cm_sn_owner), + CurrentTime); + + return TRUE; +} + +void +meta_screen_info_redirect (MetaScreenInfo *info) +{ + WsWindow *root = ws_screen_get_root_window (info->screen); + +#if 0 + g_print ("redirecting %lx\n", WS_RESOURCE_XID (root)); +#endif + + ws_window_redirect_subwindows (root); + ws_window_unredirect (info->gl_window); + + claim_selection (info); + + ws_window_map (info->gl_window); + + info->stacker = cm_stacker_new (); + + ws_display_sync (info->display); +} + +void +meta_screen_info_unredirect (MetaScreenInfo *info) +{ + WsScreen *ws_screen = info->screen; + WsWindow *root = ws_screen_get_root_window (ws_screen); + +#if 0 + g_print ("unredirecting %lx\n", WS_RESOURCE_XID (root)); +#endif + + g_signal_handler_disconnect (info->stacker, info->repaint_id); + g_object_unref (info->stacker); + + ws_window_unredirect_subwindows (root); + ws_window_unmap (info->gl_window); + + ws_display_sync (info->display); +} + +void +meta_screen_info_queue_paint (MetaScreenInfo *info) +{ + if (!info->idle_id) + info->idle_id = g_idle_add (repaint, info); +} + +void +meta_screen_info_restack (MetaScreenInfo *info, + Window window, + Window above_this) +{ + CmNode *window_node = find_node (info, window); + CmNode *above_node = find_node (info, above_this); + +#if 0 + g_print ("restack %lx over %lx \n", window, above_this); +#endif + +#if 0 + dump_stacking_order (info->stacker->children); +#endif + + if (window_node == above_node) + return; + + if (window_node && above_this == WS_RESOURCE_XID (info->gl_window)) + { + cm_stacker_raise_child (info->stacker, window_node); + } + else if (window_node && above_this == None) + { + cm_stacker_lower_child (info->stacker, window_node); + } + else if (window_node && above_node) + { + cm_stacker_restack_child (info->stacker, window_node, above_node); + } + else + g_print ("nothing happened\n"); + +#if 0 + g_print ("done restacking; new order:\n"); +#endif +#if 0 + dump_stacking_order (info->stacker->children); +#endif + +} + +void +meta_screen_info_raise_window (MetaScreenInfo *info, + Window window) +{ + CmNode *node = find_node (info, window); + + if (node) + cm_stacker_raise_child (info->stacker, node); +} + +void +meta_screen_info_set_size (MetaScreenInfo *info, + Window window, + gint x, + gint y, + gint width, + gint height) +{ + CmNode *node = find_node (info, window); + + if (node) + cm_drawable_node_set_geometry (CM_DRAWABLE_NODE (node), + x, y, width, height); +} + +static void +queue_paint (CmStacker *stacker, + MetaScreenInfo *info) +{ + meta_screen_info_queue_paint (info); +} + +static void +print_child_titles (WsWindow *window) +{ + GList *children = ws_window_query_subwindows (window); + GList *list; + int i; + + g_print ("window: %lx %s\n", WS_RESOURCE_XID (window), ws_window_query_title (window)); + + i = 0; + for (list = children; list != NULL; list = list->next) + { + WsWindow *child = list->data; + + g_print (" %d adding: %lx %s\n", i++, WS_RESOURCE_XID (child), ws_window_query_title (child)); + } +} + +void +meta_screen_info_add_window (MetaScreenInfo *info, + Window xwindow) +{ + CmNode *node; + WsDrawable *drawable; + + ws_display_begin_error_trap (info->display); + + node = find_node (info, xwindow); + drawable = WS_DRAWABLE (ws_window_lookup (info->display, xwindow)); + + if (node) + goto out; + + if (ws_window_query_input_only (WS_WINDOW (drawable))) + goto out; + + node = CM_NODE (cm_drawable_node_new (drawable)); + +#if 0 + print_child_titles (WS_WINDOW (drawable)); +#endif + + cm_stacker_add_child (info->stacker, node); + + g_hash_table_insert (info->nodes_by_xid, (gpointer)xwindow, node); + g_object_unref (node); + + info->repaint_id = + g_signal_connect (info->stacker, "need_repaint", + G_CALLBACK (queue_paint), info); + +out: + if (node) + { +#if 0 + g_print ("drawable %lx is now ", WS_RESOURCE_XID (drawable)); +#endif + if (ws_window_query_mapped (WS_WINDOW (drawable))) + { +#if 0 + g_print ("mapped\n"); +#endif + cm_drawable_node_unset_geometry (node); + cm_drawable_node_set_alpha (node, 1.0); + cm_drawable_node_set_viewable (node, TRUE); + cm_drawable_node_update_pixmap (node); + } + else + { +#if 0 + g_print ("unmapped\n"); +#endif + cm_drawable_node_set_viewable (node, FALSE); + } + } + + ws_display_end_error_trap (info->display); + +#if 0 + g_print ("done checking\n"); +#endif + + return; +} + + +void +meta_screen_info_remove_window (MetaScreenInfo *info, + Window xwindow) +{ + CmNode *node = find_node (info, xwindow); + + g_print ("removing %lx\n", xwindow); + + g_hash_table_remove (info->nodes_by_xid, (gpointer)xwindow); + + cm_stacker_remove_child (info->stacker, node); +} + +void +meta_screen_info_set_updates (MetaScreenInfo *info, + Window xwindow, + gboolean updates) +{ + CmDrawableNode *node = CM_DRAWABLE_NODE (find_node (info, xwindow)); + + if (node) + cm_drawable_node_set_updates (node, updates); +} + + +void +meta_screen_info_set_patch (MetaScreenInfo *info, + Window xwindow, + CmPoint points[4][4]) +{ + CmDrawableNode *node = CM_DRAWABLE_NODE (find_node (info, xwindow)); + + if (node) + cm_drawable_node_set_patch (node, points); +} + +void +meta_screen_info_unset_patch (MetaScreenInfo *info, + Window xwindow) +{ + CmDrawableNode *node = CM_DRAWABLE_NODE (find_node (info, xwindow)); + + if (node) + cm_drawable_node_unset_geometry (node); +} + +void +meta_screen_info_set_alpha (MetaScreenInfo *info, + Window xwindow, + gdouble alpha) +{ + CmDrawableNode *node = CM_DRAWABLE_NODE (find_node (info, xwindow)); + cm_drawable_node_set_alpha (node, alpha); +} + + +void +meta_screen_info_get_real_size (MetaScreenInfo *info, + Window xwindow, + WsRectangle *size) +{ + CmDrawableNode *node = CM_DRAWABLE_NODE (find_node (info, xwindow)); + + if (!size) + return; + + size->x = node->real_x; + size->y = node->real_y; + size->width = node->real_width; + size->height = node->real_height; +} + +void +meta_screen_info_unmap (MetaScreenInfo *info, + Window xwindow) +{ + CmDrawableNode *node = CM_DRAWABLE_NODE (find_node (info, xwindow)); + +#if 0 + g_print ("unmapping: %lx\n", xwindow); +#endif + + if (node) + cm_drawable_node_set_viewable (node, FALSE); +} + +#endif diff --git a/src/c-screen.h b/src/c-screen.h new file mode 100644 index 000000000..54fd26c94 --- /dev/null +++ b/src/c-screen.h @@ -0,0 +1,40 @@ +#include "screen.h" + +typedef struct MetaScreenInfo MetaScreenInfo; + +MetaScreenInfo *meta_screen_info_new (WsDisplay *display, + MetaScreen *screen); +MetaScreenInfo *meta_screen_info_get_by_xwindow (Window xwindow); +void meta_screen_info_destroy (MetaScreenInfo *scr_info); +void meta_screen_info_redirect (MetaScreenInfo *info); +void meta_screen_info_unredirect (MetaScreenInfo *info); +void meta_screen_info_add_window (MetaScreenInfo *scr_info, + Window xwindow); +void meta_screen_info_remove_window (MetaScreenInfo *scr_info, + Window xwindow); +void meta_screen_info_restack (MetaScreenInfo *scr_info, + Window window, + Window above_this); +void meta_screen_info_set_size (MetaScreenInfo *info, + Window window, + gint x, + gint y, + gint width, + gint height); +void meta_screen_info_raise_window (MetaScreenInfo *scr_info, + Window window); +void meta_screen_info_queue_paint (MetaScreenInfo *info); +void meta_screen_info_set_updates (MetaScreenInfo *info, + Window xwindow, + gboolean updates); +void meta_screen_info_set_patch (MetaScreenInfo *info, + Window xwindow, + CmPoint points[4][4]); +void meta_screen_info_unset_patch (MetaScreenInfo *info, + Window xwindow); +void meta_screen_info_set_alpha (MetaScreenInfo *info, + Window xwindow, + gdouble alpha); +void meta_screen_info_get_real_size (MetaScreenInfo *info, + Window xwindow, + WsRectangle *size); diff --git a/src/compositor.c b/src/compositor.c index c510beff0..8bb702389 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -49,20 +49,15 @@ #include #include "spring-model.h" #include + +#include "c-screen.h" #endif /* HAVE_COMPOSITE_EXTENSIONS */ #define FRAME_INTERVAL_MILLISECONDS ((int)(1000.0/40.0)) #ifdef HAVE_COMPOSITE_EXTENSIONS -/* Screen specific information */ -typedef struct -{ - /* top of stack is first in list */ - GList *compositor_nodes; - WsWindow *glw; - int idle_id; -} ScreenInfo; +/* Screen specific information */ typedef struct MoveInfo MoveInfo; struct MetaCompositor @@ -71,8 +66,6 @@ struct MetaCompositor WsDisplay *display; - GHashTable *window_hash; - guint repair_idle; guint enabled : 1; @@ -83,26 +76,27 @@ struct MetaCompositor guint debug_updates : 1; GList *ignored_damage; - - CmStacker *stacker; - CmCube *cube; - CmRotation *rotation; - + MoveInfo *move_info; }; #endif /* HAVE_COMPOSITE_EXTENSIONS */ #ifdef HAVE_COMPOSITE_EXTENSIONS -static void -free_window_hash_value (void *v) -{ - CmDrawableNode *drawable_node = v; -} static WsDisplay *compositor_display; #endif /* HAVE_COMPOSITE_EXTENSIONS */ -MetaCompositor* +#ifdef HAVE_COMPOSITE_EXTENSIONS +static void +handle_error (Display *dpy, XErrorEvent *ev, gpointer data) +{ + WsDisplay *display = data; + + ws_display_process_error (display, ev); +} +#endif + +MetaCompositor * meta_compositor_new (MetaDisplay *display) { #ifdef HAVE_COMPOSITE_EXTENSIONS @@ -115,6 +109,9 @@ meta_compositor_new (MetaDisplay *display) gboolean has_extensions; compositor_display = ws_display_new (NULL); + + meta_errors_register_foreign_display ( + compositor_display->xdisplay, handle_error, compositor_display); has_extensions = ws_display_init_composite (compositor_display) && @@ -141,25 +138,8 @@ meta_compositor_new (MetaDisplay *display) compositor->meta_display = display; - 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->cube = cm_cube_new (); - compositor->stacker = cm_stacker_new (); - compositor->rotation = cm_rotation_new (CM_NODE (compositor->cube)); - - cm_cube_set_face (compositor->cube, 0, CM_NODE (compositor->stacker)); - cm_cube_set_face (compositor->cube, 1, CM_NODE (compositor->stacker)); - cm_cube_set_face (compositor->cube, 2, CM_NODE (compositor->stacker)); - cm_cube_set_face (compositor->cube, 3, CM_NODE (compositor->stacker)); - cm_cube_set_face (compositor->cube, 4, CM_NODE (compositor->stacker)); - cm_cube_set_face (compositor->cube, 5, CM_NODE (compositor->stacker)); - + return compositor; #else /* HAVE_COMPOSITE_EXTENSIONS */ return NULL; @@ -198,9 +178,6 @@ meta_compositor_unref (MetaCompositor *compositor) */ remove_repair_idle (compositor); - if (compositor->window_hash) - g_hash_table_destroy (compositor->window_hash); - g_free (compositor); #endif /* HAVE_COMPOSITE_EXTENSIONS */ } @@ -222,109 +199,37 @@ draw_windows (MetaScreen *screen, #if 0 g_print ("rendering: %p\n", node); #endif - + cm_node_render (node, NULL); } -static MetaScreen * -node_get_screen (Display *dpy, - CmDrawableNode *node) -{ - /* FIXME: we should probably have a reverse mapping - * from nodes to screens - */ - - Screen *screen = XDefaultScreenOfDisplay (dpy); - return meta_screen_for_x_screen (screen); -} - -static void -handle_restacking (MetaCompositor *compositor, - CmDrawableNode *node, - CmDrawableNode *above) -{ - GList *window_link, *above_link; - MetaScreen *screen; - ScreenInfo *scr_info; - - screen = node_get_screen (compositor->meta_display->xdisplay, node); - scr_info = screen->compositor_data; - - window_link = g_list_find (scr_info->compositor_nodes, node); - above_link = g_list_find (scr_info->compositor_nodes, above); - - if (!window_link || !above_link) - return; - - if (window_link == above_link) - { - /* This can happen if the topmost window is raised above - * the GL window - */ - return; - } - -#if 0 - g_print ("restacking\n"); -#endif - - if (window_link->next != above_link) - { - ScreenInfo *scr_info = screen->compositor_data; - - scr_info->compositor_nodes = - g_list_delete_link (scr_info->compositor_nodes, window_link); - scr_info->compositor_nodes = - g_list_insert_before (scr_info->compositor_nodes, above_link, node); - } - - cm_stacker_restack_child (compositor->stacker, CM_NODE (node), CM_NODE (above)); -} - static void process_configure_notify (MetaCompositor *compositor, XConfigureEvent *event) { - WsWindow *above_window; - CmDrawableNode *node = g_hash_table_lookup (compositor->window_hash, - &event->window); - CmDrawableNode *above_node; - MetaScreen *screen; - ScreenInfo *scr_info; - + MetaScreenInfo *minfo = meta_screen_info_get_by_xwindow (event->window); + #if 0 - g_print ("processing configure\n"); + g_print ("minfo: %lx => %p\n", event->window, minfo); + + g_print ("configure on %lx (above: %lx)\n", event->window, event->above); #endif - if (!node) - return; - + if (!minfo) + { #if 0 - g_print ("we do now have a node\n"); + g_print (" --- ignoring configure (no screen info)\n"); #endif - - screen = node_get_screen (compositor->meta_display->xdisplay, node); - scr_info = screen->compositor_data; - - above_window = ws_window_lookup (WS_RESOURCE (node->drawable)->display, - event->above); - - if (above_window == scr_info->glw) - { - above_node = scr_info->compositor_nodes->data; - } - else - { - above_node = g_hash_table_lookup (compositor->window_hash, - &event->above); - } - + return; + } + + meta_screen_info_restack (minfo, event->window, event->above); #if 0 - cm_drawable_node_set_size (node, - event->x, event->y, event->width, event->height); + meta_screen_info_set_size (minfo, + event->window, + event->x, event->y, + event->width, event->height); #endif - - handle_restacking (compositor, node, above_node); } #endif /* HAVE_COMPOSITE_EXTENSIONS */ @@ -340,7 +245,6 @@ process_expose (MetaCompositor *compositor, #endif /* HAVE_COMPOSITE_EXTENSIONS */ #ifdef HAVE_COMPOSITE_EXTENSIONS -static void queue_repaint (CmDrawableNode *node, gpointer data); typedef struct { @@ -350,30 +254,6 @@ typedef struct #define FADE_TIME 0.3 -static gboolean -fade_in (gpointer data) -{ - FadeInfo *info = data; - gdouble elapsed = g_timer_elapsed (info->timer, NULL); - gdouble alpha; - - if (elapsed > FADE_TIME) - alpha = 1.0; - else - alpha = elapsed / FADE_TIME; - - cm_drawable_node_set_alpha (info->node, alpha); - - if (elapsed >= FADE_TIME) - { - return FALSE; - } - else - { - return TRUE; - } -} - static gboolean fade_out (gpointer data) { @@ -394,11 +274,11 @@ fade_out (gpointer data) if (elapsed >= FADE_TIME) { - g_object_unref (info->node); - - cm_drawable_node_set_viewable (info->node, FALSE); - - return FALSE; + g_object_unref (info->node); + + cm_drawable_node_set_viewable (info->node, FALSE); + + return FALSE; } else { @@ -412,7 +292,6 @@ static void process_map (MetaCompositor *compositor, XMapEvent *event) { - CmDrawableNode *node; MetaScreen *screen; /* FIXME: do we sometimes get mapnotifies for windows that are @@ -428,51 +307,15 @@ process_map (MetaCompositor *compositor, meta_topic (META_DEBUG_COMPOSITOR, "MapNotify received on non-root 0x%lx for 0x%lx\n", event->event, event->window); - return; /* MapNotify wasn't for a child of the root */ + + /* MapNotify wasn't for a child of the root */ + return; } -#if 0 - g_print ("processing map for %lx\n", event->window); -#endif - - node = g_hash_table_lookup (compositor->window_hash, - &event->window); - if (node == NULL) - { - XWindowAttributes attrs; - - meta_error_trap_push_with_return (compositor->meta_display); - - XGetWindowAttributes (compositor->meta_display->xdisplay, - event->window, &attrs); - - if (meta_error_trap_pop_with_return (compositor->meta_display, TRUE) != Success) - { - meta_topic (META_DEBUG_COMPOSITOR, "Failed to get attributes for window 0x%lx\n", - event->window); - } - else - { - meta_compositor_add_window (compositor, - event->window, &attrs); - } - } - else - { - cm_drawable_node_update_pixmap (node); - - cm_drawable_node_set_alpha (node, 1.0); - - FadeInfo *info = g_new (FadeInfo, 1); - - info->node = g_object_ref (node); - info->timer = g_timer_new (); - - cm_drawable_node_set_viewable (node, TRUE); - } - - queue_repaint (node, screen); + meta_screen_info_add_window (screen->compositor_data, + event->window); } + #endif /* HAVE_COMPOSITE_EXTENSIONS */ #ifdef HAVE_COMPOSITE_EXTENSIONS @@ -480,7 +323,6 @@ static void process_unmap (MetaCompositor *compositor, XUnmapEvent *event) { - CmDrawableNode *node; MetaScreen *screen; /* See if window was unmapped as child of root */ @@ -492,27 +334,14 @@ process_unmap (MetaCompositor *compositor, meta_topic (META_DEBUG_COMPOSITOR, "UnmapNotify received on non-root 0x%lx for 0x%lx\n", event->event, event->window); - return; /* UnmapNotify wasn't for a child of the root */ - } - -#if 0 - g_print ("processing unmap on %lx\n", event->window); -#endif - - node = g_hash_table_lookup (compositor->window_hash, - &event->window); - if (node != NULL) - { - FadeInfo *info = g_new (FadeInfo, 1); - info->node = g_object_ref (node); - info->timer = g_timer_new (); - - g_idle_add (fade_out, info); + /* UnmapNotify wasn't for a child of the root */ + return; } - - queue_repaint (node, screen); + + meta_screen_info_unmap (screen->compositor_data, event->window); } + #endif /* HAVE_COMPOSITE_EXTENSIONS */ #ifdef HAVE_COMPOSITE_EXTENSIONS @@ -550,7 +379,6 @@ process_create (MetaCompositor *compositor, g_print (//META_DEBUG_COMPOSITOR, "Create window 0x%lx, adding\n", event->window); #endif - meta_compositor_add_window (compositor, event->window, &attrs); } @@ -592,8 +420,6 @@ process_reparent (MetaCompositor *compositor, */ MetaScreen *event_screen; MetaScreen *parent_screen; - CmDrawableNode *node; - XWindowAttributes attrs; event_screen = meta_display_screen_for_root (compositor->meta_display, event->event); @@ -605,13 +431,7 @@ process_reparent (MetaCompositor *compositor, event->event, event->window); return; } - -#if 0 - g_print (//META_DEBUG_COMPOSITOR, - "Reparent window 0x%lx new parent 0x%lx received on 0x%lx\n", - event->window, event->parent, event->event); -#endif - + parent_screen = meta_display_screen_for_root (compositor->meta_display, event->parent); @@ -620,32 +440,17 @@ process_reparent (MetaCompositor *compositor, meta_topic (META_DEBUG_COMPOSITOR, "ReparentNotify 0x%lx to a non-screen or unmanaged screen 0x%lx\n", event->window, event->parent); + meta_compositor_remove_window (compositor, event->window); return; } - - node = g_hash_table_lookup (compositor->window_hash, - &event->window); - - meta_error_trap_push_with_return (compositor->meta_display); - - XGetWindowAttributes (compositor->meta_display->xdisplay, - event->window, &attrs); - - if (meta_error_trap_pop_with_return (compositor->meta_display, TRUE) != Success) - { - meta_topic (META_DEBUG_COMPOSITOR, "Failed to get attributes for window 0x%lx\n", - event->window); - } else { - meta_topic (META_DEBUG_COMPOSITOR, - "Reparent window 0x%lx into screen 0x%lx, adding\n", - event->window, event->parent); - meta_compositor_add_window (compositor, - event->window, &attrs); + meta_screen_info_raise_window (parent_screen->compositor_data, + event->window); } } + #endif /* HAVE_COMPOSITE_EXTENSIONS */ void @@ -716,36 +521,9 @@ wavy (double time, m++; } -static void -update_frame_counter (void) -{ -#define BUFSIZE 128 - static GTimer *timer; - static double buffer [BUFSIZE]; - static int next = 0; - - if (!timer) - timer = g_timer_new (); - - buffer[next++] = g_timer_elapsed (timer, NULL); - - if (next == BUFSIZE) - { - int i; - double total; - - next = 0; - - total = 0.0; - for (i = 1; i < BUFSIZE; ++i) - total += buffer[i] - buffer[i - 1]; - - g_print ("frames per second: %f\n", 1 / (total / (BUFSIZE - 1))); - } -} - static GTimer *timer; +#if 0 static gboolean update (gpointer data) { @@ -755,17 +533,17 @@ update (gpointer data) gdouble angle; glViewport (0, 0, screen->rect.width, screen->rect.height); - + if (!timer) timer = g_timer_new (); - + #if 0 g_print ("rotation: %f\n", 360 * g_timer_elapsed (timer, NULL)); #endif - + angle = g_timer_elapsed (timer, NULL) * 90; #if 0 - + angle = 180.0; #endif @@ -779,13 +557,13 @@ update (gpointer data) glDisable (GL_TEXTURE_2D); glDisable (GL_DEPTH_TEST); ws_window_raise (gl_window); - + #if 0 glMatrixMode (GL_MODELVIEW); glLoadIdentity(); #endif - + #if 0 glTranslatef (-1.0, -1.0, 0.0); #endif @@ -810,13 +588,13 @@ update (gpointer data) */ CmState *state = cm_state_new (); - + cm_state_disable_depth_buffer_update (state); - + cm_node_render (CM_NODE (screen->display->compositor->stacker), state); cm_state_enable_depth_buffer_update (state); - + g_object_unref (state); #if 0 @@ -832,7 +610,9 @@ update (gpointer data) return FALSE; } +#endif +#if 0 static void queue_repaint (CmDrawableNode *node, gpointer data) { @@ -864,6 +644,7 @@ queue_repaint (CmDrawableNode *node, gpointer data) } } #endif /* HAVE_COMPOSITE_EXTENSIONS */ +#endif #ifdef HAVE_COMPOSITE_EXTENSIONS static void @@ -890,194 +671,39 @@ meta_compositor_add_window (MetaCompositor *compositor, XWindowAttributes *attrs) { #ifdef HAVE_COMPOSITE_EXTENSIONS - CmDrawableNode *node; - MetaScreen *screen; - WsDrawable *drawable; - ScreenInfo *scr_info; + MetaScreen *screen = meta_screen_for_x_screen (attrs->screen); + MetaScreenInfo *minfo = screen->compositor_data; - if (!compositor->enabled) - return; /* no extension */ - - screen = meta_screen_for_x_screen (attrs->screen); - g_assert (screen != NULL); - - node = g_hash_table_lookup (compositor->window_hash, - &xwindow); - -#if 0 - g_print ("adding %lx\n", xwindow); + meta_screen_info_add_window (minfo, xwindow); #endif - - if (node != NULL) - { - g_print ("window %lx already added\n", xwindow); - meta_topic (META_DEBUG_COMPOSITOR, - "Window 0x%lx already added\n", xwindow); - return; - } - - ws_display_begin_error_trap (compositor->display); - - drawable = (WsDrawable *)ws_window_lookup (compositor->display, xwindow); - - scr_info = screen->compositor_data; - - ws_display_end_error_trap (compositor->display); - - if (!drawable) - return; - - g_assert (scr_info); - - ws_display_begin_error_trap (compositor->display); - - if (ws_window_query_input_only ((WsWindow *)drawable) || - drawable == (WsDrawable *)scr_info->glw) - { - ws_display_end_error_trap (compositor->display); - return; - } - - ws_display_end_error_trap (compositor->display); - - node = cm_drawable_node_new (drawable); - - cm_stacker_add_child (compositor->stacker, CM_NODE (node)); - - g_object_unref (node); - - cm_drawable_node_set_damage_func (node, queue_repaint, screen); -#if 0 - drawable_node_set_deformation_func (node, wavy, NULL); -#endif - - /* FIXME: we should probably just store xid's directly */ - g_hash_table_insert (compositor->window_hash, - &(WS_RESOURCE (node->drawable)->xid), node); - - /* assume cwindow is at the top of the stack as it was either just - * created or just reparented to the root window - */ - scr_info->compositor_nodes = g_list_prepend (scr_info->compositor_nodes, - node); - -#if 0 - dump_stacking_order (scr_info->compositor_nodes); -#endif - -#endif /* HAVE_COMPOSITE_EXTENSIONS */ } + void meta_compositor_remove_window (MetaCompositor *compositor, Window xwindow) { #ifdef HAVE_COMPOSITE_EXTENSIONS - CmDrawableNode *node; - MetaScreen *screen; - ScreenInfo *scr_info; - - if (!compositor->enabled) - return; /* no extension */ - - node = g_hash_table_lookup (compositor->window_hash, - &xwindow); - - if (node == NULL) - { - meta_topic (META_DEBUG_COMPOSITOR, - "Window 0x%lx already removed\n", xwindow); - return; - } - - screen = node_get_screen (compositor->meta_display->xdisplay, node); - scr_info = screen->compositor_data; - - scr_info->compositor_nodes = g_list_remove (scr_info->compositor_nodes, - node); - - /* Frees node as side effect */ - g_hash_table_remove (compositor->window_hash, - &xwindow); + MetaScreenInfo *minfo; + minfo = meta_screen_info_get_by_xwindow (xwindow); #endif /* HAVE_COMPOSITE_EXTENSIONS */ } -static gboolean -cont_update (gpointer data) -{ - update (data); - - return TRUE; -} - void meta_compositor_manage_screen (MetaCompositor *compositor, MetaScreen *screen) { #ifdef HAVE_COMPOSITE_EXTENSIONS - ScreenInfo *scr_info = g_new0 (ScreenInfo, 1); - - WsScreen *ws_screen = - ws_display_get_screen_from_number (compositor->display, screen->number); - WsWindow *root = ws_screen_get_root_window (ws_screen); - WsRegion *region; - Window current_cm_sn_owner; - WsWindow *new_cm_sn_owner; - Display *xdisplay; - Atom cm_sn_atom; - char buf[128]; - - if (screen->compositor_data) - return; - - scr_info->glw = ws_screen_get_gl_window (ws_screen); - scr_info->compositor_nodes = NULL; - scr_info->idle_id = 0; - - g_print ("setting compositor_data for screen %p to %p\n", screen, scr_info); - screen->compositor_data = scr_info; - - ws_display_init_composite (compositor->display); - ws_display_init_damage (compositor->display); - ws_display_init_fixes (compositor->display); - - g_print ("redirecting\n"); - ws_window_redirect_subwindows (root); - ws_window_set_override_redirect (scr_info->glw, TRUE); - ws_window_unredirect (scr_info->glw); - - region = ws_region_new (compositor->display); - ws_window_set_input_shape (scr_info->glw, region); - g_object_unref (G_OBJECT (region)); - - xdisplay = ws_screen->display->xdisplay; - snprintf(buf, sizeof(buf), "CM_S%d", screen->number); - cm_sn_atom = XInternAtom (xdisplay, buf, False); - current_cm_sn_owner = XGetSelectionOwner (xdisplay, cm_sn_atom); - - if (current_cm_sn_owner != None) - { - meta_warning (_("Screen %d on display \"%s\" already has a compositing manager\n"), - screen->number, ",madgh"); - } - - new_cm_sn_owner = ws_screen_get_root_window (ws_screen); - - XSetSelectionOwner (xdisplay, cm_sn_atom, WS_RESOURCE_XID (new_cm_sn_owner), - CurrentTime); - - ws_window_map (scr_info->glw); - - ws_display_sync (compositor->display); - -#if 0 - g_idle_add (cont_update, screen); -#endif - -#if 0 - children = ws_window_list_children (root); -#endif - + MetaScreenInfo *info; + + if (screen->compositor_data) + return; + + info = meta_screen_info_new (compositor->display, screen); + + screen->compositor_data = info; + + meta_screen_info_redirect (info); #endif } @@ -1085,59 +711,15 @@ void meta_compositor_unmanage_screen (MetaCompositor *compositor, MetaScreen *screen) { -#ifdef HAVE_COMPOSITE_EXTENSIONS - ScreenInfo *scr_info = screen->compositor_data; - WsScreen *ws_screen = - ws_display_get_screen_from_number (compositor->display, screen->number); - WsWindow *root = ws_screen_get_root_window (ws_screen); - - if (!compositor->enabled) - return; /* no extension */ - - while (scr_info->compositor_nodes != NULL) - { - CmDrawableNode *node = scr_info->compositor_nodes->data; - - meta_compositor_remove_window (compositor, - WS_RESOURCE (node->drawable)->xid); - } - - ws_window_raise (scr_info->glw); - - g_print ("unredirecting\n"); - ws_window_unredirect_subwindows (root); - ws_window_unmap (scr_info->glw); - - /* We need to sync here, because if someone is furiously - * clicking the 'compositing manager' check box, we might - * attempt to redirect the window again before this unredirect - * has reached the server - */ - ws_display_sync (compositor->display); +#ifdef HAVE_COMPOSITE_EXTENSIONS + MetaScreenInfo *info = screen->compositor_data; + meta_screen_info_unredirect (info); screen->compositor_data = NULL; - -#endif /* HAVE_COMPOSITE_EXTENSIONS */ +#endif } #ifdef HAVE_COMPOSITE_EXTENSIONS -static CmDrawableNode * -window_to_node (MetaCompositor *compositor, - MetaWindow *window) -{ - Window xwindow; - CmDrawableNode *node; - - if (window->frame) - xwindow = window->frame->xwindow; - else - xwindow = window->xwindow; - - node = g_hash_table_lookup (compositor->window_hash, - &xwindow); - - return node; -} #endif typedef struct @@ -1232,7 +814,7 @@ interpolate_rectangle (gdouble t, #endif -#define MINIMIZE_STYLE 3 +#define MINIMIZE_STYLE 1 #ifndef HAVE_COMPOSITE_EXTENSIONS #undef MINIMIZE_STYLE @@ -1257,11 +839,11 @@ meta_compositor_minimize (MetaCompositor *compositor, typedef struct { - CmDrawableNode *node; + MetaWindow *window; GTimer *timer; MetaCompositor *compositor; - ScreenInfo *scr_info; + MetaScreenInfo *scr_info; MetaAnimationFinishedFunc finished_func; gpointer finished_data; @@ -1286,6 +868,15 @@ typedef struct gboolean phase_5_started; } MiniInfo; +static Window +get_xid (MetaWindow *window) +{ + if (window->frame) + return window->frame->xwindow; + else + return window->xwindow; +} + static void set_geometry (MiniInfo *info, gdouble elapsed) { @@ -1300,9 +891,10 @@ set_geometry (MiniInfo *info, gdouble elapsed) g_print ("setting: %d %d %d %d\n", rect.x, rect.y, rect.width, rect.height); #endif - cm_drawable_node_set_geometry (info->node, - rect.x, rect.y, - rect.width, rect.height); + meta_screen_info_set_size (info->scr_info, + get_xid (info->window), + rect.x, rect.y, + rect.width, rect.height); } static int @@ -1320,19 +912,21 @@ run_phase_1 (MiniInfo *info, gdouble elapsed) g_print ("starting phase 1\n"); #endif info->phase_1_started = TRUE; + + meta_screen_info_get_real_size (info->scr_info, get_xid (info->window), + &info->current_geometry); +#if 0 info->current_geometry.x = info->node->real_x; info->current_geometry.y = info->node->real_y; info->current_geometry.width = info->node->real_width; info->current_geometry.height = info->node->real_height; +#endif info->target_geometry.height = info->button_height; info->target_geometry.width = info->button_height * info->aspect_ratio; info->target_geometry.x = info->button_x + center (info->target_geometry.width, info->button_width); - info->target_geometry.y = info->node->real_y + center (info->button_height, info->node->real_height); - - handle_restacking (info->compositor, info->node, - info->scr_info->compositor_nodes->data); + info->target_geometry.y = info->current_geometry.y + center (info->button_height, info->current_geometry.height); } set_geometry (info, elapsed); @@ -1368,6 +962,10 @@ run_phase_3 (MiniInfo *info, gdouble elapsed) if (!info->phase_3_started) { WsRectangle cur = info->target_geometry; + WsRectangle real; + + meta_screen_info_get_real_size (info->scr_info, get_xid (info->window), + &real); g_print ("starting phase 3\n"); info->phase_3_started = TRUE; @@ -1377,7 +975,7 @@ run_phase_3 (MiniInfo *info, gdouble elapsed) info->target_geometry.height = info->button_height; info->target_geometry.width = info->button_height * info->aspect_ratio; info->target_geometry.x = info->button_x + center (info->target_geometry.width, info->button_width); - info->target_geometry.y = info->node->real_y + center (info->button_height, info->node->real_height); + info->target_geometry.y = real.y + center (info->button_height, real.height); } set_geometry (info, elapsed); @@ -1423,8 +1021,9 @@ run_phase_5 (MiniInfo *info, gdouble elapsed) } set_geometry (info, elapsed); - - cm_drawable_node_set_alpha (info->node, 1 - elapsed); + + meta_screen_info_set_alpha (info->scr_info, + get_xid (info->window), 1 - elapsed); } static gboolean @@ -1469,12 +1068,6 @@ run_animation_01 (gpointer data) } else { - cm_drawable_node_set_viewable (info->node, FALSE); - - cm_drawable_node_unset_geometry (info->node); - - cm_drawable_node_set_alpha (info->node, 1.0); - if (info->finished_func) info->finished_func (info->finished_data); @@ -1495,11 +1088,10 @@ meta_compositor_minimize (MetaCompositor *compositor, gpointer data) { MiniInfo *info = g_new (MiniInfo, 1); - CmDrawableNode *node = window_to_node (compositor, window); WsRectangle start; MetaScreen *screen = window->screen; - info->node = node; + info->window = window; info->timer = g_timer_new (); info->finished_func = finished; @@ -1528,269 +1120,6 @@ meta_compositor_minimize (MetaCompositor *compositor, g_idle_add (run_animation_01, info); } -void -meta_compositor_unminimize (MetaCompositor *compositor, - MetaWindow *window, - int x, - int y, - int width, - int height, - MetaAnimationFinishedFunc finished, - gpointer data) -{ - finished(data); -} - -#elif MINIMIZE_STYLE == 2 - -#if 0 -static gboolean -do_minimize_animation (gpointer data) -{ - MiniInfo *info = data; - double elapsed; - gboolean done = FALSE; - -#define FADE_TIME 0.5 - - elapsed = g_timer_elapsed (info->timer, NULL); - elapsed = elapsed / FADE_TIME; - - if (elapsed >= 1.0) - { - elapsed = 1.0; - done = TRUE; - } - - g_print ("%f\n", elapsed); - - cm_drawable_node_set_geometry (info->node, - info->node->real_x + interpolate (elapsed, 0, info->node->real_width / 2, 1), - info->node->real_y + interpolate (elapsed, 0, info->node->real_height / 2, 1), - interpolate (elapsed, info->node->real_width, 0, 1), - interpolate (elapsed, info->node->real_height, 0, 1)); - - if (done) - return FALSE; - -#if 0 - g_print ("inter: %f %f %f\n", 0, 735, interpolate (0.0, 735.0, 0.5, 1.0)); - - g_print ("inter x .5: %f (%d %d)\n", info->node->real_x + interpolate (0, info->node->real_width / 2, .5, 1), 0, info->node->real_width); -#endif - - cm_drawable_node_set_alpha (info->node, 1 - elapsed); - - if (done) - { - } - else - { - return TRUE; - } - -#if 0 - queue_repaint (info->node, - node_get_screen (info->window->display->xdisplay, - info->node)); -#endif -} -#endif - -#elif MINIMIZE_STYLE == 3 - -typedef struct -{ - CmDrawableNode *node; - GTimer *timer; - gboolean expand; - - MetaCompositor *compositor; - MetaScreen *screen; - MetaRectangle rect; - double last_time; - - MetaAnimationFinishedFunc finished_func; - gpointer finished_data; - - Model *model; - - int button_x; - int button_y; - int button_width; - int button_height; -} MiniInfo; - -#define WOBBLE_TIME 1.0 - -static void -set_patch (CmDrawableNode *node, - Model *model, - gdouble blend, - MetaRectangle *target) -{ - int i, j; - CmPoint points[4][4]; - - for (i = 0; i < 4; i++) - for (j = 0; j < 4; j++) - { - double obj_x, obj_y; - int p_x, p_y; - - model_get_position (model, i, j, &obj_x, &obj_y); - -#if 0 - target_x = info->node->real_x + i * info->node->real_width / 3; - target_y = info->node->real_y + j * info->node->real_height / 3; -#endif - if (target) - { - p_x = target->x + i * target->width / 3; - p_y = target->y + j * target->height / 3; - - points[j][i].x = (1 - blend) * obj_x + blend * p_x; - points[j][i].y = (1 - blend) * obj_y + blend * p_y; - } - else - { - points[j][i].x = obj_x; - points[j][i].y = obj_y; - } - } - - cm_drawable_node_set_patch (node, points); -} - -static gboolean -run_animation (gpointer data) -{ - MiniInfo *info = data; - gdouble t, blend; - double n_steps; - int i; - - t = g_timer_elapsed (info->timer, NULL); - - n_steps = floor ((t - info->last_time) * 75); - - for (i = 0; i < n_steps; ++i) - model_step (info->model); - - if (i > 0) - info->last_time = t; - - blend = t / WOBBLE_TIME; - - set_patch (info->node, info->model, 0.0, NULL); - - if (info->expand) - cm_drawable_node_set_alpha (info->node, t / WOBBLE_TIME); - else - cm_drawable_node_set_alpha (info->node, 1.0 - t / WOBBLE_TIME); - - if (t > WOBBLE_TIME) - { - cm_drawable_node_set_viewable (info->node, info->expand); - cm_drawable_node_unset_geometry (info->node); - cm_drawable_node_set_alpha (info->node, 1.0); - - if (info->finished_func) - { - info->finished_func (info->finished_data); - - model_destroy (info->model); - info->model = NULL; - } - - return FALSE; - } - else - { - queue_repaint (info->node, info->screen); - - return TRUE; - } -} - -void -meta_compositor_minimize (MetaCompositor *compositor, - MetaWindow *window, - int x, - int y, - int width, - int height, - MetaAnimationFinishedFunc finished, - gpointer data) -{ -#ifdef HAVE_COMPOSITE_EXTENSIONS - MiniInfo *info = g_new (MiniInfo, 1); - CmDrawableNode *node = window_to_node (compositor, window); - MetaScreen *screen = window->screen; - - info->node = node; - info->timer = g_timer_new (); - - info->finished_func = finished; - info->finished_data = data; - - info->rect = window->user_rect; - - info->model = model_new (&info->rect, FALSE); - - info->last_time = 0.0; - - info->expand = FALSE; - info->button_x = x; - info->button_y = y; - info->button_width = width; - info->button_height = height; - - info->compositor = compositor; - info->screen = screen; - - g_idle_add (run_animation, info); -#endif -} - -void -meta_compositor_unminimize (MetaCompositor *compositor, - MetaWindow *window, - int x, - int y, - int width, - int height, - MetaAnimationFinishedFunc finished, - gpointer data) -{ -#ifdef HAVE_COMPOSITE_EXTENSIONS - MiniInfo *info = g_new (MiniInfo, 1); - CmDrawableNode *node = window_to_node (compositor, window); - MetaScreen *screen = window->screen; - - info->node = node; - info->timer = g_timer_new (); - - info->finished_func = finished; - info->finished_data = data; - - info->rect = window->user_rect; - - info->model = model_new (&info->rect, TRUE); - - info->expand = TRUE; - info->button_x = x; - info->button_y = y; - info->button_width = width; - info->button_height = height; - - info->compositor = compositor; - info->screen = screen; - - g_idle_add (run_animation, info); -#endif -} - #endif void @@ -1799,15 +1128,9 @@ meta_compositor_set_updates (MetaCompositor *compositor, gboolean updates) { #ifdef HAVE_COMPOSITE_EXTENSIONS - CmDrawableNode *node = window_to_node (compositor, window); + MetaScreenInfo *info = window->screen->compositor_data; - if (node) - { - g_print ("turning updates %s\n", updates? "on" : "off"); - cm_drawable_node_set_updates (node, updates); - - update (window->screen); - } + meta_screen_info_set_updates (info, get_xid (window), updates); #endif } @@ -1852,29 +1175,6 @@ blow_up (gpointer data) return TRUE; } -void -meta_compositor_delete_window (MetaCompositor *compositor, - MetaWindow *window, - MetaAnimationFinishedFunc finished, - gpointer data) -{ - CmDrawableNode *node; - BalloonInfo *info = g_new (BalloonInfo, 1); - - node = window_to_node (compositor, window); - - if (!node) - { - finished (data); - return; - } - - info->finished = finished; - info->finished_data = data; - info->timer = g_timer_new (); - g_idle_add (blow_up, info); -} - #endif void @@ -1890,8 +1190,6 @@ meta_compositor_destroy (MetaCompositor *compositor) ws_display_free (compositor->display); #endif - g_hash_table_destroy (compositor->window_hash); - g_free (compositor); #endif } @@ -1904,7 +1202,7 @@ struct MoveInfo gboolean finished; Model *model; MetaScreen *screen; - CmDrawableNode *node; + MetaWindow *window; gdouble last_time; }; @@ -1912,34 +1210,59 @@ struct MoveInfo #ifdef HAVE_COMPOSITE_EXTENSIONS +static void +get_patch_points (Model *model, + CmPoint points[4][4]) +{ + int i, j; + + for (i = 0; i < 4; i++) + { + for (j = 0; j < 4; j++) + { + double obj_x, obj_y; + + model_get_position (model, i, j, &obj_x, &obj_y); + + points[j][i].x = obj_x; + points[j][i].y = obj_y; + } + } +} + static gboolean wobble (gpointer data) { MoveInfo *info = data; + MetaScreenInfo *minfo = info->screen->compositor_data; double t = g_timer_elapsed (info->timer, NULL); if (info->finished && model_is_calm (info->model)) { - cm_drawable_node_unset_geometry (info->node); + meta_screen_info_unset_patch (minfo, get_xid (info->window)); g_free (info); info = NULL; + g_print ("stop wobb\n"); return FALSE; } else { int i; int n_steps; + CmPoint points[4][4]; n_steps = floor ((t - info->last_time) * 75); for (i = 0; i < n_steps; ++i) model_step (info->model); - + if (i > 0) info->last_time = t; - set_patch (info->node, info->model, 0.0, NULL); + get_patch_points (info->model, points); + meta_screen_info_set_patch (minfo, + get_xid (info->window), + points); - queue_repaint (info->node, info->screen); return TRUE; } } @@ -1970,6 +1293,8 @@ meta_compositor_begin_move (MetaCompositor *compositor, { #ifdef HAVE_COMPOSITE_EXTENSIONS MetaRectangle rect; + + g_print ("begin move\n"); compositor->move_info = g_new0 (MoveInfo, 1); @@ -1978,15 +1303,13 @@ meta_compositor_begin_move (MetaCompositor *compositor, compute_window_rect (window, &rect); -#if 0 g_print ("init: %d %d\n", initial->x, initial->y); g_print ("window: %d %d\n", window->rect.x, window->rect.y); g_print ("frame: %d %d\n", rect.x, rect.y); g_print ("grab: %d %d\n", grab_x, grab_y); -#endif compositor->move_info->model = model_new (&rect, TRUE); - compositor->move_info->node = window_to_node (window->display->compositor, window); + compositor->move_info->window = window; compositor->move_info->screen = window->screen; model_begin_move (compositor->move_info->model, grab_x, grab_y); diff --git a/src/compositor.h b/src/compositor.h index 1d731411a..13dbd26a6 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -55,15 +55,6 @@ void meta_compositor_minimize (MetaCompositor *compositor, gpointer finished_data); void -meta_compositor_unminimize (MetaCompositor *compositor, - MetaWindow *window, - int x, - int y, - int width, - int height, - MetaAnimationFinishedFunc finished, - gpointer data); -void meta_compositor_set_updates (MetaCompositor *compositor, MetaWindow *window, gboolean updates); diff --git a/src/display.c b/src/display.c index e1145a090..a4e5253bf 100644 --- a/src/display.c +++ b/src/display.c @@ -2142,7 +2142,7 @@ event_callback (XEvent *event, /* Handle screen resize */ { MetaScreen *screen; - + screen = meta_display_screen_for_root (display, event->xconfigure.window); diff --git a/src/errors.c b/src/errors.c index 7be2d3a77..f7e0bf274 100644 --- a/src/errors.c +++ b/src/errors.c @@ -37,6 +37,31 @@ meta_errors_init (void) XSetIOErrorHandler (x_io_error_handler); } +typedef struct ForeignDisplay ForeignDisplay; + +struct ForeignDisplay +{ + Display *dpy; + ErrorHandler handler; + gpointer data; + ForeignDisplay *next; +}; + +static ForeignDisplay *foreign_displays; + +void +meta_errors_register_foreign_display (Display *foreign_dpy, + ErrorHandler handler, + gpointer data) +{ + ForeignDisplay *info = g_new0 (ForeignDisplay, 1); + info->dpy = foreign_dpy; + info->handler = handler; + info->data = data; + info->next = foreign_displays; + foreign_displays = info; +} + static void meta_error_trap_push_internal (MetaDisplay *display, gboolean need_sync) @@ -178,6 +203,17 @@ x_error_handler (Display *xdisplay, int retval; gchar buf[64]; MetaDisplay *display; + ForeignDisplay *foreign; + + for (foreign = foreign_displays; foreign != NULL; foreign = foreign->next) + { + if (foreign->dpy == xdisplay) + { + foreign->handler (xdisplay, error, foreign->data); + + return 0; + } + } XGetErrorText (xdisplay, error->error_code, buf, 63); @@ -186,7 +222,7 @@ x_error_handler (Display *xdisplay, /* Display can be NULL here because the compositing manager * has its own Display, but Xlib only has one global error handler */ - if (display && display->error_traps > 0) + if (display->error_traps > 0) { /* we're in an error trap, chain to the trap handler * saved from GDK @@ -247,5 +283,3 @@ x_io_error_handler (Display *xdisplay) return 0; } - - diff --git a/src/errors.h b/src/errors.h index e7c8f389e..94cf603ac 100644 --- a/src/errors.h +++ b/src/errors.h @@ -25,7 +25,15 @@ #include "util.h" #include "display.h" +typedef void (* ErrorHandler) (Display *dpy, + XErrorEvent *error, + gpointer data); + void meta_errors_init (void); +void meta_errors_register_foreign_display (Display *foreign_dpy, + ErrorHandler handler, + gpointer data); + void meta_error_trap_push (MetaDisplay *display); void meta_error_trap_pop (MetaDisplay *display, gboolean last_request_was_roundtrip); diff --git a/src/screen.c b/src/screen.c index 54bd591d7..465ac2c63 100644 --- a/src/screen.c +++ b/src/screen.c @@ -815,6 +815,8 @@ meta_screen_composite_all_windows (MetaScreen *screen) if (!screen->display->compositor) return; + + g_print ("composite all asdf\n"); windows = list_windows (screen); @@ -824,12 +826,16 @@ meta_screen_composite_all_windows (MetaScreen *screen) { WindowInfo *info = list->data; + g_print ("composite all adds window\n"); + meta_compositor_add_window (screen->display->compositor, info->xwindow, &info->attrs); } meta_stack_thaw (screen->stack); + g_print ("composite all ends\n"); + g_list_foreach (windows, (GFunc)g_free, NULL); g_list_free (windows); } diff --git a/src/window.c b/src/window.c index eb10ef373..0ab682e86 100644 --- a/src/window.c +++ b/src/window.c @@ -1319,6 +1319,7 @@ finish_minimize (gpointer data) meta_window_hide (window); if (window->has_focus) { + g_print ("focusing something other than %lx\n", window->frame->xwindow); meta_workspace_focus_default_window (window->screen->active_workspace, window,