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);
}
示例#2
0
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 ();
    }
}
示例#4
0
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);
}
示例#5
0
/**
 * 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;
}
示例#6
0
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 ();
}
示例#7
0
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);
}
示例#9
0
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)));
}
示例#10
0
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);
}
示例#11
0
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;
}
示例#12
0
IO_METHOD(IoClutterActor, realize) {
  clutter_actor_realize(IOCACTOR(self));
  return self;
}
示例#13
0
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);
}
示例#14
0
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;
    }
}
示例#15
0
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 ();
}
示例#16
0
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);
  }
}
示例#18
0
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);
}
示例#19
0
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));
    }
}
示例#22
0
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
}
示例#23
0
文件: compositor.c 项目: nkoep/muffin
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);
}