diff --git a/src/lib/ecore_x/Ecore_X.h b/src/lib/ecore_x/Ecore_X.h index b58520c1b3..bb5aedf39e 100644 --- a/src/lib/ecore_x/Ecore_X.h +++ b/src/lib/ecore_x/Ecore_X.h @@ -2432,6 +2432,7 @@ EAPI void ecore_x_region_window_shape_set(Ecore_X_Region region, E EAPI void ecore_x_region_picture_clip_set(Ecore_X_Region region, Ecore_X_Picture picture, int x_origin, int y_origin); EAPI void ecore_x_cursor_show(void); EAPI void ecore_x_cursor_hide(void); +EAPI void ecore_x_root_screen_barriers_set(Ecore_X_Rectangle *screens, int num); /** @since 1.24 */ /** * xfixes selection notification request. diff --git a/src/lib/ecore_x/ecore_x_fixes.c b/src/lib/ecore_x/ecore_x_fixes.c index dd81b674c8..5582c3e3ef 100644 --- a/src/lib/ecore_x/ecore_x_fixes.c +++ b/src/lib/ecore_x/ecore_x_fixes.c @@ -7,6 +7,8 @@ #include "ecore_x_private.h" #include "Ecore_X.h" +#include + static int _fixes_available; #ifdef ECORE_XFIXES static int _fixes_major, _fixes_minor; @@ -434,3 +436,100 @@ ecore_x_cursor_hide(void) } #endif /* ifdef ECORE_XFIXES */ } + +EAPI void +ecore_x_root_screen_barriers_set(Ecore_X_Rectangle *screens, int num) +{ +#ifdef ECORE_XFIXES + static PointerBarrier *bar = NULL; + static int bar_num = 0; + static int bar_alloc = 0; + Region reg, reg2, reg3; + int i, j; + + // clear out old root screen barriers.... + if (bar) + { + for (i = 0; i < bar_num; i++) + { + XFixesDestroyPointerBarrier(_ecore_x_disp, bar[i]); + } + free(bar); + } + bar = NULL; + bar_num = 0; + bar_alloc = 0; + if ((!screens) || (num <= 0)) return; + + // set up new ones given the screen list given + for (i = 0; i < num; i++) + { + XRectangle xrect; + + reg = XCreateRegion(); + reg2 = XCreateRegion(); + xrect.x = screens[i].x - 1; + xrect.y = screens[i].y - 1; + xrect.width = screens[i].width + 2; + xrect.height = screens[i].height + 2; + XUnionRectWithRegion(&xrect, reg, reg2); + XDestroyRegion(reg); + reg = reg2; + + // reg == screen i + 1 pixel surrounding it + for (j = 0; j < num; j++) + { + // create a region representing screen j + reg2 = XCreateRegion(); + reg3 = XCreateRegion(); + xrect.x = screens[j].x; + xrect.y = screens[j].y; + xrect.width = screens[j].width; + xrect.height = screens[j].height; + XUnionRectWithRegion(&xrect, reg2, reg3); + XDestroyRegion(reg2); + reg2 = reg3; + // reg2 == screen j + + reg3 = XCreateRegion(); + XSubtractRegion(reg, reg2, reg3); + XDestroyRegion(reg); + XDestroyRegion(reg2); + reg = reg3; + // reg now has had screen j cut out of the boundary + } + // reg is the result of starting with screen i and then with a + // 1 pixel boundary around it havnig adjacent screens "cut out" + // of that boundary leaving only extra bounds where no screens + // are adjacent + + // walk rects and create barriers + for (j = 0; j < reg->numRects; j++) + { + int x1, y1, x2, y2; + + bar_num++; + if (bar_num > bar_alloc) + { + bar_alloc += 32; + PointerBarrier *t = realloc(bar, bar_alloc * sizeof(PointerBarrier)); + if (!t) + { + bar_num--; + return; + } + bar = t; + } + x1 = reg->rects[j].x1; + y1 = reg->rects[j].y1; + x2 = reg->rects[j].x2 - 1; + y2 = reg->rects[j].y2 - 1; + bar[bar_num - 1] = + XFixesCreatePointerBarrier(_ecore_x_disp, + DefaultRootWindow(_ecore_x_disp), + x1, y1, x2, y2, 0, 0, NULL); + } + XDestroyRegion(reg); + } +#endif +}