Пример #1
0
static void
shell_gtk_window_actor_set_property (GObject         *object,
                                     guint            prop_id,
                                     const GValue    *value,
                                     GParamSpec      *pspec)
{
  ShellGtkWindowActor *wactor = SHELL_GTK_WINDOW_ACTOR (object);

  switch (prop_id)
    {
    case PROP_WINDOW:
      wactor->priv->window = g_value_dup_object (value);

      /* Here automatic=FALSE means to use CompositeRedirectManual.
       * That is, the X server shouldn't draw the window onto the
       * screen.
       */
      clutter_x11_texture_pixmap_set_window (CLUTTER_X11_TEXTURE_PIXMAP (wactor),
                                             GDK_WINDOW_XWINDOW (wactor->priv->window->window),
                                             FALSE);
      /* Here automatic has a different meaning--whether
       * ClutterX11TexturePixmap should process damage update and
       * refresh the pixmap itself.
       */
      clutter_x11_texture_pixmap_set_automatic (CLUTTER_X11_TEXTURE_PIXMAP (wactor), TRUE);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}
static void
clutter_x11_texture_pixmap_set_property (GObject      *object,
                                         guint         prop_id,
                                         const GValue *value,
                                         GParamSpec   *pspec)
{
  ClutterX11TexturePixmap  *texture = CLUTTER_X11_TEXTURE_PIXMAP (object);

  switch (prop_id)
    {
    case PROP_PIXMAP:
      clutter_x11_texture_pixmap_set_pixmap (texture,
                                             g_value_get_uint (value));
      break;
    case PROP_AUTO:
      clutter_x11_texture_pixmap_set_automatic (texture,
                                                g_value_get_boolean (value));
      break;
    case PROP_WINDOW:
      clutter_x11_texture_pixmap_set_window (texture,
                                             g_value_get_uint (value));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}
static gboolean
create_cogl_texture (ClutterTexture *texture,
		     guint width,
		     guint height)
{
  CoglHandle  handle;

  handle
    = cogl_texture_new_with_size (width, height,
                                  -1, FALSE,
                                  COGL_PIXEL_FORMAT_RGBA_8888|COGL_BGR_BIT);

  if (handle)
    {
      clutter_texture_set_cogl_texture (texture, handle);

      CLUTTER_ACTOR_SET_FLAGS (texture, CLUTTER_ACTOR_REALIZED);

      clutter_glx_texture_pixmap_update_area
                                  (CLUTTER_X11_TEXTURE_PIXMAP (texture),
                                   0, 0,
                                   width, height);
      return TRUE;
    }

  return FALSE;
}
static void
clutter_x11_texture_pixmap_dispose (GObject *object)
{
  ClutterX11TexturePixmap *texture = CLUTTER_X11_TEXTURE_PIXMAP (object);
  ClutterX11TexturePixmapPrivate *priv = texture->priv;

  free_damage_resources (texture);

  clutter_x11_remove_filter (on_x_event_filter_too, (gpointer)texture);

  if (priv->owns_pixmap && priv->pixmap)
    {
      g_signal_emit (texture, signals[PIXMAP_FREEING], 0, NULL);
      XFreePixmap (clutter_x11_get_default_display (), priv->pixmap);
      priv->pixmap = None;
    }

  if (priv->image)
    {
      XDestroyImage (priv->image);
      priv->image = NULL;
    }

  free_shm_resources (texture);

  G_OBJECT_CLASS (clutter_x11_texture_pixmap_parent_class)->dispose (object);
}
static ClutterX11FilterReturn
on_x_event_filter (XEvent *xev, ClutterEvent *cev, gpointer data)
{
  ClutterX11TexturePixmap        *texture;
  ClutterX11TexturePixmapPrivate *priv;
  Display                        *dpy;

  texture = CLUTTER_X11_TEXTURE_PIXMAP (data);

  g_return_val_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture), \
                        CLUTTER_X11_FILTER_CONTINUE);

  dpy = clutter_x11_get_default_display();
  priv = texture->priv;

  if (xev->type == _damage_event_base + XDamageNotify)
    {
      XserverRegion  parts;
      gint           i, r_count;
      XRectangle    *r_damage;
      XRectangle     r_bounds;
      XDamageNotifyEvent *dev = (XDamageNotifyEvent*)xev;

      if (dev->drawable != priv->damage_drawable)
        return CLUTTER_X11_FILTER_CONTINUE;


      clutter_x11_trap_x_errors ();
      /*
       * Retrieve the damaged region and break it down into individual
       * rectangles so we do not have to update the whole shebang.
       */
      parts = XFixesCreateRegion (dpy, 0, 0);
      XDamageSubtract (dpy, priv->damage, None, parts);

      r_damage = XFixesFetchRegionAndBounds (dpy,
                                             parts,
                                             &r_count,
                                             &r_bounds);

      clutter_x11_untrap_x_errors ();

      if (r_damage)
        {
          for (i = 0; i < r_count; ++i)
            clutter_x11_texture_pixmap_update_area (texture,
                                                    r_damage[i].x,
                                                    r_damage[i].y,
                                                    r_damage[i].width,
                                                    r_damage[i].height);
          XFree (r_damage);
        }

      XFixesDestroyRegion (dpy, parts);
    }

  return  CLUTTER_X11_FILTER_CONTINUE;
}
Пример #6
0
static void
cinnamon_gtk_embed_init (CinnamonGtkEmbed *embed)
{
  embed->priv = G_TYPE_INSTANCE_GET_PRIVATE (embed, CINNAMON_TYPE_GTK_EMBED,
                                             CinnamonGtkEmbedPrivate);

  /* automatic here means whether ClutterX11TexturePixmap should
   * process damage update and refresh the pixmap itself.
   */
  clutter_x11_texture_pixmap_set_automatic (CLUTTER_X11_TEXTURE_PIXMAP (embed), TRUE);
}
Пример #7
0
static void
cinnamon_gtk_embed_on_window_realize (GtkWidget     *widget,
                                   CinnamonGtkEmbed *embed)
{
  /* Here automatic=FALSE means to use CompositeRedirectManual.
   * That is, the X server shouldn't draw the window onto the
   * screen.
   */
  clutter_x11_texture_pixmap_set_window (CLUTTER_X11_TEXTURE_PIXMAP (embed),
                                         gdk_x11_window_get_xid (gtk_widget_get_window (widget)),
                                         FALSE);
}
static void
clutter_x11_texture_pixmap_get_property (GObject      *object,
                                         guint         prop_id,
                                         GValue       *value,
                                         GParamSpec   *pspec)
{
  ClutterX11TexturePixmap *texture = CLUTTER_X11_TEXTURE_PIXMAP (object);
  ClutterX11TexturePixmapPrivate *priv = texture->priv;

  switch (prop_id)
    {
    case PROP_PIXMAP:
      g_value_set_uint (value, priv->pixmap);
      break;
    case PROP_PIXMAP_WIDTH:
      g_value_set_uint (value, priv->pixmap_width);
      break;
    case PROP_PIXMAP_HEIGHT:
      g_value_set_uint (value, priv->pixmap_height);
      break;
    case PROP_DEPTH:
      g_value_set_uint (value, priv->depth);
      break;
    case PROP_AUTO:
      g_value_set_boolean (value, priv->automatic_updates);
      break;
    case PROP_WINDOW:
      g_value_set_uint (value, priv->window);
      break;
    case PROP_WINDOW_MAPPED:
      g_value_set_boolean (value, priv->window_mapped);
      break;
    case PROP_DESTROYED:
      g_value_set_boolean (value, priv->destroyed);
      break;
    case PROP_WINDOW_X:
      g_value_set_int (value, priv->window_x);
      break;
    case PROP_WINDOW_Y:
      g_value_set_int (value, priv->window_y);
      break;
    case PROP_WINDOW_OVERRIDE_REDIRECT:
      g_value_set_boolean (value, priv->override_redirect);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}
static void
clutter_x11_texture_pixmap_realize (ClutterActor *actor)
{
  ClutterX11TexturePixmap        *texture = CLUTTER_X11_TEXTURE_PIXMAP (actor);
  ClutterX11TexturePixmapPrivate *priv = texture->priv;

  CLUTTER_ACTOR_CLASS (clutter_x11_texture_pixmap_parent_class)->
      realize (actor);

  CLUTTER_ACTOR_SET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);

  clutter_x11_texture_pixmap_update_area_real (texture,
					       0, 0,
					       priv->pixmap_width,
					       priv->pixmap_height);
}
Пример #10
0
static void
cinnamon_gtk_embed_set_window (CinnamonGtkEmbed       *embed,
                            CinnamonEmbeddedWindow *window)
{

  if (embed->priv->window)
    {
      _cinnamon_embedded_window_set_actor (embed->priv->window, NULL);

      g_object_unref (embed->priv->window);

      clutter_x11_texture_pixmap_set_window (CLUTTER_X11_TEXTURE_PIXMAP (embed),
                                             None,
                                             FALSE);

      g_signal_handlers_disconnect_by_func (embed->priv->window,
                                            (gpointer)cinnamon_gtk_embed_on_window_destroy,
                                            embed);
      g_signal_handlers_disconnect_by_func (embed->priv->window,
                                            (gpointer)cinnamon_gtk_embed_on_window_realize,
                                            embed);
    }

  embed->priv->window = window;

  if (embed->priv->window)
    {
      g_object_ref (embed->priv->window);

      _cinnamon_embedded_window_set_actor (embed->priv->window, embed);

      g_signal_connect (embed->priv->window, "destroy",
                        G_CALLBACK (cinnamon_gtk_embed_on_window_destroy), embed);
      g_signal_connect (embed->priv->window, "realize",
                        G_CALLBACK (cinnamon_gtk_embed_on_window_realize), embed);

      if (gtk_widget_get_realized (GTK_WIDGET (window)))
        cinnamon_gtk_embed_on_window_realize (GTK_WIDGET (embed->priv->window), embed);
    }

  clutter_actor_queue_relayout (CLUTTER_ACTOR (embed));
}
static ClutterX11FilterReturn
on_x_event_filter_too (XEvent *xev, ClutterEvent *cev, gpointer data)
{
  ClutterX11TexturePixmap        *texture;
  ClutterX11TexturePixmapPrivate *priv;

  texture = CLUTTER_X11_TEXTURE_PIXMAP (data);

  g_return_val_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture), \
                        CLUTTER_X11_FILTER_CONTINUE);

  priv = texture->priv;

  switch (xev->type) {
  case MapNotify:
  case ConfigureNotify:
    {
      if (((XConfigureEvent *)xev)->window != priv->window)
        break;
      /* Only sync the window pixmap if the size has changed */
      if (xev->xconfigure.width != priv->pixmap_width ||
          xev->xconfigure.height != priv->pixmap_height ||
          !priv->window_mapped)
        clutter_x11_texture_pixmap_sync_window (texture);
      break;
    }
  case UnmapNotify:
    if (((XUnmapEvent *)xev)->window != priv->window)
      break;
    clutter_x11_texture_pixmap_set_mapped (texture, FALSE);
    break;
  case DestroyNotify:
    if (((XDestroyWindowEvent *)xev)->window != priv->window)
      break;
    clutter_x11_texture_pixmap_destroyed (texture);
    break;
  default:
    break;
  }

  return CLUTTER_X11_FILTER_CONTINUE;
}
Пример #12
0
G_MODULE_EXPORT int
test_egl_image_main (int argc, char **argv)
{
  static const ClutterColor stage_color = { 0x1f, 0x84, 0x56, 0xff };
  ClutterActor *stage;
  ClutterActor *texture;
  ClutterX11TexturePixmap *x11_texture;
  Window window;

  clutter_init (&argc, &argv);

  if (argc != 2)
    {
      g_printerr ("usage: clutter-test xid\n");
      return EXIT_FAILURE;
    }

  window = (Window)strtol (argv[1], NULL, 0);
  g_print ("Attempting to redirect window 0x%08x\n", (guint)window);

  stage = clutter_stage_get_default ();
  clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);

  texture = clutter_eglx_egl_image_new_with_window (window);
  x11_texture = CLUTTER_X11_TEXTURE_PIXMAP (texture);
  clutter_x11_texture_pixmap_set_automatic (x11_texture, TRUE);

  clutter_actor_set_name (texture, "EGL Image");
  clutter_container_add (CLUTTER_CONTAINER (stage), texture, NULL);

  clutter_actor_set_size (stage, 512, 512);
  clutter_actor_show (stage);

  clutter_main ();

  return EXIT_SUCCESS;
}
Пример #13
0
/*
 * Updates the global->root_pixmap actor with the root window's pixmap or fails
 * with a warning.
 */
static void
update_root_window_pixmap (ShellGlobal *global)
{
  Atom type;
  int format;
  gulong nitems;
  gulong bytes_after;
  guchar *data;
  Pixmap root_pixmap_id = None;

  if (!XGetWindowProperty (gdk_x11_get_default_xdisplay (),
                           gdk_x11_get_default_root_xwindow (),
                           gdk_x11_get_xatom_by_name ("_XROOTPMAP_ID"),
                           0, LONG_MAX,
                           False,
                           AnyPropertyType,
                           &type, &format, &nitems, &bytes_after, &data) &&
      type != None)
  {
     /* Got a property. */
     if (type == XA_PIXMAP && format == 32 && nitems == 1)
       {
         /* Was what we expected. */
         root_pixmap_id = *(Pixmap *)data;
       }
     else
       {
         g_warning ("Could not get the root window pixmap");
       }

     XFree(data);
  }

  clutter_x11_texture_pixmap_set_pixmap (CLUTTER_X11_TEXTURE_PIXMAP (global->root_pixmap),
                                         root_pixmap_id);
}
Пример #14
0
G_MODULE_EXPORT int
test_pixmap_main (int argc, char **argv)
{
  GOptionContext      *context;
  Display	      *xdpy;
  int		       screen;
  ClutterActor        *group = NULL, *label, *stage, *tex;
  Pixmap               pixmap;
  const ClutterColor   gry = { 0x99, 0x99, 0x99, 0xFF };
  Window               win_remote;
  guint		       w, h, d;
  GC		       gc;
  ClutterTimeline     *timeline;
  ClutterAlpha	      *alpha;
  ClutterBehaviour    *depth_behavior;
  int		       i;
  int                  row_height;

#ifdef CLUTTER_WINDOWING_X11
  clutter_set_windowing_backend (CLUTTER_WINDOWING_X11);
#endif

  if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
    return 1;

#ifdef CLUTTER_WINDOWING_X11
  if (!clutter_check_windowing_backend (CLUTTER_WINDOWING_X11))
    g_error ("test-pixmap requires the X11 Clutter backend.");
#endif

  xdpy = clutter_x11_get_default_display ();
  XSynchronize (xdpy, True);

  context = g_option_context_new (" - test-pixmap options");
  g_option_context_add_main_entries (context, g_options, NULL);
  g_option_context_parse (context, &argc, &argv, NULL);

  pixmap = create_pixmap (&w, &h, &d);

  screen = DefaultScreen(xdpy);
  win_remote = XCreateSimpleWindow (xdpy, DefaultRootWindow(xdpy),
				    0, 0, 200, 200,
				    0,
				    WhitePixel(xdpy, screen),
				    WhitePixel(xdpy, screen));

  XMapWindow (xdpy, win_remote);

  stage = clutter_stage_new ();
  clutter_actor_set_position (stage, 0, 150);
  clutter_actor_set_background_color (stage, &gry);
  clutter_stage_set_title (CLUTTER_STAGE (stage), "X11 Texture from Pixmap");
  g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);

  timeline = clutter_timeline_new (5000);
  g_signal_connect (timeline,
                    "completed", G_CALLBACK (timeline_completed),
                    NULL);

  alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR);
  depth_behavior = clutter_behaviour_depth_new (alpha, -2500, 400);

  if (!disable_x11)
    {
      group = clutter_group_new ();
      clutter_container_add_actor (CLUTTER_CONTAINER (stage), group);
      label = clutter_text_new_with_text ("fixed",
                                          "ClutterX11Texture (Window)");
      clutter_container_add_actor (CLUTTER_CONTAINER (group), label);
      tex = clutter_x11_texture_pixmap_new_with_window (win_remote);
      clutter_container_add_actor (CLUTTER_CONTAINER (group), tex);
      clutter_actor_set_position (tex, 0, 20);
      clutter_x11_texture_pixmap_set_automatic (CLUTTER_X11_TEXTURE_PIXMAP (tex),
                                                TRUE);
      clutter_texture_set_filter_quality (CLUTTER_TEXTURE (tex),
                                          CLUTTER_TEXTURE_QUALITY_HIGH);
      clutter_actor_set_position (group, 0, 0);
      if (!disable_animation)
        clutter_behaviour_apply (depth_behavior, group);
    }

  if (group)
    row_height = clutter_actor_get_height (group);
  else
    row_height = 0;

  /* NB: We only draw on the window after being redirected, so we dont
   * have to worry about handling expose events... */
  gc = XCreateGC (xdpy, win_remote, 0, NULL);
  XSetForeground (xdpy, gc, BlackPixel (xdpy, screen));
  XSetLineAttributes(xdpy, gc, 5, LineSolid, CapButt, JoinMiter);

  for (i = 0; i < 10; i++)
    XDrawLine (xdpy, win_remote, gc, 0+i*20, 0, 10+i*20+i, 200);


  group = clutter_group_new ();
  clutter_container_add_actor (CLUTTER_CONTAINER (stage), group);
  label = clutter_text_new_with_text ("fixed", "ClutterX11Texture (Pixmap)");
  clutter_container_add_actor (CLUTTER_CONTAINER (group), label);
  tex = clutter_x11_texture_pixmap_new_with_pixmap (pixmap);
  clutter_x11_texture_pixmap_set_automatic (CLUTTER_X11_TEXTURE_PIXMAP (tex),
                                            TRUE);
  clutter_container_add_actor (CLUTTER_CONTAINER (group), tex);
  clutter_actor_set_position (tex, 0, 20);
  clutter_texture_set_filter_quality (CLUTTER_TEXTURE (tex),
				      CLUTTER_TEXTURE_QUALITY_HIGH);
  /* oddly, the actor's size is 0 until it is realized, even though
     pixmap-height is set */
  clutter_actor_set_position (group, 0, row_height);
  if (!disable_animation)
    clutter_behaviour_apply (depth_behavior, group);


  g_signal_connect (stage, "key-release-event",
                    G_CALLBACK (stage_key_release_cb), (gpointer)pixmap);
  g_signal_connect (stage, "button-press-event",
                    G_CALLBACK (stage_button_press_cb), (gpointer)pixmap);

  clutter_actor_show (stage);

  if (!disable_animation)
    clutter_timeline_start (timeline);

  clutter_threads_add_timeout (1000, draw_arc, GUINT_TO_POINTER (pixmap));

  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);
    }
}