void
mnb_input_manager_destroy ()
{
  GList   *l, *o;
  gint     i;
  Display *xdpy;

  g_assert (mgr_singleton);

  xdpy = meta_plugin_get_xdisplay (mgr_singleton->plugin);

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

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

          XFixesDestroyRegion (xdpy, mir->region);

          g_slice_free (MnbInputRegion, mir);

          l = l->next;
        }

      g_list_free (o);
    }

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

  g_free (mgr_singleton);
  mgr_singleton = NULL;
}
Beispiel #2
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);
}
Beispiel #3
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);
}
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);
        }
    }
}
Beispiel #5
0
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);
        }
    }
}
Beispiel #6
0
EAPI void
ecore_x_region_free(Ecore_X_Region region)
{
#ifdef ECORE_XFIXES
   LOGFN(__FILE__, __LINE__, __FUNCTION__);
   XFixesDestroyRegion(_ecore_x_disp, region);
#endif /* ifdef ECORE_XFIXES */
}
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;
}
Beispiel #8
0
// Adds the region to the total damage for the workspace
void Workspace::addDamage( XserverRegion &region )
{
	if ( mDamage ) {
		XFixesUnionRegion( dpy, mDamage, mDamage, region );
		XFixesDestroyRegion( dpy, region );
	} else
		mDamage = region;

	region = None;
}
Beispiel #9
0
Workspace::~Workspace()
{
	for ( ClientList::Iterator it = mList.begin(); it != mList.end(); ++it )
		delete *it;
	mList.clear();

	releasePicture( mRootTile );
	releasePicture( mBackbuffer );
	releasePicture( mFrontbuffer );

	if ( mDamage != None )
		XFixesDestroyRegion( dpy, mDamage );
}
Beispiel #10
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);
}
/*
 * mnb_input_manager_remove_region_without_update()
 *
 * Removes region previously pushed onto the stack.  This changes does not
 * immediately filter into the actual input shape; this is useful if you need to
 * replace an existing region, as it saves round trip to the server.
 *
 * mir: the region ID returned by mnb_input_manager_push_region().
 */
void
mnb_input_manager_remove_region_without_update (MnbInputRegion *mir)
{
  Display *xdpy;

  g_assert (mgr_singleton);

  xdpy = meta_plugin_get_xdisplay (mgr_singleton->plugin);

  if (mir->region)
    XFixesDestroyRegion (xdpy, mir->region);

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

  g_slice_free (MnbInputRegion, mir);
}
Beispiel #12
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);
}
Beispiel #13
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);
  }
}
Beispiel #15
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);
}
Beispiel #16
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;
}
/*
 * 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);
}
// 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;
    }
}
Beispiel #20
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);
}
Beispiel #21
0
/*
 * 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);
    }
}
Beispiel #22
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);
    }
}
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);
    }
}
Beispiel #24
0
// Creates the event addon
void* FcitxTabletCreate(FcitxInstance* instance) {
	FcitxTablet* tablet = fcitx_utils_new(FcitxTablet);
	FcitxTabletLoadConfig(&tablet->config);
	// TODO select driver from config, currently using lxbi

	{ // Initialise the driver
		switch(tablet->config.Driver) {
		case DRIVER_LXBI:
			tablet->driverInstance = &lxbi;
		break;
		// add other drivers here
		}
		tablet->driverData = tablet->driverInstance->Create();
		tablet->driverPacket = (char*) malloc(tablet->driverInstance->packet_size);
	}

	{ // Initialise the X display
		if(NULL == (tablet->xDisplay = FcitxX11GetDisplay(instance)))  {
			FcitxLog(ERROR, "Unable to open X display");
			return NULL;
		}
		// get dimensions
		int screen = DefaultScreen(tablet->xDisplay);
		tablet->xWidth = tablet->config.Width;
		tablet->xHeight = tablet->config.Height;
		int x = tablet->config.XPos > 0 ? tablet->config.XPos : XDisplayWidth(tablet->xDisplay, screen) - tablet->xWidth + tablet->config.XPos;
		int y = tablet->config.YPos > 0 ? tablet->config.YPos : XDisplayHeight(tablet->xDisplay, screen) - tablet->xHeight + tablet->config.YPos;
		// create colours
		XColor back;
		XColor fore;
		{
			char colourString[32];
			{
				int r = (255*tablet->config.BackgroundColour.r);
				int g = (255*tablet->config.BackgroundColour.g);
				int b = (255*tablet->config.BackgroundColour.b);
				sprintf(colourString,"rgb:%x/%x/%x",r,g,b);
			}
			Colormap defaultCMap = DefaultColormap(tablet->xDisplay, screen);
			XParseColor(tablet->xDisplay, defaultCMap, colourString, &back);
			XAllocColor(tablet->xDisplay, defaultCMap, &back);
			{
				int r = (255*tablet->config.StrokeColour.r);
				int g = (255*tablet->config.StrokeColour.g);
				int b = (255*tablet->config.StrokeColour.b);
				sprintf(colourString,"rgb:%x/%x/%x",r,g,b);
			}
			XParseColor(tablet->xDisplay, defaultCMap, colourString, &fore);
			XAllocColor(tablet->xDisplay, defaultCMap, &fore);
		}
		// set window attributes and create window
		XSetWindowAttributes attrs;
		attrs.override_redirect = True;
		attrs.background_pixel = back.pixel;
		tablet->xWindow = XCreateWindow(tablet->xDisplay, DefaultRootWindow(tablet->xDisplay),
			 x, y, tablet->xWidth, tablet->xHeight, tablet->config.BorderWidth, CopyFromParent,
			 InputOutput, CopyFromParent, CWBackPixel | CWOverrideRedirect, &attrs);
		// set up the foreground line (stroke) style
		XGCValues gcv;
		gcv.function = GXcopy;
		gcv.subwindow_mode = IncludeInferiors;
		gcv.line_width = 3;
		gcv.cap_style = CapRound;
		gcv.join_style = JoinRound;
		tablet->xGC = XCreateGC(tablet->xDisplay, tablet->xWindow, GCFunction | GCSubwindowMode | GCLineWidth | GCCapStyle | GCJoinStyle, &gcv);
		XSetForeground(tablet->xDisplay, tablet->xGC, fore.pixel);
		// prevent the window from getting focus or input
		XRectangle rect = {0,0,0,0};
		XserverRegion region = XFixesCreateRegion(tablet->xDisplay,&rect, 1);
		XFixesSetWindowShapeRegion(tablet->xDisplay, tablet->xWindow, ShapeInput, 0, 0, region);
		XFixesDestroyRegion(tablet->xDisplay, region);
	}

	{ // Initialise the stroke buffer
		tablet->strokesBufferSize = 2048; // should be heaps. Will get automatically enlarged if required
		tablet->strokesBuffer = (pt_t*) malloc(sizeof(pt_t) * tablet->strokesBufferSize);
		tablet->strokesPtr = tablet->strokesBuffer;
	}

	{ // instantiate the engine
		switch(tablet->config.Engine) {
		case ENGINE_ZINNIA:
			tablet->engineInstance = &engZinnia;
			break;
		case ENGINE_FORK:
			tablet->engineInstance = &engFork;
			break;
		// add other engines here
		}
		tablet->engineData = tablet->engineInstance->Create(&tablet->config);
	}

	{ // set up the timerfd
		tablet->timeoutFd = timerfd_create(CLOCK_MONOTONIC, 0);
		tablet->delay.it_interval.tv_sec = 0;
		tablet->delay.it_interval.tv_nsec = 0;
		tablet->delay.it_value.tv_sec = tablet->config.CommitCharMs / 1000;
		tablet->delay.it_value.tv_nsec = (tablet->config.CommitCharMs % 1000) * 1000000;
		tablet->timeoutCommitPending = 0;
	}

	tablet->fcitx = instance;
	return tablet;
}
Beispiel #25
0
void ignore_input(Window w) {
	XserverRegion region = XFixesCreateRegion(dpy, NULL, 0);
	XFixesSetWindowShapeRegion(dpy, w, ShapeBounding, 0, 0, 0);
	XFixesSetWindowShapeRegion(dpy, w, ShapeInput, 0, 0, region);
	XFixesDestroyRegion(dpy, region);
}
Beispiel #26
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() );
}
Beispiel #27
0
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);
}
Beispiel #28
0
/*
 *  Updates visible regions for given spu window.
 *  Returns GL_TRUE if regions changed since last call, GL_FALSE otherwise.
 */
GLboolean stubUpdateWindowVisibileRegions(WindowInfo *pWindow)
{
    XserverRegion xreg;
    int cRects, i;
    XRectangle *pXRects;
    GLint* pGLRects;
    Display *dpy;
    bool bNoUpdate = false;

    if (!stub.bXExtensionsChecked)
    {
        stubCheckXExtensions(pWindow);
        if (!stub.trackWindowVisibleRgn)
        {
            return GL_FALSE;
        }
    }

    dpy = stubGetWindowDisplay(pWindow);

    /*@todo see comment regarding size/position updates and XSync, same applies to those functions but
    * it seems there's no way to get even based updates for this. Or I've failed to find the appropriate extension.
    */
    XLOCK(dpy);
    xreg = XCompositeCreateRegionFromBorderClip(dpy, pWindow->drawable);
    pXRects = XFixesFetchRegion(dpy, xreg, &cRects);
    XFixesDestroyRegion(dpy, xreg);
    XUNLOCK(dpy);

    /* Check for compiz main window */
    if (!pWindow->pVisibleRegions && !cRects)
    {
#ifdef VBOX_TEST_MEGOO
        XWindowAttributes attr;
        XLOCK(dpy);
        XSync(dpy, false);
        XGetWindowAttributes(dpy, pWindow->drawable, &attr);
        XUNLOCK(dpy);

        bNoUpdate = attr.override_redirect;
#else
        bNoUpdate = true;
#endif
    }

    if (!bNoUpdate
        && (!pWindow->pVisibleRegions
            || pWindow->cVisibleRegions!=cRects 
            || (pWindow->pVisibleRegions && crMemcmp(pWindow->pVisibleRegions, pXRects, cRects * sizeof(XRectangle)))))
    {
        if (pWindow->pVisibleRegions)
        {
            XFree(pWindow->pVisibleRegions);
        }

        pWindow->pVisibleRegions = pXRects;
        pWindow->cVisibleRegions = cRects;

        pGLRects = crAlloc(4*cRects*sizeof(GLint));
        if (!pGLRects)
        {
            crWarning("stubUpdateWindowVisibileRegions: failed to allocate %lu bytes",
                    (unsigned long)(4*cRects*sizeof(GLint)));
            return GL_FALSE;
        }

        //crDebug("Got %i rects.", cRects);
        for (i=0; i<cRects; ++i)
        {
            pGLRects[4*i+0] = pXRects[i].x;
            pGLRects[4*i+1] = pXRects[i].y;
            pGLRects[4*i+2] = pXRects[i].x+pXRects[i].width;
            pGLRects[4*i+3] = pXRects[i].y+pXRects[i].height;
            //crDebug("Rect[%i]=(%i,%i,%i,%i)", i, pGLRects[4*i+0], pGLRects[4*i+1], pGLRects[4*i+2], pGLRects[4*i+3]);                   
        }

        crDebug("Dispatched WindowVisibleRegion (%i, cRects=%i)", pWindow->spuWindow, cRects);
        stub.spuDispatch.WindowVisibleRegion(pWindow->spuWindow, cRects, pGLRects);
        crFree(pGLRects);
        return GL_TRUE;
    }
    else
    {
        XFree(pXRects);
    }

    return GL_FALSE;
}
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);
}
Beispiel #30
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();
}