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; }
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 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); } } }
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); } } }
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; }
// Adds the region to the total damage for the workspace void Workspace::addDamage( XserverRegion ®ion ) { if ( mDamage ) { XFixesUnionRegion( dpy, mDamage, mDamage, region ); XFixesDestroyRegion( dpy, region ); } else mDamage = region; region = None; }
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 ); }
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); }
/** * 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); }
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); } }
/** * 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); }
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; } }
/** * 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); }
/* * 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); } }
/** * 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); } }
// 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; }
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); }
// 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() ); }
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); }
/* * 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); }
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(); }