示例#1
0
/*
 * mnb_input_manager_push_region ()
 *
 * Pushes region of the given dimensions onto the input region stack; this is
 * immediately reflected in the actual input shape.
 *
 * x, y, width, height: region position and size (screen-relative)
 *
 * inverse: indicates whether the region should be added to the input shape
 *          (FALSE; input events in this area will go to Clutter) or subtracted
 *          from it (TRUE; input events will go to X)
 *
 * layer: Which layer this input region belongs to
 *
 * returns: id that identifies this region; used in subsequent call to
 *          mnb_input_manager_remove_region().
 */
MnbInputRegion *
mnb_input_manager_push_region (gint          x,
                               gint          y,
                               guint         width,
                               guint         height,
                               gboolean      inverse,
                               MnbInputLayer layer)
{
  MnbInputRegion *mir  = g_slice_alloc (sizeof (MnbInputRegion));
  Display        *xdpy;

  g_assert (mgr_singleton && layer >= 0 && layer <= MNB_INPUT_LAYER_TOP);

  xdpy = meta_plugin_get_xdisplay (mgr_singleton->plugin);

  mir->rect.x       = x;
  mir->rect.y       = y;
  mir->rect.width   = width;
  mir->rect.height  = height;

  mir->inverse = inverse;
  mir->region  = XFixesCreateRegion (xdpy, &mir->rect, 1);
  mir->layer   = layer;

  mgr_singleton->layers[layer] =
    g_list_append (mgr_singleton->layers[layer], mir);

  mnb_input_manager_apply_stack ();

  return mir;
}
示例#2
0
void Workspace::damageNotifyEvent( const XDamageNotifyEvent *event )
{
	Client *client = find( event->drawable );

	// ### should never happen
	if ( !client )
		return;

	XserverRegion parts;

	if ( !client->isPainted() ) {
		// If the window has been painted for the first time, mark the whole
		// window as damaged.
		parts = client->createRegion( WindowAndBorder );
		XDamageSubtract( dpy, client->damageHandle(), None, None );
		client->setPainted( true );
	} else {
		// Create a new empty region
		parts = XFixesCreateRegion( dpy, 0, 0 );

		// Copy the damage region to parts, subtracting it from the widgets damage
		XDamageSubtract( dpy, client->damageHandle(), None, parts );

		// Offset parts with the widgets position
		XFixesTranslateRegion( dpy, parts, client->x(), client->y() );
	}

	// Add the damaged region to the total damage for the workspace
	// (destroys parts)
	addDamage( parts );
}
示例#3
0
文件: compositor.c 项目: nkoep/muffin
void
meta_set_stage_input_region (MetaScreen   *screen,
                             XserverRegion region)
{
    MetaCompScreen *info = meta_screen_get_compositor_data (screen);
    MetaDisplay  *display = meta_screen_get_display (screen);
    Display      *xdpy    = meta_display_get_xdisplay (display);

    if (info->stage && info->output)
    {
        do_set_stage_input_region (screen, region);
    }
    else
    {
        /* Reset info->pending_input_region if one existed before and set the new
         * one to use it later. */
        if (info->pending_input_region)
        {
            XFixesDestroyRegion (xdpy, info->pending_input_region);
            info->pending_input_region = None;
        }
        if (region != None)
        {
            info->pending_input_region = XFixesCreateRegion (xdpy, NULL, 0);
            XFixesCopyRegion (xdpy, info->pending_input_region, region);
        }
    }
}
static void 
dri2SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
{
    struct dri2_drawable *dri2_drawable = (struct dri2_drawable *)dri_drawable;
    XRectangle xrect;
    XserverRegion region;

    if (dri2_drawable->has_backbuffer) {
        if (gsDRI2SwapAvailable) {
            CARD64 ret;
            VA_DRI2SwapBuffers(ctx->native_dpy, dri_drawable->x_drawable, 0, 0,
                               0, &ret);
        } else {
            xrect.x = 0;
            xrect.y = 0;
            xrect.width = dri2_drawable->width;
            xrect.height = dri2_drawable->height;

            region = XFixesCreateRegion(ctx->native_dpy, &xrect, 1);
            VA_DRI2CopyRegion(ctx->native_dpy, dri_drawable->x_drawable, region,
                              DRI2BufferFrontLeft, DRI2BufferBackLeft);
            XFixesDestroyRegion(ctx->native_dpy, region);
        }
    }
}
示例#5
0
static void
dri2WaitGL(__GLXDRIdrawable * pdraw)
{
    __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
    XRectangle xrect;
    XserverRegion region;

    if (!priv->have_fake_front)
        return;

    xrect.x = 0;
    xrect.y = 0;
    xrect.width = priv->width;
    xrect.height = priv->height;

#ifdef __DRI2_FLUSH
    if (pdraw->psc->f)
        (*pdraw->psc->f->flush) (pdraw->driDrawable);
#endif

    region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
    DRI2CopyRegion(pdraw->psc->dpy, pdraw->xDrawable, region,
                   DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
    XFixesDestroyRegion(pdraw->psc->dpy, region);
}
示例#6
0
static void
dri2CopySubBuffer(__GLXDRIdrawable *pdraw, int x, int y, int width, int height)
{
    __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
    XRectangle xrect;
    XserverRegion region;

    /* Check we have the right attachments */
    if (!priv->have_back)
        return;

    xrect.x = x;
    xrect.y = priv->height - y - height;
    xrect.width = width;
    xrect.height = height;

#ifdef __DRI2_FLUSH
    if (pdraw->psc->f)
        (*pdraw->psc->f->flush) (pdraw->driDrawable);
#endif

    region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
    /* should get a fence ID back from here at some point */
    DRI2CopyRegion(pdraw->psc->dpy, pdraw->xDrawable, region,
                   DRI2BufferFrontLeft, DRI2BufferBackLeft);
    XFixesDestroyRegion(pdraw->psc->dpy, region);

    /* Refresh the fake front (if present) after we just damaged the real
     * front.
     */
    dri2WaitX(pdraw);
}
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;
}
示例#8
0
文件: xf_peer.c 项目: SSphere/FreeRDP
void xf_xdamage_init(xfInfo* xfi)
{
	int damage_event;
	int damage_error;
	int major, minor;
	XGCValues values;

	if (XDamageQueryExtension(xfi->display, &damage_event, &damage_error) == 0)
	{
		fprintf(stderr, "XDamageQueryExtension failed\n");
		return;
	}

	XDamageQueryVersion(xfi->display, &major, &minor);

	if (XDamageQueryVersion(xfi->display, &major, &minor) == 0)
	{
		fprintf(stderr, "XDamageQueryVersion failed\n");
		return;
	}
	else if (major < 1)
	{
		fprintf(stderr, "XDamageQueryVersion failed: major:%d minor:%d\n", major, minor);
		return;
	}

	xfi->xdamage_notify_event = damage_event + XDamageNotify;
	xfi->xdamage = XDamageCreate(xfi->display, xfi->root_window, XDamageReportDeltaRectangles);

	if (xfi->xdamage == None)
	{
		fprintf(stderr, "XDamageCreate failed\n");
		return;
	}

#ifdef WITH_XFIXES
	xfi->xdamage_region = XFixesCreateRegion(xfi->display, NULL, 0);

	if (xfi->xdamage_region == None)
	{
		fprintf(stderr, "XFixesCreateRegion failed\n");
		XDamageDestroy(xfi->display, xfi->xdamage);
		xfi->xdamage = None;
		return;
	}
#endif

	values.subwindow_mode = IncludeInferiors;
	xfi->xdamage_gc = XCreateGC(xfi->display, xfi->root_window, GCSubwindowMode, &values);
	XSetFunction(xfi->display, xfi->xdamage_gc, GXcopy);
}
// Convert QRegion to XserverRegion. All code uses XserverRegion
// only when really necessary as the shared implementation uses
// QRegion.
XserverRegion toXserverRegion(QRegion region)
{
    QVector< QRect > rects = region.rects();
    XRectangle* xr = new XRectangle[ rects.count()];
    for (int i = 0;
            i < rects.count();
            ++i) {
        xr[ i ].x = rects[ i ].x();
        xr[ i ].y = rects[ i ].y();
        xr[ i ].width = rects[ i ].width();
        xr[ i ].height = rects[ i ].height();
    }
    XserverRegion ret = XFixesCreateRegion(display(), xr, rects.count());
    delete[] xr;
    return ret;
}
示例#10
0
void
meta_empty_stage_input_region (MetaScreen *screen)
{
  /* Using a static region here is a bit hacky, but Metacity never opens more than
   * one XDisplay, so it works fine. */
  static XserverRegion region = None;

  if (region == None)
    {
      MetaDisplay  *display = meta_screen_get_display (screen);
      Display      *xdpy    = meta_display_get_xdisplay (display);
      region = XFixesCreateRegion (xdpy, NULL, 0);
    }

  meta_set_stage_input_region (screen, region);
}
示例#11
0
/**
 * Copy between buffers of the DRI2 drawable.
 */
void
x11_drawable_copy_buffers(struct x11_screen *xscr, Drawable drawable,
                          int x, int y, int width, int height,
                          int src_buf, int dst_buf)
{
   XRectangle rect;
   XserverRegion region;

   rect.x = x;
   rect.y = y;
   rect.width = width;
   rect.height = height;

   region = XFixesCreateRegion(xscr->dpy, &rect, 1);
   DRI2CopyRegion(xscr->dpy, drawable, region, dst_buf, src_buf);
   XFixesDestroyRegion(xscr->dpy, region);
}
示例#12
0
EAPI Ecore_X_Region
ecore_x_region_new(Ecore_X_Rectangle *rects,
                   int num)
{
#ifdef ECORE_XFIXES
   Ecore_X_Region region;
   XRectangle *xrect;

   LOGFN(__FILE__, __LINE__, __FUNCTION__);
   xrect = _ecore_x_rectangle_ecore_to_x(rects, num);
   region = XFixesCreateRegion(_ecore_x_disp, xrect, num);
   free(xrect);
   return region;
#else /* ifdef ECORE_XFIXES */
   return 0;
#endif /* ifdef ECORE_XFIXES */
}
示例#13
0
static void dri2_copy_swap(Display *dpy, Drawable d,
			   int width, int height, int has_front)
{
	XRectangle rect;
	XserverRegion region;

	rect.x = 0;
	rect.y = 0;
	rect.width = width;
	rect.height = height;

	region = XFixesCreateRegion(dpy, &rect, 1);
	DRI2CopyRegion(dpy, d, region, DRI2BufferFrontLeft, DRI2BufferBackLeft);
	if (has_front)
		DRI2CopyRegion(dpy, d, region, DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
	XFixesDestroyRegion(dpy, region);
}
示例#14
0
static void
__glXReportDamage(__DRIdrawable * driDraw,
                  int x, int y,
                  drm_clip_rect_t * rects, int num_rects,
                  GLboolean front_buffer, void *loaderPrivate)
{
   XRectangle *xrects;
   XserverRegion region;
   int i;
   int x_off, y_off;
   __GLXDRIdrawable *glxDraw = loaderPrivate;
   struct glx_screen *psc = glxDraw->psc;
   Display *dpy = psc->dpy;
   Drawable drawable;

   if (!has_damage_post(dpy))
      return;

   if (front_buffer) {
      x_off = x;
      y_off = y;
      drawable = RootWindow(dpy, psc->scr);
   }
   else {
      x_off = 0;
      y_off = 0;
      drawable = glxDraw->xDrawable;
   }

   xrects = malloc(sizeof(XRectangle) * num_rects);
   if (xrects == NULL)
      return;

   for (i = 0; i < num_rects; i++) {
      xrects[i].x = rects[i].x1 + x_off;
      xrects[i].y = rects[i].y1 + y_off;
      xrects[i].width = rects[i].x2 - rects[i].x1;
      xrects[i].height = rects[i].y2 - rects[i].y1;
   }
   region = XFixesCreateRegion(dpy, xrects, num_rects);
   free(xrects);
   XDamageAdd(dpy, drawable, region);
   XFixesDestroyRegion(dpy, region);
}
LOCAL void
dri_state_swap_buffer(dri_state_t *state, dri_drawable_t *dri_drwble)
{
  dri2_drawable_t *dri2_drwble = (dri2_drawable_t*)dri_drwble;
  XRectangle xrect;
  XserverRegion region;

  if (dri2_drwble->has_backbuffer) {
    xrect.x = 0;
    xrect.y = 0;
    xrect.width = dri2_drwble->width;
    xrect.height = dri2_drwble->height;

    region = XFixesCreateRegion(state->x11_dpy, &xrect, 1);
    VA_DRI2CopyRegion(state->x11_dpy, dri_drwble->x_drawable, region,
        DRI2BufferFrontLeft, DRI2BufferBackLeft);
    XFixesDestroyRegion(state->x11_dpy, region);
  }
}
示例#16
0
// Handles expose events for the root window
void Workspace::exposeEvent( const XExposeEvent *event )
{
	if ( event->window != rootId() )
		return;

	int more = event->count + 1;
	if ( mExposeRects.count() + more > mExposeRects.capacity() )
		mExposeRects.reserve( mExposeRects.count() + more );

	XRectangle r = { event->x, event->y, event->width, event->height };
	mExposeRects.append( r );

	if ( event->count == 0 ) {
		XserverRegion damage = XFixesCreateRegion( dpy,
					&mExposeRects.first(), mExposeRects.count() );
		addDamage( damage );
		mExposeRects.clear();
	}
}
示例#17
0
/**
 * Copy between buffers of the DRI2 drawable.
 */
void
x11_drawable_copy_buffers_region(struct x11_screen *xscr, Drawable drawable,
                                 int num_rects, const int *rects,
                                 int src_buf, int dst_buf)
{
   XserverRegion region;
   XRectangle *rectangles = CALLOC(num_rects, sizeof(XRectangle));

   for (int i = 0; i < num_rects; i++) {
      rectangles[i].x = rects[i * 4 + 0];
      rectangles[i].y = rects[i * 4 + 1];
      rectangles[i].width = rects[i * 4 + 2];
      rectangles[i].height = rects[i * 4 + 3];
   }

   region = XFixesCreateRegion(xscr->dpy, rectangles, num_rects);
   DRI2CopyRegion(xscr->dpy, drawable, region, dst_buf, src_buf);
   XFixesDestroyRegion(xscr->dpy, region);
   FREE(rectangles);
}
示例#18
0
void
clientwin_repair(ClientWin *cw)
{
	int nrects, i;
	XRectangle *rects;
	XserverRegion rgn = XFixesCreateRegion(cw->mainwin->dpy, 0, 0);
	
	XDamageSubtract(cw->mainwin->dpy, cw->damage, None, rgn);
	
	rects = XFixesFetchRegion(cw->mainwin->dpy, rgn, &nrects);
	XFixesDestroyRegion(cw->mainwin->dpy, rgn);
	
	for(i = 0; i < nrects; i++)
		clientwin_repaint(cw, &rects[i]);
	
	if(rects)
		XFree(rects);
	
	cw->damaged = False;
}
int ephyrDRI2CopyRegion(XID drawable,
		   EphyrDRI2WindowPair *pair,
		   RegionPtr pRegion,
		   unsigned int dest,
		   unsigned int src)
{
    Display *dpy = hostx_get_display ();
    XRectangle xrect;
    XserverRegion region;

    xrect.x = pRegion->extents.x1;
    xrect.y = pRegion->extents.y1;
    xrect.width  = pRegion->extents.x2 - pRegion->extents.x1;
    xrect.height = pRegion->extents.y2 - pRegion->extents.y1;

    region = XFixesCreateRegion(dpy, &xrect, 1);
    DRI2CopyRegion(dpy, pair->remote, region, dest, src);
    XFixesDestroyRegion(dpy, region);

    return Success;
}
// Global event filter for intercepting damage events
static bool x11EventFilter(void *message, long int *result)
{
    XEvent *event = reinterpret_cast<XEvent*>(message);
    if (event->type == damageEventBase + XDamageNotify) {
        XDamageNotifyEvent *e = reinterpret_cast<XDamageNotifyEvent*>(event);
        if (DamageWatch *damageWatch = damageWatches.value(e->drawable)) {
            // Create a new region and empty the damage region into it.
            // The window is small enough that we don't really care about the region;
            // we'll just throw it away and schedule a full repaint of the container.
            XserverRegion region = XFixesCreateRegion(e->display, 0, 0);
            XDamageSubtract(e->display, e->damage, None, region);
            XFixesDestroyRegion(e->display, region);
            damageWatch->container->update();
        }
    }

    if (oldEventFilter && oldEventFilter != x11EventFilter) {
        return oldEventFilter(message, result);
    } else {
        return false;
    }
}
示例#21
0
/*
 * Applies the current input shape base and stack to the stage input shape.
 * This function is for internal use only and should not be used outside of the
 * actual implementation of the input shape stack.
 */
static void
mnb_input_manager_apply_stack (void)
{
  Display       *xdpy;
  GList         *l;
  gint           i;
  XserverRegion  result;

  g_assert (mgr_singleton);

  xdpy = meta_plugin_get_xdisplay (mgr_singleton->plugin);

  if (mgr_singleton->current_region)
    XFixesDestroyRegion (xdpy, mgr_singleton->current_region);

  result = mgr_singleton->current_region = XFixesCreateRegion (xdpy, NULL, 0);

  for (i = 0; i <= MNB_INPUT_LAYER_TOP; ++i)
    {
      l = mgr_singleton->layers[i];

      if (!l)
        continue;

      while (l)
        {
          MnbInputRegion *mir = l->data;

          if (mir->inverse)
            XFixesSubtractRegion (xdpy, result, result, mir->region);
          else
            XFixesUnionRegion (xdpy, result, result, mir->region);

          l = l->next;
        }
    }

  meta_plugin_set_stage_input_region (mgr_singleton->plugin, result);
}
示例#22
0
static XserverRegion
client_win_extents (Wm *w, Client *client)
{
  int x, y, width, height;
  XRectangle	    r;

  /* XXX make coverage much fast as its now getting called all the time */
  client->get_coverage(client, &x, &y, &width, &height);  

  r.x = x;
  r.y = y; 
  r.width = width;
  r.height = height;

  if (w->config->shadow_style)
    {
      if (client->type == MBCLIENT_TYPE_DIALOG 
	  || client->type == MBCLIENT_TYPE_TASK_MENU 
	  || client->type == MBCLIENT_TYPE_OVERRIDE)
	{
	  if (w->config->shadow_style == SHADOW_STYLE_SIMPLE)
	    {
	      r.width  += w->config->shadow_dx;
	      r.height += w->config->shadow_dy;
	    } else {
	      r.x      += w->config->shadow_dx;
	      r.y      += w->config->shadow_dy;
	      r.width  += w->config->shadow_padding_width;
	      r.height += w->config->shadow_padding_height;
	    }
	}
    }

  dbg("comp %s() +%i+%i , %ix%i\n", __func__, x, y, width, height);

  return XFixesCreateRegion (w->dpy, &r, 1);
}
示例#23
0
static int x11_shadow_xdamage_init(x11ShadowSubsystem* subsystem)
{
#ifdef WITH_XDAMAGE
	int major, minor;
	int damage_event;
	int damage_error;

	if (!subsystem->use_xfixes)
		return -1;

	if (!XDamageQueryExtension(subsystem->display, &damage_event, &damage_error))
		return -1;

	if (!XDamageQueryVersion(subsystem->display, &major, &minor))
		return -1;

	if (major < 1)
		return -1;

	subsystem->xdamage_notify_event = damage_event + XDamageNotify;
	subsystem->xdamage = XDamageCreate(subsystem->display, subsystem->root_window, XDamageReportDeltaRectangles);

	if (!subsystem->xdamage)
		return -1;

#ifdef WITH_XFIXES
	subsystem->xdamage_region = XFixesCreateRegion(subsystem->display, NULL, 0);

	if (!subsystem->xdamage_region)
		return -1;
#endif

	return 1;
#else
	return -1;
#endif
}
示例#24
0
文件: compositor.c 项目: nkoep/muffin
/*
 * Shapes the cow so that the given window is exposed,
 * when metaWindow is NULL it clears the shape again
 */
static void
meta_shape_cow_for_window (MetaScreen *screen,
                           MetaWindow *metaWindow)
{
    MetaCompScreen *info = meta_screen_get_compositor_data (screen);
    Display *xdisplay = meta_display_get_xdisplay (meta_screen_get_display (screen));

    if (metaWindow == NULL)
        XFixesSetWindowShapeRegion (xdisplay, info->output, ShapeBounding, 0, 0, None);
    else
    {
        XserverRegion output_region;
        XRectangle screen_rect, window_bounds;
        int width, height;
        MetaRectangle rect;

        meta_window_get_outer_rect (metaWindow, &rect);

        window_bounds.x = rect.x;
        window_bounds.y = rect.y;
        window_bounds.width = rect.width;
        window_bounds.height = rect.height;

        meta_screen_get_size (screen, &width, &height);
        screen_rect.x = 0;
        screen_rect.y = 0;
        screen_rect.width = width;
        screen_rect.height = height;

        output_region = XFixesCreateRegion (xdisplay, &window_bounds, 1);

        XFixesInvertRegion (xdisplay, output_region, &screen_rect, output_region);
        XFixesSetWindowShapeRegion (xdisplay, info->output, ShapeBounding, 0, 0, output_region);
        XFixesDestroyRegion (xdisplay, output_region);
    }
}
示例#25
0
/**
 * meta_shape_cow_for_window:
 * @compositor: A #MetaCompositor
 * @window: (nullable): A #MetaWindow to shape the COW for
 *
 * Sets an bounding shape on the COW so that the given window
 * is exposed. If @window is %NULL it clears the shape again.
 *
 * Used so we can unredirect windows, by shaping away the part
 * of the COW, letting the raw window be seen through below.
 */
static void
meta_shape_cow_for_window (MetaCompositor *compositor,
                           MetaWindow *window)
{
  MetaDisplay *display = compositor->display;
  Display *xdisplay = meta_display_get_xdisplay (display);

  if (window == NULL)
    XFixesSetWindowShapeRegion (xdisplay, compositor->output, ShapeBounding, 0, 0, None);
  else
    {
      XserverRegion output_region;
      XRectangle screen_rect, window_bounds;
      int width, height;
      MetaRectangle rect;

      meta_window_get_frame_rect (window, &rect);

      window_bounds.x = rect.x;
      window_bounds.y = rect.y;
      window_bounds.width = rect.width;
      window_bounds.height = rect.height;

      meta_screen_get_size (display->screen, &width, &height);
      screen_rect.x = 0;
      screen_rect.y = 0;
      screen_rect.width = width;
      screen_rect.height = height;

      output_region = XFixesCreateRegion (xdisplay, &window_bounds, 1);

      XFixesInvertRegion (xdisplay, output_region, &screen_rect, output_region);
      XFixesSetWindowShapeRegion (xdisplay, compositor->output, ShapeBounding, 0, 0, output_region);
      XFixesDestroyRegion (xdisplay, output_region);
    }
}
示例#26
0
/**
 * shell_global_set_stage_input_region:
 * @global: the #ShellGlobal
 * @rectangles: (element-type Meta.Rectangle): a list of #MetaRectangle
 * describing the input region.
 *
 * Sets the area of the stage that is responsive to mouse clicks when
 * the stage mode is %SHELL_STAGE_INPUT_MODE_NORMAL (but does not change the
 * current stage mode).
 */
void
shell_global_set_stage_input_region (ShellGlobal *global,
                                     GSList      *rectangles)
{
  MetaScreen *screen = mutter_plugin_get_screen (global->plugin);
  MetaDisplay *display = meta_screen_get_display (screen);
  Display *xdpy = meta_display_get_xdisplay (display);
  MetaRectangle *rect;
  XRectangle *rects;
  int nrects, i;
  GSList *r;

  g_return_if_fail (SHELL_IS_GLOBAL (global));

  nrects = g_slist_length (rectangles);
  rects = g_new (XRectangle, nrects);
  for (r = rectangles, i = 0; r; r = r->next, i++)
    {
      rect = (MetaRectangle *)r->data;
      rects[i].x = rect->x;
      rects[i].y = rect->y;
      rects[i].width = rect->width;
      rects[i].height = rect->height;
    }

  if (global->input_region)
    XFixesDestroyRegion (xdpy, global->input_region);

  global->input_region = XFixesCreateRegion (xdpy, rects, nrects);
  g_free (rects);

  /* set_stage_input_mode() will figure out whether or not we
   * should actually change the input region right now.
   */
  shell_global_set_stage_input_mode (global, global->input_mode);
}
示例#27
0
// This is the function that creates the screen presentation, by compositing the
// top-level windows on the root window.
void Workspace::repaint()
{
	// If there's no damage, update the whole display
	if ( mDamage == None || mInitialRepaint ) {
		XRectangle r = { 0, 0, width(), height() };
		XserverRegion region = XFixesCreateRegion( dpy, &r, 1 );

		if ( mDamage )
			XFixesDestroyRegion( dpy, mDamage );

		mDamage = region;
		mInitialRepaint = false;
	}

	// Use the damage region as the clip region for the root window
	XFixesSetPictureClipRegion( dpy, frontBuffer(), 0, 0, mDamage );

	// Client list for clients that are either translucent, or have a shadow
	ClientList translucents;

	// Draw each opaque window top to bottom, subtracting the bounding rect of
	// each drawn window from the clip region.
	ClientList::ConstIterator end = mList.constEnd();
	for ( ClientList::ConstIterator it = mList.constBegin(); it != end; ++it )
	{
		Client *client = *it;

		if ( !client->isVisible() || !client->isPainted() )
			continue;

		// Update the region containing the area the window was last rendered at.
		client->updateOnScreenRegion();

		// Only draw the window if it's opaque
		if ( client->isOpaque() ) {
			// Set the clip region for the backbuffer to the damage region, and
			// subtract the clients shape from the damage region
			XFixesSetPictureClipRegion( dpy, backBuffer(), 0, 0, mDamage );
			XFixesSubtractRegion( dpy, mDamage, mDamage, client->shape() );

			XRenderComposite( dpy, PictOpSrc, client->picture(),
					None, backBuffer(), 0, 0, 0, 0,
					client->x(), client->y(),
					client->width() + client->borderWidth() * 2,
					client->height() + client->borderWidth() * 2 );
		}

		// Save the clip region before the next client shape is subtracted from it.
		// We need to restore it later when we're drawing the shadow.
		client->setShapeClip( mDamage );
		translucents.prepend( client );
	}

	// Draw any areas of the root window not covered by windows
	XFixesSetPictureClipRegion( dpy, backBuffer(), 0, 0, mDamage );
	XRenderComposite( dpy, PictOpSrc, rootTile(), None, backBuffer(),
					  0, 0, 0, 0, 0, 0, width(), height() );

	// Now walk the list backwards, drawing translucent windows and shadows.
	// That we draw bottom to top is important now since we're drawing translucent windows.
	end = translucents.constEnd();
	for ( ClientList::ConstIterator it = translucents.constBegin(); it != end; ++it )
	{
		Client *client = *it;

		// Restore the previously saved clip region
		XFixesSetPictureClipRegion( dpy, backBuffer(), 0, 0, client->shapeClip() );

		// Only draw the window if it's translucent
		// (we drew the opaque ones in the previous loop)
		if ( !client->isOpaque() )
			XRenderComposite( dpy, PictOpOver, client->picture(),
				    client->alphaMask(), backBuffer(), 0, 0, 0, 0,
					client->x() + client->borderWidth(),
					client->y() + client->borderWidth(),
					client->width(), client->height() );

		// We don't need the clip region anymore
		client->destroyShapeClip();
	}

	translucents.clear();

	// Destroy the damage region
	XFixesDestroyRegion( dpy, mDamage );
	mDamage = None;

	// Copy the back buffer contents to the root window
	XFixesSetPictureClipRegion( dpy, backBuffer(), 0, 0, None );
	XRenderComposite( dpy, PictOpSrc, backBuffer(), None, frontBuffer(),
					  0, 0, 0, 0, 0, 0, width(), height() );
}
示例#28
0
EffectInstance::EffectInstance(Effect *owner, int64_t started, bool right, QWidget *parent)
    :QMainWindow(parent), time_started(started), label(this), owner(owner)
{
    // Set window properties the same as the pony window
    setAttribute(Qt::WA_TranslucentBackground, true);
    setAttribute(Qt::WA_ShowWithoutActivating);

#ifdef Q_WS_X11
    // Disables shadows under the pony window.
    setAttribute(Qt::WA_X11NetWmWindowTypeDock);
#endif

#if defined QT_MAC_USE_COCOA && QT_VERSION >= 0x040800
    // Removes shadows that lag behind animation on OS X. QT 4.8+ needed.
    setAttribute(Qt::WA_MacNoShadow, true);
#endif

#ifdef QT_MAC_USE_COCOA
    // On OS X, tool windows are hidden when another program gains focus.
    Qt::WindowFlags windowflags = Qt::FramelessWindowHint;
#else
    Qt::WindowFlags windowflags = Qt::FramelessWindowHint | Qt::Tool;
#endif

    if(ConfigWindow::getSetting<bool>("general/always-on-top")) {
        windowflags |= Qt::WindowStaysOnTopHint;
    }

#ifdef Q_WS_X11
    if(ConfigWindow::getSetting<bool>("general/bypass-wm")) {
        // Bypass the window manager
        windowflags |= Qt::X11BypassWindowManagerHint;
    }
#endif

    setWindowFlags( windowflags );

#ifdef Q_WS_X11
    // Qt on X11 does not support the skip taskbar/pager window flags, we have to set them ourselves
    // We let Qt initialize the other window properties, which aren't deleted when we replace them with ours
    // (they probably are appended on show())
    Atom window_state = XInternAtom( QX11Info::display(), "_NET_WM_STATE", False );
    Atom window_props[] = {
        XInternAtom( QX11Info::display(), "_NET_WM_STATE_SKIP_TASKBAR", False ),
        XInternAtom( QX11Info::display(), "_NET_WM_STATE_SKIP_PAGER"  , False )
    };

    XChangeProperty( QX11Info::display(), window()->winId(), window_state, XA_ATOM, 32, PropModeReplace, (unsigned char*)&window_props, 2 );

    // Set a null input region mask for the event window, so that it does not interfere with mouseover effects.
    XRectangle rect{0,0,0,0};
    XserverRegion shapeRegion = XFixesCreateRegion(QX11Info::display(), &rect, 1);
    XFixesSetWindowShapeRegion(QX11Info::display(), winId(), ShapeInput, 0, 0, shapeRegion);
    XFixesDestroyRegion(QX11Info::display(), shapeRegion);
#endif
    // TODO: add WS_EX_TRANSPARENT extended window style on windows.

#ifdef Q_WS_X11
    // Make sure the effect gets drawn on the same desktop as the pony
    Atom wm_desktop = XInternAtom(QX11Info::display(), "_NET_WM_DESKTOP", False);
    Atom type_ret;
    int fmt_ret;
    unsigned long nitems_ret;
    unsigned long bytes_after_ret;
    int *desktop = NULL;

    if(XGetWindowProperty(QX11Info::display(), owner->parent_pony->window()->winId(), wm_desktop, 0, 1,
                          False, XA_CARDINAL, &type_ret, &fmt_ret,
                          &nitems_ret, &bytes_after_ret, reinterpret_cast<unsigned char **>(&desktop))
       == Success && desktop != NULL) {
       XChangeProperty(QX11Info::display(), window()->winId(), wm_desktop, XA_CARDINAL, 32, PropModeReplace,
                       reinterpret_cast<unsigned char*>(desktop), 1);
       XFree(desktop);
    }
#endif

    // Load animations and verify them
    // TODO: Do we need to change the direction of active effects? Maybe we only need to display the image for the direction at witch it was spawned.
    animation_left = new QMovie(QString("%1/%2/%3").arg(ConfigWindow::getSetting<QString>("general/pony-directory"), owner->path, owner->image_left ));
    animation_right = new QMovie(QString("%1/%2/%3").arg(ConfigWindow::getSetting<QString>("general/pony-directory"), owner->path, owner->image_right));

    if(!animation_left->isValid())
        qCritical() << "Effect:"<< owner->path <<"Error opening left animation:"<< owner->image_left << "for effect:"<< owner->name;
    if(!animation_right->isValid())
        qCritical() << "Effect:"<< owner->path <<"Error opening right animation:"<< owner->image_right << "for behavior:"<< owner->name;

    animation_left->setCacheMode(QMovie::CacheAll);
    animation_right->setCacheMode(QMovie::CacheAll);

    if(right){
        current_animation = animation_right;
    }else{
        current_animation = animation_left;
    }

    current_animation->jumpToFrame(0);

    image_width = current_animation->currentImage().width();
    image_height = current_animation->currentImage().height();

    if(right){
        offset = get_location(owner->location_right, owner->center_right);
    }else{
        offset = get_location(owner->location_left, owner->center_left);
    }

    current_animation->start();
    update_animation();
    show();
}
gboolean expose_parent(GtkWidget * widget, GdkEventExpose * event) {

    OMWeather *plugin = OMWEATHER(widget);
    GdkDrawable *drawable;
    gint x_offset, y_offset;
    XRenderColor color;
    Picture picture;
    XserverRegion region;
    cairo_t *cr;
    gint radius = 0;
    gint width, height, x, y;

    if (GTK_WIDGET_DRAWABLE(widget) == FALSE) {
        return FALSE;
    }

    gtk_widget_set_size_request(GTK_WIDGET(widget), -1, -1);
    gdk_window_get_internal_paint_info(widget->window, &drawable,
                                       &x_offset, &y_offset);


    picture = hildon_desktop_picture_from_drawable(drawable);

    if (picture == None) {
        return FALSE;
    }

    plugin->clip.x = event->area.x - x_offset;
    plugin->clip.y = event->area.y - y_offset;
    plugin->clip.width = event->area.width + x_offset;
    plugin->clip.height = event->area.height + y_offset;

    region = XFixesCreateRegion(GDK_DISPLAY(), &plugin->clip, 1);

    XFixesSetPictureClipRegion(GDK_DISPLAY(), picture, 0, 0, region);


    color.red = color.blue = color.green = 0;
    color.alpha = 0;

    XRenderFillRectangle(GDK_DISPLAY(), PictOpSrc, picture, &color,
                             0, 0,
                             widget->allocation.width,
                             widget->allocation.height);

    if (app->config->icons_layout < PRESET_NOW){
        radius = app->config->corner_radius;
        cr = gdk_cairo_create(drawable);
        cairo_set_source_rgba(cr,
                              (double)app->config->background_color.red /
                              (MAXSHORT * 2 + 1),
                              (double)app->config->background_color.green /
                              (MAXSHORT * 2 + 1),
                              (double)app->config->background_color.blue /
                              (MAXSHORT * 2 + 1),
                              (double)app->config->alpha_comp / 100);

        width = plugin->clip.width;
        height = plugin->clip.height;
        x = plugin->clip.x;
        y = plugin->clip.y;

        if ((radius > height / 2) || (radius > width / 2)) {
            if (width < height) {
                radius = width / 2 - 1;
            } else {
                radius = height / 2 - 2;
            }
        }

        cairo_move_to(cr, x + radius, y);
        cairo_line_to(cr, x + width - radius, y);
        cairo_curve_to(cr, x + width - radius, y, x + width, y, x + width,
                       y + radius);
        cairo_line_to(cr, x + width, y + height - radius);
        cairo_curve_to(cr, x + width, y + height - radius, x + width,
                       y + height, x + width - radius, y + height);
        cairo_line_to(cr, x + radius, y + height);
        cairo_curve_to(cr, x + radius, y + height, x, y + height, x,
                       y + height - radius);
        cairo_line_to(cr, x, y + radius);
        cairo_curve_to(cr, x, y + radius, x, y, x + radius, y);

        cairo_fill(cr);
        cairo_destroy(cr);
    }
    
    XFixesDestroyRegion(GDK_DISPLAY(), region);
    XRenderFreePicture(GDK_DISPLAY(), picture);

    if (plugin->queueRefresh) {
        redraw_home_window(TRUE);
        plugin->queueRefresh = FALSE;
    }

     
        
    return
        GTK_WIDGET_CLASS(g_type_class_peek_parent
                         (GTK_FRAME_GET_CLASS(widget)))->expose_event
        (widget, event);
}
示例#30
0
static void
process_damage_event (CoglTexturePixmapX11 *tex_pixmap,
                      XDamageNotifyEvent *damage_event)
{
  CoglTexture *tex = COGL_TEXTURE (tex_pixmap);
  Display *display;
  enum
{ DO_NOTHING, NEEDS_SUBTRACT, NEED_BOUNDING_BOX } handle_mode;
  const CoglWinsysVtable *winsys;

  _COGL_GET_CONTEXT (ctxt, NO_RETVAL);

  display = cogl_xlib_renderer_get_display (ctxt->display->renderer);

  COGL_NOTE (TEXTURE_PIXMAP, "Damage event received for %p", tex_pixmap);

  switch (tex_pixmap->damage_report_level)
    {
    case COGL_TEXTURE_PIXMAP_X11_DAMAGE_RAW_RECTANGLES:
      /* For raw rectangles we don't need do look at the damage region
         at all because the damage area is directly given in the event
         struct and the reporting of events is not affected by
         clearing the damage region */
      handle_mode = DO_NOTHING;
      break;

    case COGL_TEXTURE_PIXMAP_X11_DAMAGE_DELTA_RECTANGLES:
    case COGL_TEXTURE_PIXMAP_X11_DAMAGE_NON_EMPTY:
      /* For delta rectangles and non empty we'll query the damage
         region for the bounding box */
      handle_mode = NEED_BOUNDING_BOX;
      break;

    case COGL_TEXTURE_PIXMAP_X11_DAMAGE_BOUNDING_BOX:
      /* For bounding box we need to clear the damage region but we
         don't actually care what it was because the damage event
         itself contains the bounding box of the region */
      handle_mode = NEEDS_SUBTRACT;
      break;

    default:
      g_assert_not_reached ();
    }

  /* If the damage already covers the whole rectangle then we don't
     need to request the bounding box of the region because we're
     going to update the whole texture anyway. */
  if (cogl_damage_rectangle_is_whole (&tex_pixmap->damage_rect,
                                      tex->width,
                                      tex->height))
    {
      if (handle_mode != DO_NOTHING)
        XDamageSubtract (display, tex_pixmap->damage, None, None);
    }
  else if (handle_mode == NEED_BOUNDING_BOX)
    {
      XserverRegion parts;
      int r_count;
      XRectangle r_bounds;
      XRectangle *r_damage;

      /* We need to extract the damage region so we can get the
         bounding box */

      parts = XFixesCreateRegion (display, 0, 0);
      XDamageSubtract (display, tex_pixmap->damage, None, parts);
      r_damage = XFixesFetchRegionAndBounds (display,
                                             parts,
                                             &r_count,
                                             &r_bounds);
      cogl_damage_rectangle_union (&tex_pixmap->damage_rect,
                                   r_bounds.x,
                                   r_bounds.y,
                                   r_bounds.width,
                                   r_bounds.height);
      if (r_damage)
        XFree (r_damage);

      XFixesDestroyRegion (display, parts);
    }
  else
    {
      if (handle_mode == NEEDS_SUBTRACT)
        /* We still need to subtract from the damage region but we
           don't care what the region actually was */
        XDamageSubtract (display, tex_pixmap->damage, None, None);

      cogl_damage_rectangle_union (&tex_pixmap->damage_rect,
                                   damage_event->area.x,
                                   damage_event->area.y,
                                   damage_event->area.width,
                                   damage_event->area.height);
    }

  if (tex_pixmap->winsys)
    {
      /* If we're using the texture from pixmap extension then there's no
         point in getting the region and we can just mark that the texture
         needs updating */
      winsys = _cogl_texture_pixmap_x11_get_winsys (tex_pixmap);
      winsys->texture_pixmap_x11_damage_notify (tex_pixmap);
    }
}