void test_realized (TestConformSimpleFixture *fixture, gconstpointer data) { ClutterActor *actor; ClutterActor *stage; stage = clutter_stage_get_default (); actor = clutter_rectangle_new (); g_assert (!(CLUTTER_ACTOR_IS_REALIZED (actor))); clutter_actor_hide (actor); /* don't show, so won't map */ clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor); clutter_actor_realize (actor); g_assert (CLUTTER_ACTOR_IS_REALIZED (actor)); g_assert (!(CLUTTER_ACTOR_IS_MAPPED (actor))); g_assert (!(CLUTTER_ACTOR_IS_VISIBLE (actor))); clutter_actor_destroy (actor); }
static void actor_realize_not_recursive (void) { ClutterActor *actor, *group; ClutterActor *stage; stage = clutter_test_get_stage (); clutter_actor_show (stage); group = clutter_actor_new (); actor = clutter_actor_new (); clutter_actor_hide (group); /* don't show, so won't map */ clutter_actor_hide (actor); /* don't show, so won't map */ g_assert (!(CLUTTER_ACTOR_IS_REALIZED (group))); g_assert (!(CLUTTER_ACTOR_IS_REALIZED (actor))); clutter_actor_add_child (stage, group); clutter_actor_add_child (group, actor); clutter_actor_realize (group); g_assert (CLUTTER_ACTOR_IS_REALIZED (group)); g_assert (!(CLUTTER_ACTOR_IS_MAPPED (group))); g_assert (!(CLUTTER_ACTOR_IS_VISIBLE (group))); /* realizing group did not realize the child */ g_assert (!CLUTTER_ACTOR_IS_REALIZED (actor)); g_assert (!(CLUTTER_ACTOR_IS_MAPPED (actor))); g_assert (!(CLUTTER_ACTOR_IS_VISIBLE (actor))); }
static void mpl_panel_clutter_ensure_window (MplPanelClutter *panel) { MplPanelClutterPrivate *priv = panel->priv; Window xwin = None; Display *xdpy; gint32 myint; Atom atom1, atom2; if (priv->xwindow) return; xdpy = clutter_x11_get_default_display (); clutter_actor_realize (priv->stage); priv->xwindow = xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (priv->stage)); g_object_set (panel, "xid", xwin, NULL); if (priv->needs_gdk_pump) mpl_panel_clutter_setup_events_with_gtk_for_xid (xwin); if (!mpl_utils_panel_in_standalone_mode ()) { MPL_X_ERROR_TRAP (); /* * Make dock, sticky and position at the correct place. */ atom1 = XInternAtom(xdpy, "_NET_WM_WINDOW_TYPE", False); atom2 = XInternAtom(xdpy, "_NET_WM_WINDOW_TYPE_DOCK", False); XChangeProperty (xdpy, xwin, atom1, XA_ATOM, 32, PropModeReplace, (unsigned char *) &atom2, 1); atom1 = XInternAtom(xdpy, "_NET_WM_DESKTOP", False); myint = -1; XChangeProperty (xdpy, xwin, atom1, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &myint, 1); XSync (xdpy, False); MPL_X_ERROR_UNTRAP (); } }
static void tweet_overlay_realize (ClutterActor *actor) { TweetOverlayPrivate *priv = TWEET_OVERLAY (actor)->priv; if (G_LIKELY (priv->base)) clutter_actor_realize (priv->base); g_list_foreach (priv->children, (GFunc) clutter_actor_realize, NULL); }
/** * clutter_win32_set_stage_foreign: * @stage: a #ClutterStage * @hwnd: an existing window handle * * Target the #ClutterStage to use an existing external window handle. * * Return value: %TRUE if foreign window is valid * * Since: 0.8 */ gboolean clutter_win32_set_stage_foreign (ClutterStage *stage, HWND hwnd) { ClutterStageWin32 *stage_win32; ClutterStageWindow *impl; ClutterActor *actor; RECT client_rect; POINT window_pos; ClutterGeometry geom; g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE); g_return_val_if_fail (hwnd != NULL, FALSE); actor = CLUTTER_ACTOR (stage); impl = _clutter_stage_get_window (stage); stage_win32 = CLUTTER_STAGE_WIN32 (impl); /* FIXME this needs updating to use _clutter_actor_rerealize(), * see the analogous code in x11 backend. Probably best if * win32 maintainer does it so they can be sure it compiles * and works. */ clutter_actor_unrealize (actor); if (!GetClientRect (hwnd, &client_rect)) { g_warning ("Unable to retrieve the new window geometry"); return FALSE; } window_pos.x = client_rect.left; window_pos.y = client_rect.right; ClientToScreen (hwnd, &window_pos); CLUTTER_NOTE (BACKEND, "Setting foreign window (0x%x)", (int) hwnd); stage_win32->hwnd = hwnd; stage_win32->is_foreign_win = TRUE; geom.x = 0; geom.y = 0; geom.width = client_rect.right - client_rect.left; geom.height = client_rect.bottom - client_rect.top; clutter_actor_set_geometry (actor, &geom); clutter_actor_realize (actor); return TRUE; }
static void clutter_reflect_texture_paint (ClutterActor *self) { ClutterReflectTexturePrivate *priv; ClutterActor *parent_texture; gint x1, y1, x2, y2; GLenum target_type; priv = CLUTTER_REFLECT_TEXTURE (self)->priv; /* no need to paint stuff if we don't have a texture to reflect */ if (!clutter_clone_texture_get_parent_texture(CLUTTER_CLONE_TEXTURE(self))) return; /* parent texture may have been hidden, there for need to make sure its * realised with resources available. */ parent_texture = CLUTTER_ACTOR (clutter_clone_texture_get_parent_texture(CLUTTER_CLONE_TEXTURE(self))); if (!CLUTTER_ACTOR_IS_REALIZED (parent_texture)) clutter_actor_realize (parent_texture); /* FIXME: figure out nicer way of getting at this info... */ if (clutter_feature_available (CLUTTER_FEATURE_TEXTURE_RECTANGLE) && clutter_texture_is_tiled (CLUTTER_TEXTURE (parent_texture)) == FALSE) { target_type = CGL_TEXTURE_RECTANGLE_ARB; cogl_enable (CGL_ENABLE_TEXTURE_RECT | CGL_ENABLE_BLEND); } else { target_type = CGL_TEXTURE_2D; cogl_enable (CGL_ENABLE_TEXTURE_2D|CGL_ENABLE_BLEND); } cogl_push_matrix (); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4ub (255, 255, 255, clutter_actor_get_opacity (self)); clutter_actor_get_coords (self, &x1, &y1, &x2, &y2); /* Parent paint translated us into position */ reflect_texture_render_to_gl_quad (CLUTTER_REFLECT_TEXTURE (self), 0, 0, x2 - x1, y2 - y1); cogl_pop_matrix (); }
static gboolean handle_xembed_event (ClutterBackendX11 *backend_x11, XEvent *xevent) { ClutterActor *stage; stage = clutter_stage_get_default (); switch (xevent->xclient.data.l[1]) { case XEMBED_EMBEDDED_NOTIFY: CLUTTER_NOTE (EVENT, "got XEMBED_EMBEDDED_NOTIFY from %lx", xevent->xclient.data.l[3]); ParentEmbedderWin = xevent->xclient.data.l[3]; clutter_actor_realize (stage); clutter_actor_show (stage); xembed_set_info (backend_x11, clutter_x11_get_stage_window (CLUTTER_STAGE (stage)), XEMBED_MAPPED); break; case XEMBED_WINDOW_ACTIVATE: CLUTTER_NOTE (EVENT, "got XEMBED_WINDOW_ACTIVATE"); break; case XEMBED_WINDOW_DEACTIVATE: CLUTTER_NOTE (EVENT, "got XEMBED_WINDOW_DEACTIVATE"); break; case XEMBED_FOCUS_IN: CLUTTER_NOTE (EVENT, "got XEMBED_FOCUS_IN"); if (ParentEmbedderWin) xembed_send_message (backend_x11, ParentEmbedderWin, XEMBED_FOCUS_NEXT, 0, 0, 0); break; default: CLUTTER_NOTE (EVENT, "got unknown XEMBED message"); break; } /* do not propagate the XEMBED events to the stage */ return FALSE; }
static void setup_standalone (DawatiStatusPanel *status_panel) { ClutterActor *stage, *status; Window xwin; status = make_status (status_panel); clutter_actor_set_size (status, 1000, 600); stage = clutter_stage_new (); clutter_actor_set_size (stage, 1000, 600); clutter_container_add_actor (CLUTTER_CONTAINER (stage), status); clutter_actor_realize (stage); xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (stage)); mpl_panel_clutter_setup_events_with_gtk_for_xid (xwin); clutter_actor_show (stage); }
static void actor_realized (void) { ClutterActor *actor; ClutterActor *stage; stage = clutter_test_get_stage (); actor = clutter_actor_new (); g_assert (!(CLUTTER_ACTOR_IS_REALIZED (actor))); clutter_actor_hide (actor); /* don't show, so won't map */ clutter_actor_add_child (stage, actor); clutter_actor_realize (actor); g_assert (CLUTTER_ACTOR_IS_REALIZED (actor)); g_assert (!(CLUTTER_ACTOR_IS_MAPPED (actor))); g_assert (!(CLUTTER_ACTOR_IS_VISIBLE (actor))); }
void test_realize_not_recursive (TestConformSimpleFixture *fixture, gconstpointer data) { ClutterActor *actor, *group; ClutterActor *stage; stage = clutter_stage_get_default (); group = clutter_group_new (); actor = clutter_rectangle_new (); clutter_actor_hide (group); /* don't show, so won't map */ clutter_actor_hide (actor); /* don't show, so won't map */ g_assert (!(CLUTTER_ACTOR_IS_REALIZED (group))); g_assert (!(CLUTTER_ACTOR_IS_REALIZED (actor))); clutter_container_add_actor (CLUTTER_CONTAINER (stage), group); clutter_container_add_actor (CLUTTER_CONTAINER (group), actor); clutter_actor_realize (group); g_assert (CLUTTER_ACTOR_IS_REALIZED (group)); g_assert (!(CLUTTER_ACTOR_IS_MAPPED (group))); g_assert (!(CLUTTER_ACTOR_IS_VISIBLE (group))); /* realizing group did not realize the child */ g_assert (!CLUTTER_ACTOR_IS_REALIZED (actor)); g_assert (!(CLUTTER_ACTOR_IS_MAPPED (actor))); g_assert (!(CLUTTER_ACTOR_IS_VISIBLE (actor))); clutter_actor_destroy (group); }
int main (int argc, char **argv) { GtkWidget *window, *embed, *vbox, *menubar, *vpaned, *textpanel; ClutterActor *stage, *grid_view; setlocale (LC_ALL, ""); bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); g_thread_init (NULL); profile_timer = g_timer_new (); clutter_init (&argc, &argv); gtk_init(&argc, &argv); g_set_application_name("GNOME Social Zone"); mx_style_load_from_file (mx_style_get_default (), THEMEDIR "/panel.css", NULL); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), _("GNOME Social Zone")); gtk_window_set_icon_name (GTK_WINDOW (window), "gnome-social-zone"); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(window), vbox); menubar = get_menubar_menu (GTK_WIDGET(window)); vpaned = gtk_vpaned_new (); gtk_box_pack_start(GTK_BOX (vbox), menubar, FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX (vbox), vpaned, TRUE, TRUE, 0); embed = gtk_clutter_embed_new (); gtk_paned_pack1 (GTK_PANED (vpaned), GTK_WIDGET(embed), FALSE, FALSE); textpanel = get_text_panel(); gtk_paned_pack2 (GTK_PANED (vpaned), textpanel, TRUE, TRUE); stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (embed)); clutter_actor_realize (stage); grid_view = g_object_new (PENGE_TYPE_GRID_VIEW, NULL); clutter_container_add_actor (CLUTTER_CONTAINER (stage), (ClutterActor *)grid_view); clutter_actor_set_size ((ClutterActor *)grid_view, 1016, 536); gtk_widget_set_size_request (embed, 1016, 536); clutter_actor_show_all (stage); gtk_widget_show_all (GTK_WIDGET(window)); g_signal_connect_after (stage, "paint", (GCallback)_stage_paint_cb, NULL); g_message (G_STRLOC ": PROFILE: Main loop started: %f", g_timer_elapsed (profile_timer, NULL)); gtk_main(); return 0; }
IO_METHOD(IoClutterActor, realize) { clutter_actor_realize(IOCACTOR(self)); return self; }
int main (int argc, char *argv[]) { ClutterActor *video; GdkPixbuf *shot = NULL; gint duration; CoglHandle tex_id; CoglPixelFormat format; gint size; gint width; gint height; gint rowstride; guchar *data = NULL; #ifdef USE_HELIX clutter_helix_init (&argc, &argv); #else gst_init (&argc, &argv); #endif clutter_init (&argc, &argv); if (argc < 3) { g_print ("Usage: %s <path to movie file> <output png>\n", argv[0]); exit(-1); } totem_resources_monitor_start (argv[1], 60 * G_USEC_PER_SEC); #ifdef USE_HELIX video = clutter_helix_video_texture_new (); #else video = clutter_gst_video_texture_new (); #endif if (argv[1][0] == '/') clutter_media_set_filename(CLUTTER_MEDIA(video), argv[1]); else clutter_media_set_uri(CLUTTER_MEDIA(video), argv[1]); clutter_media_set_volume (CLUTTER_MEDIA(video), 0); clutter_media_set_playing (CLUTTER_MEDIA(video), TRUE); do { while (g_main_context_pending (NULL)) g_main_context_iteration (NULL, FALSE); duration = clutter_media_get_duration (CLUTTER_MEDIA(video)); } while (duration == 0); clutter_actor_realize (video); clutter_media_set_position (CLUTTER_MEDIA(video), duration/3); do { while (g_main_context_pending (NULL)) g_main_context_iteration (NULL, FALSE); } while (clutter_media_get_position (CLUTTER_MEDIA(video)) <= duration/3); tex_id = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (video)); if (tex_id) { format = cogl_texture_get_format (tex_id); size = cogl_texture_get_data (tex_id, format, 0, NULL); width = cogl_texture_get_width (tex_id); height = cogl_texture_get_height (tex_id); rowstride = cogl_texture_get_rowstride (tex_id); data = (guchar*) g_malloc (sizeof(guchar) * size); if (!data) g_error ("malloc");; cogl_texture_get_data (tex_id, format, rowstride, data); shot = gdk_pixbuf_new_from_data (data, GDK_COLORSPACE_RGB, FALSE, 8, width, height, rowstride, NULL, NULL); } totem_resources_monitor_stop (); if (shot) { GdkPixbuf *thumb, *pic; gint x, y, nw, nh, w, h, size; size = 128; /* FIXME swap RGB pixels */ w = clutter_actor_get_width (video); h = clutter_actor_get_height (video); nh = ( h * size) / w; if (nh <= size) { nw = size; x = 0; y = (size - nh) / 2; } else { nw = ( w * size ) / h; nh = size; x = (size - nw) / 2; y = 0; } thumb = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, size, size); gdk_pixbuf_fill (thumb, 0x000000FF); pic = gdk_pixbuf_scale_simple (shot, nw, nh, GDK_INTERP_BILINEAR); gdk_pixbuf_copy_area (pic, 0, 0, nw, nh, thumb, x, y); if (!gdk_pixbuf_save (thumb, argv[2], "png", NULL, NULL)) { g_error ("%s: Pixbuf save failed\n", argv[0]); exit(-1); } g_object_unref (shot); g_object_unref (thumb); g_object_unref (pic); exit(0); } exit (-1); }
static void reflect_texture_render_to_gl_quad (ClutterReflectTexture *ctexture, int x1, int y1, int x2, int y2) { gint qx1 = 0, qx2 = 0, qy1 = 0, qy2 = 0; gint qwidth = 0, qheight = 0; gint x, y, i =0, lastx = 0, lasty = 0; gint n_x_tiles, n_y_tiles; gint pwidth, pheight, rheight; float tx, ty, ty2 = 0.0; ClutterReflectTexturePrivate *priv = ctexture->priv; ClutterActor *parent_texture = CLUTTER_ACTOR(clutter_clone_texture_get_parent_texture(CLUTTER_CLONE_TEXTURE(ctexture))); priv = ctexture->priv; qwidth = x2 - x1; qheight = y2 - y1; rheight = priv->reflection_height; if (rheight > qheight) rheight = qheight; if (!CLUTTER_ACTOR_IS_REALIZED (parent_texture)) clutter_actor_realize (parent_texture); /* Only paint if parent is in a state to do so */ if (!clutter_texture_has_generated_tiles (CLUTTER_TEXTURE(parent_texture))) return; clutter_texture_get_base_size (CLUTTER_TEXTURE(parent_texture), &pwidth, &pheight); if (!clutter_texture_is_tiled (CLUTTER_TEXTURE(parent_texture))) { clutter_texture_bind_tile (CLUTTER_TEXTURE(parent_texture), 0); /* NPOTS textures *always* used if extension available */ if (clutter_feature_available (CLUTTER_FEATURE_TEXTURE_RECTANGLE)) { tx = (float) pwidth; ty = (float) pheight; ty2 = (float)(clutter_actor_get_height (CLUTTER_ACTOR(ctexture)) * rheight) / pheight; ty2 = pheight - ty2; } else { tx = (float) pwidth / clutter_util_next_p2 (pwidth); ty = (float) pheight / clutter_util_next_p2 (pheight); } qx1 = x1; qx2 = x2; qy1 = y1; qy2 = y1 + rheight; glBegin (GL_QUADS); glColor4ub (255, 255, 255, clutter_actor_get_opacity (CLUTTER_ACTOR(ctexture))); glTexCoord2f (0, ty); glVertex2i (qx1, qy1); glTexCoord2f (tx, ty); glVertex2i (qx2, qy1); glColor4ub (255, 255, 255, 0); glTexCoord2f (tx, ty2); glVertex2i (qx2, qy2); glTexCoord2f (0, ty2); glVertex2i (qx1, qy2); glEnd (); return; } clutter_texture_get_n_tiles (CLUTTER_TEXTURE(parent_texture), &n_x_tiles, &n_y_tiles); for (x = 0; x < n_x_tiles; x++) { lasty = 0; for (y = 0; y < n_y_tiles; y++) { gint actual_w, actual_h; gint xpos, ypos, xsize, ysize, ywaste, xwaste; clutter_texture_bind_tile (CLUTTER_TEXTURE(parent_texture), i); clutter_texture_get_x_tile_detail (CLUTTER_TEXTURE(parent_texture), x, &xpos, &xsize, &xwaste); clutter_texture_get_y_tile_detail (CLUTTER_TEXTURE(parent_texture), y, &ypos, &ysize, &ywaste); actual_w = xsize - xwaste; actual_h = ysize - ywaste; tx = (float) actual_w / xsize; ty = (float) actual_h / ysize; qx1 = x1 + lastx; qx2 = qx1 + ((qwidth * actual_w ) / pwidth ); qy1 = y1 + lasty; qy2 = qy1 + ((qheight * actual_h) / pheight ); glBegin (GL_QUADS); glTexCoord2f (tx, ty); glVertex2i (qx2, qy2); glTexCoord2f (0, ty); glVertex2i (qx1, qy2); glTexCoord2f (0, 0); glVertex2i (qx1, qy1); glTexCoord2f (tx, 0); glVertex2i (qx2, qy1); glEnd (); lasty += qy2 - qy1; i++; } lastx += qx2 - qx1; } }
static void clutter_reflect_texture_paint (ClutterActor *actor) { ClutterReflectTexturePrivate *priv; ClutterReflectTexture *texture; ClutterClone *clone; ClutterTexture *parent; guint width, height; gfloat fwidth, fheight; gint r_height; gint opacity; gint bottom; CoglHandle cogl_texture; CoglTextureVertex tvert[4]; CoglFixed rty; texture = CLUTTER_REFLECT_TEXTURE (actor); clone = CLUTTER_CLONE (actor); parent = (ClutterTexture*) clutter_clone_get_source (clone); if (!parent) return; if (!CLUTTER_ACTOR_IS_REALIZED (parent)) clutter_actor_realize (CLUTTER_ACTOR (parent)); cogl_texture = clutter_texture_get_cogl_texture (parent); if (cogl_texture == COGL_INVALID_HANDLE) return; priv = texture->priv; clutter_actor_get_size (CLUTTER_ACTOR(parent), &fwidth, &fheight); width = fwidth; height = fheight; if (!height) // probably won't happen, but just in case, to avoid divide by zero. return; r_height = priv->reflection_height; bottom = priv->reflect_bottom; opacity = clutter_actor_get_opacity(actor); if (r_height < 0 || r_height > height) r_height = height; #define FX(x) COGL_FIXED_FROM_INT(x) rty = COGL_FIXED_FAST_DIV(FX(bottom ? height-r_height : r_height),FX(height)); /* clockise vertices and tex coords and colors! */ tvert[0].x = tvert[0].y = tvert[0].z = 0; tvert[0].tx = 0; tvert[0].ty = bottom ? COGL_FIXED_1 : rty; tvert[0].color.red = tvert[0].color.green = tvert[0].color.blue = 0xff; tvert[0].color.alpha = bottom ? opacity : 0; tvert[1].x = FX(width); tvert[1].y = tvert[1].z = 0; tvert[1].tx = COGL_FIXED_1; tvert[1].ty = bottom ? COGL_FIXED_1 : rty; tvert[1].color.red = tvert[1].color.green = tvert[1].color.blue = 0xff; tvert[1].color.alpha = bottom ? opacity : 0; tvert[2].x = FX(width); tvert[2].y = FX(r_height); tvert[2].z = 0; tvert[2].tx = COGL_FIXED_1; tvert[2].ty = bottom ? rty : 0; tvert[2].color.red = tvert[2].color.green = tvert[2].color.blue = 0xff; tvert[2].color.alpha = bottom ? 0 : opacity; tvert[3].x = 0; tvert[3].y = FX(r_height); tvert[3].z = 0; tvert[3].tx = 0; tvert[3].ty = bottom ? rty : 0; tvert[3].color.red = tvert[3].color.green = tvert[3].color.blue = 0xff; tvert[3].color.alpha = bottom ? 0 : opacity; cogl_push_matrix (); cogl_set_source_texture(cogl_texture); /* FIXME: this does not work as expected */ /* cogl_polygon(tvert, 4, TRUE); */ cogl_pop_matrix (); }
static void mnb_toolbar_shadow_paint (ClutterActor *self) { MnbToolbarShadowPrivate *priv = MNB_TOOLBAR_SHADOW (self)->priv; CoglHandle cogl_texture = COGL_INVALID_HANDLE; CoglHandle cogl_material = COGL_INVALID_HANDLE; ClutterActorBox box = { 0, }; gfloat width, height; gfloat tex_width, tex_height; gfloat ex, ey; gfloat tx1, ty1, tx2, ty2; guint8 opacity; /* no need to paint stuff if we don't have a texture */ if (G_UNLIKELY (priv->parent_texture == NULL)) return; /* parent texture may have been hidden, so need to make sure it gets * realized */ if (!CLUTTER_ACTOR_IS_REALIZED (priv->parent_texture)) clutter_actor_realize (CLUTTER_ACTOR (priv->parent_texture)); cogl_texture = clutter_texture_get_cogl_texture (priv->parent_texture); if (cogl_texture == COGL_INVALID_HANDLE) return; cogl_material = clutter_texture_get_cogl_material (priv->parent_texture); if (cogl_material == COGL_INVALID_HANDLE) return; tex_width = cogl_texture_get_width (cogl_texture); tex_height = cogl_texture_get_height (cogl_texture); clutter_actor_get_allocation_box (self, &box); width = box.x2 - box.x1; height = box.y2 - box.y1; opacity = clutter_actor_get_paint_opacity (self); /* Paint using the parent texture's material. It should already have the cogl texture set as the first layer */ /* NB: for correct blending we need set a preumultiplied color here: */ cogl_material_set_color4ub (cogl_material, opacity, opacity, opacity, opacity); #if TOOLBAR_CUT_OUT selector_texture = mnb_toolbar_get_selector_texture (priv->toolbar); cogl_material_set_layer (cogl_material, 1, selector_texture); cogl_material_set_layer_wrap_mode (cogl_material, 1, COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE); if (!cogl_material_set_layer_combine (cogl_material, 1, "RGBA = MODULATE(PREVIOUS,TEXTURE)", &error)) { g_warning (G_STRLOC ": Error setting layer combine blend string: %s", error->message); g_error_free (error); } #endif cogl_set_source (cogl_material); /* simple stretch */ if (priv->left == 0 && priv->right == 0 && priv->top == 0 && priv->bottom == 0) { #if TOOLBAR_CUT_OUT float spot_width, spot_height; float coords[8] = { 0, 0, 1, 1, 0, 0, 0, 0 }; mnb_toolbar_get_selector_allocation_box (priv->toolbar, &box); spot_width = box.x2 - box.x1; spot_height = box.y2 - box.y1; coords[4] = -(box.x1 / width) * (width / spot_width); coords[5] = -(box.y1 + SHADOW_CUT_OUT_OFFSET / height) * (height / spot_height); coords[6] = width / spot_width - (box.x1 / width) * (width / spot_width); coords[7] = height / spot_height - (box.y1 + SHADOW_CUT_OUT_OFFSET / height) * (height / spot_height); cogl_rectangle_with_multitexture_coords (0, 0, width, height, coords, 8); #else cogl_rectangle (0, 0, width, height); #endif /* TOOLBAR_CUT_OUT */ return; } tx1 = priv->left / tex_width; tx2 = (tex_width - priv->right) / tex_width; ty1 = priv->top / tex_height; ty2 = (tex_height - priv->bottom) / tex_height; ex = width - priv->right; if (ex < priv->left) ex = priv->left; ey = height - priv->bottom; if (ey < priv->top) ey = priv->top; { GLfloat rectangles[] = { /* top left corner */ 0, 0, priv->left, priv->top, 0.0, 0.0, tx1, ty1, /* top middle */ priv->left, 0, MAX (priv->left, ex), priv->top, tx1, 0.0, tx2, ty1, /* top right */ ex, 0, MAX (ex + priv->right, width), priv->top, tx2, 0.0, 1.0, ty1, /* mid left */ 0, priv->top, priv->left, ey, 0.0, ty1, tx1, ty2, /* center */ priv->left, priv->top, ex, ey, tx1, ty1, tx2, ty2, /* mid right */ ex, priv->top, MAX (ex + priv->right, width), ey, tx2, ty1, 1.0, ty2, /* bottom left */ 0, ey, priv->left, MAX (ey + priv->bottom, height), 0.0, ty2, tx1, 1.0, /* bottom center */ priv->left, ey, ex, MAX (ey + priv->bottom, height), tx1, ty2, tx2, 1.0, /* bottom right */ ex, ey, MAX (ex + priv->right, width), MAX (ey + priv->bottom, height), tx2, ty2, 1.0, 1.0 }; cogl_rectangles_with_texture_coords (rectangles, 9); } }
/* * Paints the provided texture frame trimming to the area indicated by padding. * * (Basically, we have one asset that gets split into two parts: an border area * that matches the padding, and the inside; MplPanelBackground paints the * latter, while the border is painted by the compositor as the window shadow.) */ static void mpl_panel_background_paint_border_image (CoglHandle *frame, MxPadding *padding) { CoglHandle cogl_texture = COGL_INVALID_HANDLE; CoglHandle cogl_material = COGL_INVALID_HANDLE; ClutterActorBox box = { 0, }; gfloat width, height; gfloat tex_width, tex_height; gfloat ex, ey; gfloat tx1, ty1, tx2, ty2; gfloat left = 4, right = 4 , top = 4, bottom =4; guint8 opacity; ClutterTexture *parent_texture; gfloat margin_l, margin_r, margin_t, margin_b; parent_texture = mx_texture_frame_get_parent_texture (frame); mx_texture_frame_get_border_values (frame, &top, &right, &bottom, &left); /* no need to paint stuff if we don't have a texture */ if (G_UNLIKELY (parent_texture == NULL)) return; /* parent texture may have been hidden, so need to make sure it gets * realized */ if (!CLUTTER_ACTOR_IS_REALIZED (parent_texture)) clutter_actor_realize (CLUTTER_ACTOR (parent_texture)); cogl_texture = clutter_texture_get_cogl_texture (parent_texture); if (cogl_texture == COGL_INVALID_HANDLE) return; cogl_material = clutter_texture_get_cogl_material (parent_texture); if (cogl_material == COGL_INVALID_HANDLE) return; tex_width = cogl_texture_get_width (cogl_texture); tex_height = cogl_texture_get_height (cogl_texture); clutter_actor_get_allocation_box ((ClutterActor*) frame, &box); width = box.x2 - box.x1; height = box.y2 - box.y1; /* * These are the margins we are to trim expressed in texture coordinates. */ margin_l = padding->left / tex_width; margin_r = padding->right / tex_width; margin_t = padding->top / tex_height; margin_b = padding->bottom / tex_height; tx1 = left / tex_width; tx2 = (tex_width - right) / tex_width; ty1 = top / tex_height; ty2 = (tex_height - bottom) / tex_height; ex = width - right; if (ex < 0) ex = right; ey = height - bottom; if (ey < 0) ey = bottom; opacity = clutter_actor_get_paint_opacity ((ClutterActor*)frame); cogl_material_set_color4ub (cogl_material, opacity, opacity, opacity, opacity); cogl_set_source (cogl_material); cogl_material_set_layer_filters (cogl_material, 0, COGL_MATERIAL_FILTER_NEAREST, COGL_MATERIAL_FILTER_NEAREST); { GLfloat rectangles[] = { /* top left corner */ 0.0, 0.0, left, top, margin_l, margin_t, tx1, ty1, /* top middle */ left, 0.0, ex, top, tx1, margin_t, tx2, ty1, /* top right */ ex, 0.0, width, top, tx2, margin_t, 1.0 - margin_r, ty1, /* mid left */ 0.0, top, left, ey, margin_l, ty1, tx1, ty2, /* center */ left, top, ex, ey, tx1, ty1, tx2, ty2, /* mid right */ ex, top, width, ey, tx2, ty1, 1.0 - margin_r, ty2, /* bottom left */ 0.0, ey, left, height, margin_l, ty2, tx1, 1.0 - margin_b, /* bottom center */ left, ey, ex, height, tx1, ty2, tx2, 1.0 - margin_b, /* bottom right */ ex, ey, width, height, tx2, ty2, 1.0 - margin_r, 1.0 - margin_b }; cogl_rectangles_with_texture_coords (rectangles, 9); } }
void meta_compositor_manage (MetaCompositor *compositor) { MetaDisplay *display = compositor->display; Display *xdisplay = display->xdisplay; MetaScreen *screen = display->screen; Window xwin = 0; gint width, height; meta_screen_set_cm_selection (display->screen); if (meta_is_wayland_compositor ()) { MetaWaylandCompositor *wayland_compositor = meta_wayland_compositor_get_default (); compositor->stage = meta_stage_new (); wayland_compositor->stage = compositor->stage; meta_screen_get_size (screen, &width, &height); clutter_actor_set_size (compositor->stage, width, height); clutter_actor_show (compositor->stage); } else { compositor->stage = clutter_stage_new (); meta_screen_get_size (screen, &width, &height); clutter_actor_realize (compositor->stage); xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (compositor->stage)); XResizeWindow (xdisplay, xwin, width, height); { MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ()); Display *backend_xdisplay = meta_backend_x11_get_xdisplay (backend); unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; XISetMask (mask.mask, XI_KeyPress); XISetMask (mask.mask, XI_KeyRelease); XISetMask (mask.mask, XI_ButtonPress); XISetMask (mask.mask, XI_ButtonRelease); XISetMask (mask.mask, XI_Enter); XISetMask (mask.mask, XI_Leave); XISetMask (mask.mask, XI_FocusIn); XISetMask (mask.mask, XI_FocusOut); XISetMask (mask.mask, XI_Motion); XIClearMask (mask.mask, XI_TouchBegin); XIClearMask (mask.mask, XI_TouchEnd); XIClearMask (mask.mask, XI_TouchUpdate); XISelectEvents (backend_xdisplay, xwin, &mask, 1); } } /* We use connect_after() here to accomodate code in GNOME Shell that, * when benchmarking drawing performance, connects to ::after-paint * and calls glFinish(). The timing information from that will be * more accurate if we hold off until that completes before we signal * apps to begin drawing the next frame. If there are no other * connections to ::after-paint, connect() vs. connect_after() doesn't * matter. */ g_signal_connect_after (CLUTTER_STAGE (compositor->stage), "after-paint", G_CALLBACK (after_stage_paint), compositor); clutter_stage_set_sync_delay (CLUTTER_STAGE (compositor->stage), META_SYNC_DELAY); compositor->window_group = meta_window_group_new (screen); compositor->top_window_group = meta_window_group_new (screen); clutter_actor_add_child (compositor->stage, compositor->window_group); clutter_actor_add_child (compositor->stage, compositor->top_window_group); if (meta_is_wayland_compositor ()) { /* NB: When running as a wayland compositor we don't need an X * composite overlay window, and we don't need to play any input * region tricks to redirect events into clutter. */ compositor->output = None; } else { compositor->output = screen->composite_overlay_window; XReparentWindow (xdisplay, xwin, compositor->output, 0, 0); meta_empty_stage_input_region (screen); /* Make sure there isn't any left-over output shape on the * overlay window by setting the whole screen to be an * output region. * * Note: there doesn't seem to be any real chance of that * because the X server will destroy the overlay window * when the last client using it exits. */ XFixesSetWindowShapeRegion (xdisplay, compositor->output, ShapeBounding, 0, 0, None); /* Map overlay window before redirecting windows offscreen so we catch their * contents until we show the stage. */ XMapWindow (xdisplay, compositor->output); } redirect_windows (display->screen); compositor->plugin_mgr = meta_plugin_manager_new (compositor); }
int main (int argc, char *argv[]) { ClutterActor *video; /* So we can fade out at the end. */ clutter_x11_set_use_argb_visual (TRUE); if (clutter_gst_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) return EXIT_FAILURE; if (argc < 2) { g_print ("Usage: %s [OPTIONS] <video file>\n", argv[0]); return EXIT_FAILURE; } if (!clutter_color_from_string (&bg_color, BG_COLOR)) { g_warning ("Invalid BG_COLOR"); exit (1); } stage = clutter_stage_new (); /* Clutter's full-screening code does not allow us to * set both that and _NET_WM_STATE_ABOVE, so do the state * management ourselves for now. */ #if 0 clutter_stage_set_fullscreen (CLUTTER_STAGE (stage), TRUE); #endif /* Clutter will set maximum size restrictions (meaning not * full screen) unless I set this. */ clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); clutter_stage_set_use_alpha (CLUTTER_STAGE (stage), TRUE); clutter_actor_set_background_color (stage, &bg_color); clutter_actor_set_layout_manager (stage, clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_FIXED, CLUTTER_BIN_ALIGNMENT_FIXED)); clutter_actor_realize (stage); set_above_and_fullscreen (); video = clutter_gst_video_texture_new (); clutter_actor_set_x_expand (video, TRUE); clutter_actor_set_y_expand (video, TRUE); clutter_actor_set_x_align (video, CLUTTER_ACTOR_ALIGN_CENTER); clutter_actor_set_y_align (video, CLUTTER_ACTOR_ALIGN_CENTER); set_idle_material (CLUTTER_GST_VIDEO_TEXTURE (video)); g_signal_connect (video, "eos", G_CALLBACK (on_video_texture_eos), NULL); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); clutter_media_set_filename (CLUTTER_MEDIA (video), argv[1]); clutter_stage_hide_cursor (CLUTTER_STAGE (stage)); clutter_actor_add_child (stage, video); g_signal_connect (stage, "key-press-event", G_CALLBACK (key_press_cb), NULL); clutter_media_set_playing (CLUTTER_MEDIA (video), TRUE); clutter_actor_show (stage); clutter_main (); return EXIT_SUCCESS; }
static void clutter_x11_texture_pixmap_paint (ClutterActor *self) { ClutterX11TexturePixmap *texture = CLUTTER_X11_TEXTURE_PIXMAP (self); ClutterX11TexturePixmapPrivate *priv = texture->priv; gint x_1, y_1, x_2, y_2; ClutterColor col = { 0xff, 0xff, 0xff, 0xff }; ClutterFixed t_w, t_h; GList *shape; CoglHandle cogl_texture; g_return_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture)); /* If we have no shapes, just call what we had before */ if (priv->shapes==0) { CLUTTER_ACTOR_CLASS(clutter_x11_texture_pixmap_parent_class)->paint(self); return; } if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR(texture))) clutter_actor_realize (CLUTTER_ACTOR(texture)); CLUTTER_NOTE (PAINT, "painting X11 texture '%s'", clutter_actor_get_name (self) ? clutter_actor_get_name (self) : "unknown"); col.alpha = clutter_actor_get_paint_opacity (self); cogl_color (&col); clutter_actor_get_allocation_coords (self, &x_1, &y_1, &x_2, &y_2); CLUTTER_NOTE (PAINT, "paint to x1: %i, y1: %i x2: %i, y2: %i " "opacity: %i", x_1, y_1, x_2, y_2, clutter_actor_get_opacity (self)); t_w = CFX_ONE; t_h = CFX_ONE; cogl_texture = clutter_texture_get_cogl_texture(CLUTTER_TEXTURE(self)); if (cogl_texture == COGL_INVALID_HANDLE) return; /* so now we go through our shapes and render */ for (shape = priv->shapes; shape; shape = shape->next) { gint w = x_2 - x_1; gint h = y_2 - y_1; ClutterGeometry *geo = (ClutterGeometry*)shape->data; cogl_texture_rectangle ( cogl_texture, CLUTTER_INT_TO_FIXED(w * geo->x / priv->pixmap_width), CLUTTER_INT_TO_FIXED(h * geo->y / priv->pixmap_height), CLUTTER_INT_TO_FIXED(w * (geo->x+geo->width) / priv->pixmap_width), CLUTTER_INT_TO_FIXED(h * (geo->y+geo->height) / priv->pixmap_height), t_w * geo->x / priv->pixmap_width, t_h * geo->y / priv->pixmap_height, t_w * (geo->x+geo->width) / priv->pixmap_width, t_h * (geo->y+geo->height) / priv->pixmap_height); } }
static void clutter_glx_texture_pixmap_create_glx_pixmap (ClutterGLXTexturePixmap *texture) { ClutterGLXTexturePixmapPrivate *priv = texture->priv; GLXPixmap glx_pixmap = None; int attribs[7], i = 0, mipmap = 0; GLXFBConfig *fbconfig; Display *dpy; guint depth; Pixmap pixmap; guint pixmap_width, pixmap_height; ClutterBackendGLX *backend_glx; ClutterTextureQuality quality; CLUTTER_NOTE (TEXTURE, "Creating GLXPixmap"); backend_glx = CLUTTER_BACKEND_GLX(clutter_get_default_backend ()); dpy = clutter_x11_get_default_display (); if (priv->use_fallback == TRUE || !clutter_glx_texture_pixmap_using_extension (texture)) goto cleanup; priv->use_fallback = FALSE; g_object_get (texture, "pixmap-width", &pixmap_width, "pixmap-height", &pixmap_height, "pixmap-depth", &depth, "pixmap", &pixmap, NULL); if (!pixmap) { goto cleanup; } fbconfig = get_fbconfig_for_depth (depth); if (!fbconfig) { g_warning ("Could not find an FBConfig for selected pixmap"); goto cleanup; } attribs[i++] = GLX_TEXTURE_FORMAT_EXT; if (depth == 24) { attribs[i++] = GLX_TEXTURE_FORMAT_RGB_EXT; } else if (depth == 32) { attribs[i++] = GLX_TEXTURE_FORMAT_RGBA_EXT; } else { g_warning ("Pixmap with depth bellow 24 are not supported"); goto cleanup; } quality = clutter_texture_get_filter_quality (CLUTTER_TEXTURE (texture)); if (quality == CLUTTER_TEXTURE_QUALITY_HIGH) mipmap = 1; attribs[i++] = GLX_MIPMAP_TEXTURE_EXT; attribs[i++] = mipmap; attribs[i++] = GLX_TEXTURE_TARGET_EXT; attribs[i++] = GLX_TEXTURE_2D_EXT; attribs[i++] = None; clutter_x11_trap_x_errors (); glx_pixmap = glXCreatePixmap (dpy, *fbconfig, pixmap, attribs); XSync (dpy, FALSE); if (clutter_x11_untrap_x_errors ()) { CLUTTER_NOTE (TEXTURE, "Failed to create GLXPixmap"); /* Make sure we don't think the call actually succeeded */ glx_pixmap = None; } g_free (fbconfig); cleanup: if (priv->glx_pixmap) clutter_glx_texture_pixmap_free_glx_pixmap (texture); if (glx_pixmap != None) { priv->glx_pixmap = glx_pixmap; create_cogl_texture (CLUTTER_TEXTURE (texture), pixmap_width, pixmap_height); CLUTTER_NOTE (TEXTURE, "Created GLXPixmap"); return; } else { priv->use_fallback = TRUE; priv->glx_pixmap = None; /* Some fucky logic here - we've fallen back and need to make sure * we realize here.. */ clutter_actor_realize (CLUTTER_ACTOR (texture)); } }
static void tidy_texture_frame_paint (ClutterActor *self) { TidyTextureFramePrivate *priv; ClutterActor *parent_texture; guint width, height; gint pwidth, pheight, ex, ey; ClutterFixed tx1, ty1, tx2, ty2, tw, th; GLenum target_type; ClutterColor col = { 0xff, 0xff, 0xff, 0xff }; priv = TIDY_TEXTURE_FRAME (self)->priv; /* no need to paint stuff if we don't have a texture to reflect */ if (!clutter_clone_texture_get_parent_texture (CLUTTER_CLONE_TEXTURE(self))) return; /* parent texture may have been hidden, there for need to make sure its * realised with resources available. */ parent_texture = CLUTTER_ACTOR (clutter_clone_texture_get_parent_texture(CLUTTER_CLONE_TEXTURE(self))); if (!CLUTTER_ACTOR_IS_REALIZED (parent_texture)) clutter_actor_realize (parent_texture); if (clutter_texture_is_tiled (CLUTTER_TEXTURE (parent_texture))) { g_warning("tiled textures not yet supported..."); return; } cogl_push_matrix (); #define FX(x) CLUTTER_INT_TO_FIXED(x) clutter_texture_get_base_size (CLUTTER_TEXTURE(parent_texture), &pwidth, &pheight); clutter_actor_get_size (self, &width, &height); tx1 = FX (priv->left); tx2 = FX (pwidth - priv->right); ty1 = FX (priv->top); ty2 = FX (pheight - priv->bottom); tw = FX (pwidth); th = FX (pheight); if (clutter_feature_available (CLUTTER_FEATURE_TEXTURE_RECTANGLE)) { target_type = CGL_TEXTURE_RECTANGLE_ARB; cogl_enable (CGL_ENABLE_TEXTURE_RECT|CGL_ENABLE_BLEND); } else { target_type = CGL_TEXTURE_2D; cogl_enable (CGL_ENABLE_TEXTURE_2D|CGL_ENABLE_BLEND); tw = clutter_util_next_p2 (pwidth); th = clutter_util_next_p2 (pheight); tx1 = tx1/tw; tx2 = tx2/tw; ty1 = ty1/th; ty2 = ty2/th; tw = FX(pwidth)/tw; th = FX(pheight)/th; } col.alpha = clutter_actor_get_opacity (self); cogl_color (&col); clutter_texture_bind_tile (CLUTTER_TEXTURE(parent_texture), 0); ex = width - priv->right; if (ex < 0) ex = priv->right; /* FIXME */ ey = height - priv->bottom; if (ey < 0) ey = priv->bottom; /* FIXME */ /* top left corner */ cogl_texture_quad (0, priv->left, /* FIXME: clip if smaller */ 0, priv->top, 0, 0, tx1, ty1); /* top middle */ cogl_texture_quad (priv->left, ex, 0, priv->top, tx1, 0, tx2, ty1); /* top right */ cogl_texture_quad (ex, width, 0, priv->top, tx2, 0, tw, ty1); /* mid left */ cogl_texture_quad (0, priv->left, priv->top, ey, 0, ty1, tx1, ty2); /* center */ cogl_texture_quad (priv->left, ex, priv->top, ey, tx1, ty1, tx2, ty2); /* mid right */ cogl_texture_quad (ex, width, priv->top, ey, tx2, ty1, tw, ty2); /* bottom left */ cogl_texture_quad (0, priv->left, ey, height, 0, ty2, tx1, th); /* bottom center */ cogl_texture_quad (priv->left, ex, ey, height, tx1, ty2, tx2, th); /* bottom right */ cogl_texture_quad (ex, width, ey, height, tx2, ty2, tw, th); cogl_pop_matrix (); #undef FX }
void meta_compositor_manage_screen (MetaCompositor *compositor, MetaScreen *screen) { MetaCompScreen *info; MetaDisplay *display = meta_screen_get_display (screen); Display *xdisplay = meta_display_get_xdisplay (display); int screen_number = meta_screen_get_screen_number (screen); Window xroot = meta_screen_get_xroot (screen); Window xwin; gint width, height; XWindowAttributes attr; long event_mask; guint n_retries; guint max_retries; /* Check if the screen is already managed */ if (meta_screen_get_compositor_data (screen)) return; if (meta_get_replace_current_wm ()) max_retries = 5; else max_retries = 1; n_retries = 0; /* Some compositors (like old versions of Muffin) might not properly unredirect * subwindows before destroying the WM selection window; so we wait a while * for such a compositor to exit before giving up. */ while (TRUE) { meta_error_trap_push_with_return (display); XCompositeRedirectSubwindows (xdisplay, xroot, CompositeRedirectManual); XSync (xdisplay, FALSE); if (!meta_error_trap_pop_with_return (display)) break; if (n_retries == max_retries) { /* This probably means that a non-WM compositor like xcompmgr is running; * we have no way to get it to exit */ meta_fatal (_("Another compositing manager is already running on screen %i on display \"%s\"."), screen_number, display->name); } n_retries++; g_usleep (G_USEC_PER_SEC); } info = g_new0 (MetaCompScreen, 1); /* * We use an empty input region for Clutter as a default because that allows * the user to interact with all the windows displayed on the screen. * We have to initialize info->pending_input_region to an empty region explicitly, * because None value is used to mean that the whole screen is an input region. */ info->pending_input_region = XFixesCreateRegion (xdisplay, NULL, 0); info->screen = screen; meta_screen_set_compositor_data (screen, info); info->output = None; info->windows = NULL; meta_screen_set_cm_selection (screen); info->stage = clutter_stage_new (); meta_screen_get_size (screen, &width, &height); clutter_actor_realize (info->stage); xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); XResizeWindow (xdisplay, xwin, width, height); event_mask = FocusChangeMask | ExposureMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | PropertyChangeMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask; if (XGetWindowAttributes (xdisplay, xwin, &attr)) { event_mask |= attr.your_event_mask; } XSelectInput (xdisplay, xwin, event_mask); info->window_group = meta_window_group_new (screen); info->background_actor = meta_background_actor_new_for_screen (screen); info->bottom_window_group = clutter_group_new(); info->overlay_group = clutter_group_new (); info->top_window_group = meta_window_group_new (screen); info->hidden_group = clutter_group_new (); clutter_container_add (CLUTTER_CONTAINER (info->window_group), info->background_actor, NULL); clutter_container_add (CLUTTER_CONTAINER (info->stage), info->window_group, info->overlay_group, info->hidden_group, NULL); clutter_actor_hide (info->hidden_group); info->plugin_mgr = meta_plugin_manager_get (screen); meta_plugin_manager_initialize (info->plugin_mgr); /* * Delay the creation of the overlay window as long as we can, to avoid * blanking out the screen. This means that during the plugin loading, the * overlay window is not accessible; if the plugin needs to access it * directly, it should hook into the "show" signal on stage, and do * its stuff there. */ info->output = get_output_window (screen); XReparentWindow (xdisplay, xwin, info->output, 0, 0); /* Make sure there isn't any left-over output shape on the * overlay window by setting the whole screen to be an * output region. * * Note: there doesn't seem to be any real chance of that * because the X server will destroy the overlay window * when the last client using it exits. */ XFixesSetWindowShapeRegion (xdisplay, info->output, ShapeBounding, 0, 0, None); do_set_stage_input_region (screen, info->pending_input_region); if (info->pending_input_region != None) { XFixesDestroyRegion (xdisplay, info->pending_input_region); info->pending_input_region = None; } clutter_actor_show (info->overlay_group); clutter_actor_show (info->stage); }