2 * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
3 * Copyright (C) 2004-2008 Kim Woelders
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies of the Software, its documentation and marketing & publicity
14 * materials, and acknowledgment shall be given in the documentation, materials
15 * and software packages that this Software was used.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 #include <X11/Xatom.h>
35 #include <X11/Xutil.h>
36 #include <X11/Xresource.h>
37 #include <X11/extensions/shape.h>
39 #include <X11/extensions/Xrender.h>
46 #define DEBUG_PIXMAP 0
51 static Visual *argb_visual = NULL;
52 static Colormap argb_cmap = None;
55 static XContext xid_context = 0;
57 static Win win_first = NULL;
58 static Win win_last = NULL;
60 #define WinBgInvalidate(win) if (win->bg_owned > 0) win->bg_owned = -1
64 WinGetXwin(const Win win)
70 WinGetX(const Win win)
76 WinGetY(const Win win)
82 WinGetW(const Win win)
88 WinGetH(const Win win)
94 WinGetBorderWidth(const Win win)
100 WinGetDepth(const Win win)
106 WinGetVisual(const Win win)
112 WinGetCmap(const Win win)
121 memset(&Dpy, 0, sizeof(Dpy));
129 win = ECALLOC(struct _xwin, 1);
131 win->bgcol = 0xffffffff;
140 Eprintf("EXidDestroy: %p %#lx\n", win, win->xwin);
152 Eprintf("EXidAdd: %p %#lx\n", win, win->xwin);
155 xid_context = XUniqueContext();
157 XSaveContext(disp, win->xwin, xid_context, (XPointer) win);
161 win_first = win_last = win;
165 win->prev = win_last;
166 win_last->next = win;
175 Eprintf("EXidDel: %p %#lx\n", win, win->xwin);
177 if (win == win_first)
181 win_first = win_last = NULL;
185 win_first = win->next;
186 win->next->prev = NULL;
189 else if (win == win_last)
191 win_last = win->prev;
192 win->prev->next = NULL;
196 win->prev->next = win->next;
197 win->next->prev = win->prev;
200 XDeleteContext(disp, win->xwin, xid_context);
207 #define EXidLookup ELookupXwin
210 EXidLookup(Window xwin)
219 if (XFindContext(disp, xwin, xid_context, &xp) == XCNOENT)
227 EXidSet(Window xwin, Win parent, int x, int y, int w, int h, int depth,
228 Visual * visual, Colormap cmap)
233 win->parent = parent;
240 win->visual = visual;
243 Eprintf("EXidSet: %#lx\n", win->xwin);
251 EventCallbackRegister(Win win, int type __UNUSED__, EventCallbackFunc * func,
254 EventCallbackItem *eci;
259 Eprintf("EventCallbackRegister: %p %#lx: func=%p prm=%p\n", win, win->xwin,
264 win->cbl.lst = EREALLOC(EventCallbackItem, win->cbl.lst, win->cbl.num);
265 eci = win->cbl.lst + win->cbl.num - 1;
271 EventCallbackUnregister(Win win, int type __UNUSED__,
272 EventCallbackFunc * func, void *prm)
274 EventCallbackList *ecl;
275 EventCallbackItem *eci;
281 Eprintf("EventCallbackUnregister: %p %#lx: func=%p prm=%p\n", win, win->xwin,
287 for (i = 0; i < ecl->num; i++, eci++)
288 if (eci->func == func && eci->prm == prm)
293 for (; i < ecl->num; i++, eci++)
296 EREALLOC(EventCallbackItem, win->cbl.lst, ecl->num);
308 EventCallbacksProcess(Win win, XEvent * ev)
310 EventCallbackList *ecl;
311 EventCallbackItem *eci;
320 for (i = 0; i < ecl->num; i++, eci++)
322 if (EDebug(EDBUG_TYPE_DISPATCH))
323 Eprintf("EventDispatch: type=%d win=%#lx func=%p prm=%p\n",
324 ev->type, ev->xany.window, eci->func, eci->prm);
325 eci->func(win, ev, eci->prm);
336 ECreateWindow(Win parent, int x, int y, int w, int h, int saveunder)
340 XSetWindowAttributes attr;
342 attr.backing_store = NotUseful;
343 attr.override_redirect = False;
344 attr.colormap = parent->cmap;
345 attr.border_pixel = 0;
346 /* attr.background_pixel = 0; */
347 attr.background_pixmap = None;
348 if ((saveunder == 1) && (Conf.save_under))
349 attr.save_under = True;
350 else if (saveunder == 2)
351 attr.save_under = True;
353 attr.save_under = False;
355 xwin = XCreateWindow(disp, parent->xwin, x, y, w, h, 0,
356 CopyFromParent, InputOutput, CopyFromParent,
357 CWOverrideRedirect | CWSaveUnder | CWBackingStore |
358 CWColormap | CWBackPixmap | CWBorderPixel, &attr);
359 win = EXidSet(xwin, parent, x, y, w, h, parent->depth, parent->visual,
367 ECreateWindowVDC(Win parent, int x, int y, int w, int h,
368 Visual * vis, unsigned int depth, Colormap cmap)
372 XSetWindowAttributes attr;
374 attr.background_pixmap = None;
375 attr.border_pixel = 0;
376 attr.backing_store = NotUseful;
377 attr.save_under = False;
378 attr.override_redirect = False;
379 attr.colormap = cmap;
381 xwin = XCreateWindow(disp, parent->xwin, x, y, w, h, 0,
382 depth, InputOutput, vis,
383 CWOverrideRedirect | CWSaveUnder | CWBackingStore |
384 CWColormap | CWBackPixmap | CWBorderPixel, &attr);
385 win = EXidSet(xwin, parent, x, y, w, h, depth, vis, cmap);
391 ECreateArgbWindow(Win parent, int x, int y, int w, int h, Win cwin)
397 if (cwin && Conf.testing.argb_clients_inherit_attr)
407 argb_visual = EVisualFindARGB();
409 XCreateColormap(disp, WinGetXwin(VROOT), argb_visual,
417 return ECreateWindowVDC(parent, x, y, w, h, vis, depth, cmap);
422 ECreateWindowVD(Win parent, int x, int y, int w, int h,
423 Visual * vis, unsigned int depth)
427 if (!vis || depth == 0)
430 cmap = XCreateColormap(disp, WinGetXwin(VROOT), vis, AllocNone);
432 return ECreateWindowVDC(parent, x, y, w, h, vis, depth, cmap);
436 #endif /* USE_COMPOSITE */
439 ECreateObjectWindow(Win parent, int x, int y, int w, int h, int saveunder,
450 case WIN_TYPE_NO_ARGB:
452 case WIN_TYPE_CLIENT:
453 if (Conf.testing.argb_clients || EVisualIsARGB(cwin->visual))
456 case WIN_TYPE_INTERNAL:
457 if (Conf.testing.argb_internal_objects)
461 case WIN_TYPE_GLX: /* Internal GL */
464 ECreateWindowVD(parent, x, y, w, h, EGlGetVisual(), EGlGetDepth());
472 win = ECreateArgbWindow(parent, x, y, w, h, cwin);
474 win = ECreateWindow(parent, x, y, w, h, saveunder);
477 win = ECreateWindow(parent, x, y, w, h, saveunder);
486 ECreateClientWindow(Win parent, int x, int y, int w, int h)
489 if (Conf.testing.argb_internal_clients)
490 return ECreateArgbWindow(parent, x, y, w, h, NULL);
493 return ECreateWindow(parent, x, y, w, h, 0);
497 ECreateEventWindow(Win parent, int x, int y, int w, int h)
501 XSetWindowAttributes attr;
503 attr.override_redirect = False;
505 xwin = XCreateWindow(disp, parent->xwin, x, y, w, h, 0, 0, InputOnly,
506 CopyFromParent, CWOverrideRedirect, &attr);
507 win = EXidSet(xwin, parent, x, y, w, h, 0, NULL, None);
514 * create a window which will accept the keyboard focus when no other
518 ECreateFocusWindow(Win parent, int x, int y, int w, int h)
521 XSetWindowAttributes attr;
523 attr.backing_store = NotUseful;
524 attr.override_redirect = False;
525 attr.colormap = WinGetCmap(VROOT);
526 attr.border_pixel = 0;
527 attr.background_pixel = 0;
528 attr.save_under = False;
529 attr.event_mask = KeyPressMask | FocusChangeMask;
533 win = XCreateWindow(disp, parent, x, y, w, h, 0, 0, InputOnly,
535 CWOverrideRedirect | CWSaveUnder | CWBackingStore |
536 CWColormap | CWBackPixel | CWBorderPixel | CWEventMask,
539 XSetWindowBackground(disp, win, 0);
540 XMapWindow(disp, win);
541 XSetInputFocus(disp, win, RevertToParent, CurrentTime);
548 EMoveWindow(Win win, int x, int y)
554 Eprintf("EMoveWindow: %p %#lx: %d,%d %dx%d -> %d,%d\n",
555 win, win->xwin, win->x, win->y, win->w, win->h, x, y);
557 if ((x == win->x) && (y == win->y))
563 XMoveWindow(disp, win->xwin, x, y);
567 EResizeWindow(Win win, int w, int h)
572 if ((w == win->w) && (h == win->h))
575 WinBgInvalidate(win);
579 XResizeWindow(disp, win->xwin, w, h);
583 EMoveResizeWindow(Win win, int x, int y, int w, int h)
589 Eprintf("EMoveResizeWindow: %p %#lx: %d,%d %dx%d -> %d,%d %dx%d\n",
590 win, win->xwin, win->x, win->y, win->w, win->h, x, y, w, h);
592 if ((w == win->w) && (h == win->h) && (x == win->x) && (y == win->y))
595 if (w != win->w || h != win->h)
596 WinBgInvalidate(win);
603 XMoveResizeWindow(disp, win->xwin, x, y, w, h);
615 for (win2 = win_first; win2; win2 = win2->next)
617 if (win2->parent != win)
627 EDestroyWindow(Win win)
636 Eprintf("ExDestroyWindow: %p %#lx\n", win, win->xwin);
638 if (win->parent != None)
640 EFreeWindowBackgroundPixmap(win);
641 XDestroyWindow(disp, win->xwin);
644 /* Mark the ones to be deleted */
645 nsub = ExDelTree(win);
653 /* Delete entire tree */
654 for (win = win_first; win; win = next)
667 unsigned int w, h, bw, depth;
672 XGetGeometry(disp, win->xwin, &rr, &x, &y, &w, &h, &bw, &depth);
674 Eprintf("EWindowSync: %p %#lx: %d,%d %dx%d -> %d,%d %dx%d\n",
675 win, win->xwin, win->x, win->y, win->w, win->h, x, y, w, h);
685 EWindowSetGeometry(Win win, int x, int y, int w, int h, int bw)
698 EWindowSetMapped(Win win, int mapped)
703 win->mapped = mapped;
707 EXWindowGetParent(Window xwin)
711 unsigned int nch = 0;
714 if (!XQueryTree(disp, xwin, &rt, &parent, &pch, &nch))
719 #if 0 /* FIXME - Remove? */
720 win = EXidLookup(xwin);
722 win->parent = parent;
729 ECreateWinFromXwin(Window xwin)
734 unsigned int w, h, bw, depth;
736 if (!XGetGeometry(disp, xwin, &rr, &x, &y, &w, &h, &bw, &depth))
749 win->visual = WinGetVisual(VROOT);
750 win->cmap = WinGetCmap(VROOT);
762 ERegisterWindow(Window xwin, XWindowAttributes * pxwa)
765 XWindowAttributes xwa;
767 win = EXidLookup(xwin);
774 if (!XGetWindowAttributes(disp, xwin, pxwa))
779 Eprintf("ERegisterWindow %#lx %d+%d %dx%d\n", win, x, y, w, h);
781 win = EXidSet(xwin, None, pxwa->x, pxwa->y, pxwa->width, pxwa->height,
782 pxwa->depth, pxwa->visual, pxwa->colormap);
783 win->mapped = pxwa->map_state != IsUnmapped;
791 EUnregisterXwin(Window xwin)
795 win = EXidLookup(xwin);
799 /* FIXME - We shouldn't go here */
801 #if 1 /* Debug - Fix code if we get here */
802 Eprintf("*** FIXME - EUnregisterXwin %#lx\n", xwin);
807 EUnregisterWindow(Win win)
815 Eprintf("EUnregisterWindow(%#lx) Ignored (%d callbacks remain)\n",
816 win->xwin, win->cbl.num);
833 XMapWindow(disp, win->xwin);
837 EUnmapWindow(Win win)
846 XUnmapWindow(disp, win->xwin);
850 EReparentWindow(Win win, Win parent, int x, int y)
857 ("EReparentWindow: %p %#lx: %d %#lx->%#lx %d,%d %dx%d -> %d,%d\n",
858 win, win->xwin, win->mapped, win->parent, parent->xwin,
859 win->x, win->y, win->w, win->h, x, y);
861 if (parent == win->parent)
863 if ((x != win->x) || (y != win->y))
867 XMoveWindow(disp, win->xwin, x, y);
873 win->parent = parent;
878 XReparentWindow(disp, win->xwin, parent->xwin, x, y);
889 XRaiseWindow(disp, win->xwin);
897 XMapRaised(disp, win->xwin);
901 EXGetGeometry(Drawable draw, Window * root_return, int *x, int *y,
902 int *w, int *h, int *bw, int *depth)
907 unsigned int ww, hh, bb, dd;
909 ok = XGetGeometry(disp, draw, &rr, &xx, &yy, &ww, &hh, &bb, &dd);
931 Eprintf("EGetGeometry win=%#x, error %d\n", (unsigned)win, ok);
937 EGetGeometry(Win win, Window * root_return, int *x, int *y,
938 int *w, int *h, int *bw, int *depth)
956 *root_return = WinGetXwin(VROOT);
962 EGetWindowAttributes(Win win, XWindowAttributes * pxwa)
969 pxwa->width = win->w;
970 pxwa->height = win->h;
971 pxwa->border_width = win->bw;
972 pxwa->depth = win->depth;
973 pxwa->visual = win->visual;
974 pxwa->colormap = win->cmap;
979 EConfigureWindow(Win win, unsigned int mask, XWindowChanges * wc)
986 if ((mask & CWX) && (wc->x != win->x))
991 if ((mask & CWY) && (wc->y != win->y))
996 if ((mask & CWWidth) && (wc->width != win->w))
998 WinBgInvalidate(win);
1002 if ((mask & CWHeight) && (wc->height != win->h))
1004 WinBgInvalidate(win);
1005 win->h = wc->height;
1009 if ((doit) || (mask & (CWBorderWidth | CWSibling | CWStackMode)))
1010 XConfigureWindow(disp, win->xwin, mask, wc);
1015 ESetWindowBackgroundPixmap(Win win, Pixmap pmap)
1020 if (win->bgpmap && win->bg_owned)
1021 EFreeWindowBackgroundPixmap(win);
1023 win->bg_owned = 0; /* Don't manage pixmap */
1024 win->bgcol = 0xffffffff; /* Hmmm.. */
1026 XSetWindowBackgroundPixmap(disp, win->xwin, pmap);
1030 EGetWindowBackgroundPixmap(Win win)
1037 if (win->bg_owned < 0) /* Free if invalidated */
1038 EFreeWindowBackgroundPixmap(win);
1039 else if (win->bgpmap)
1042 /* Allocate/set new */
1043 pmap = ECreatePixmap(win, win->w, win->h, 0);
1044 ESetWindowBackgroundPixmap(win, pmap);
1045 win->bg_owned = 1; /* Manage pixmap */
1051 EFreeWindowBackgroundPixmap(Win win)
1053 if (!win || !win->bgpmap)
1057 EFreePixmap(win->bgpmap);
1063 ESetWindowBackground(Win win, unsigned int col)
1070 EFreeWindowBackgroundPixmap(win);
1073 else if (win->bgcol != col)
1080 XSetWindowBackground(disp, win->xwin, col);
1084 ESelectInput(Win win, unsigned int event_mask)
1086 XSelectInput(disp, win->xwin, event_mask);
1090 EChangeWindowAttributes(Win win, unsigned int mask, XSetWindowAttributes * attr)
1092 XChangeWindowAttributes(disp, win->xwin, mask, attr);
1096 ESetWindowBorderWidth(Win win, unsigned int bw)
1098 XSetWindowBorderWidth(disp, win->xwin, bw);
1102 ERaiseWindow(Win win)
1104 XRaiseWindow(disp, win->xwin);
1108 ELowerWindow(Win win)
1110 XLowerWindow(disp, win->xwin);
1114 EXRestackWindows(Window * windows, int nwindows)
1116 XRestackWindows(disp, windows, nwindows);
1120 EClearWindow(Win win)
1122 XClearWindow(disp, win->xwin);
1126 EClearArea(Win win, int x, int y, unsigned int w, unsigned int h)
1128 XClearArea(disp, win->xwin, x, y, w, h, False);
1132 ETranslateCoordinates(Win src_w, Win dst_w, int src_x, int src_y,
1133 int *dest_x_return, int *dest_y_return,
1134 Window * child_return)
1139 child_return = &child;
1141 return XTranslateCoordinates(disp, src_w->xwin, dst_w->xwin, src_x, src_y,
1142 dest_x_return, dest_y_return, child_return);
1146 EXWarpPointer(Window xwin, int x, int y)
1148 XWarpPointer(disp, None, xwin, 0, 0, 0, 0, x, y);
1152 EXQueryPointer(Window xwin, int *px, int *py, Window * pchild,
1153 unsigned int *pmask)
1160 xwin = WinGetXwin(VROOT);
1171 return XQueryPointer(disp, xwin, &root, pchild, &root_x, &root_y, px, py,
1176 EQueryPointer(Win win, int *px, int *py, Window * pchild, unsigned int *pmask)
1180 xwin = (win) ? win->xwin : WinGetXwin(VROOT);
1182 return EXQueryPointer(xwin, px, py, pchild, pmask);
1186 ESelectInputChange(Win win, unsigned long set, unsigned long clear)
1188 XWindowAttributes xwa;
1190 XGetWindowAttributes(disp, win->xwin, &xwa);
1191 xwa.your_event_mask |= set;
1192 xwa.your_event_mask &= ~clear;
1193 XSelectInput(disp, win->xwin, xwa.your_event_mask);
1197 EDrawableCheck(Drawable draw, int grab)
1207 ok = EXGetGeometry(draw, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
1216 EKeysymToKeycode(KeySym keysym)
1218 return XKeysymToKeycode(disp, keysym);
1222 EKeynameToKeycode(const char *name)
1224 return XKeysymToKeycode(disp, XStringToKeysym(name));
1228 EKeycodeToString(KeyCode keycode, int ix)
1230 return XKeysymToString(XKeycodeToKeysym(disp, keycode, ix));
1234 EInternAtom(const char *name)
1236 return XInternAtom(disp, name, False);
1239 #define DEBUG_SHAPE_OPS 0
1240 #define DEBUG_SHAPE_PROPAGATE 0
1242 #if DEBUG_SHAPE_OPS || DEBUG_SHAPE_PROPAGATE
1244 EShapeShow(const char *txt, Window xwin, XRectangle * pr, int nr)
1248 Eprintf("%s %#lx nr=%d\n", txt, xwin, nr);
1249 for (i = 0; i < nr; i++)
1250 Eprintf(" %d - %4d,%4d %4dx%4d\n", i,
1251 pr[i].x, pr[i].y, pr[i].width, pr[i].height);
1256 EShapeUpdate(Win win)
1265 XShapeGetRectangles(disp, win->xwin, ShapeBounding, &(win->num_rect),
1269 if (win->num_rect == 1)
1271 if ((win->rects[0].x == 0) && (win->rects[0].y == 0)
1272 && (win->rects[0].width == win->w)
1273 && (win->rects[0].height == win->h))
1278 XShapeCombineMask(disp, win->xwin, ShapeBounding, 0, 0,
1282 else if (win->num_rect > 4096)
1284 Eprintf("*** EShapeUpdate: nrect=%d - Not likely, ignoring.\n",
1286 XShapeCombineMask(disp, win->xwin, ShapeBounding, 0, 0, None,
1298 EShapeShow("EShapeUpdate", win->xwin, win->rects, win->num_rect);
1303 EShapeCombineMask(Win win, int dest, int x, int y, Pixmap pmap, int op)
1310 if (win->rects || win->num_rect < 0)
1319 Eprintf("EShapeCombineMask %#lx %d,%d %dx%d mask=%#lx wassh=%d\n",
1320 win->xwin, win->x, win->y, win->w, win->h, pmap, wasshaped);
1324 XShapeCombineMask(disp, win->xwin, dest, x, y, pmap, op);
1328 XShapeCombineMask(disp, win->xwin, dest, x, y, pmap, op);
1332 EShapeCombineMaskTiled(Win win, int dest, int x, int y,
1333 Pixmap pmap, int op, int w, int h)
1339 gcv.fill_style = FillTiled;
1341 gcv.ts_x_origin = 0;
1342 gcv.ts_y_origin = 0;
1343 tm = ECreatePixmap(win, w, h, 1);
1344 gc = EXCreateGC(tm, GCFillStyle | GCTile |
1345 GCTileStipXOrigin | GCTileStipYOrigin, &gcv);
1346 XFillRectangle(disp, tm, gc, 0, 0, w, h);
1348 EShapeCombineMask(win, dest, x, y, tm, op);
1353 EShapeCombineRectangles(Win win, int dest, int x, int y,
1354 XRectangle * rect, int n_rects, int op, int ordering)
1359 Eprintf("EShapeCombineRectangles %#lx %d\n", win->xwin, n_rects);
1362 if (n_rects == 1 && op == ShapeSet)
1364 if ((rect[0].x == 0) && (rect[0].y == 0) &&
1365 (rect[0].width == win->w) && (rect[0].height == win->h))
1370 XShapeCombineMask(disp, win->xwin, dest, x, y, None, op);
1374 XShapeCombineRectangles(disp, win->xwin, dest, x, y, rect, n_rects, op,
1378 /* Limit shape to window extents */
1384 XShapeCombineRectangles(disp, win->xwin, ShapeBounding, 0, 0, &r,
1385 1, ShapeIntersect, Unsorted);
1391 EShapeCombineShape(Win win, int dest, int x, int y,
1392 Win src_win, int src_kind, int op)
1397 XShapeCombineShape(disp, win->xwin, dest, x, y, src_win->xwin, src_kind, op);
1402 EShapePropagate(Win win)
1405 unsigned int num_rects;
1408 XRectangle *rects, *rectsn, *rl;
1410 if (!win || win->w <= 0 || win->h <= 0)
1413 #if DEBUG_SHAPE_PROPAGATE
1414 Eprintf("EShapePropagate %#lx %d,%d %dx%d\n", win->xwin,
1415 win->x, win->y, win->w, win->h);
1421 /* go through all child windows and create/inset spans */
1422 for (xch = win_first; xch; xch = xch->next)
1424 if (xch->parent != win)
1427 #if DEBUG_SHAPE_PROPAGATE > 1
1428 Eprintf("%#lx(%d): %4d,%4d %4dx%4d\n", xch->xwin, xch->mapped,
1429 xch->x, xch->y, xch->w, xch->h);
1438 if (x >= win->w || y >= win->h || x + w < 0 || y + h < 0)
1446 rectsn = EREALLOC(XRectangle, rects, num_rects + rn);
1451 /* go through all clip rects in thsi window's shape */
1452 for (k = 0; k < rn; k++)
1454 /* for each clip rect, add it to the rect list */
1455 rects[num_rects + k].x = x + rl[k].x;
1456 rects[num_rects + k].y = y + rl[k].y;
1457 rects[num_rects + k].width = rl[k].width;
1458 rects[num_rects + k].height = rl[k].height;
1459 #if DEBUG_SHAPE_PROPAGATE > 1
1460 Eprintf(" - %d: %4d,%4d %4dx%4d\n", k,
1461 rects[num_rects + k].x,
1462 rects[num_rects + k].y, rects[num_rects + k].width,
1463 rects[num_rects + k].height);
1471 rectsn = EREALLOC(XRectangle, rects, num_rects + 1);
1476 rects[num_rects].x = x;
1477 rects[num_rects].y = y;
1478 rects[num_rects].width = w;
1479 rects[num_rects].height = h;
1484 #if DEBUG_SHAPE_PROPAGATE
1485 EShapeShow("EShapePropagate", win->xwin, rects, num_rects);
1488 /* set the rects as the shape mask */
1491 EShapeCombineRectangles(win, ShapeBounding, 0, 0, rects,
1492 num_rects, ShapeSet, Unsorted);
1498 EShapeCombineRectangles(win, ShapeBounding, 0, 0, NULL, 0, ShapeSet,
1502 return win->num_rect;
1506 EShapeCombineMask(win, ShapeBounding, 0, 0, None, ShapeSet);
1511 EShapeCheck(Win win)
1516 return win->num_rect;
1520 EShapeSetMask(Win win, int x, int y, Pixmap mask)
1522 EShapeCombineMask(win, ShapeBounding, x, y, mask, ShapeSet);
1526 EShapeUnionMask(Win win, int x, int y, Pixmap mask)
1528 EShapeCombineMask(win, ShapeBounding, x, y, mask, ShapeUnion);
1532 EShapeSetMaskTiled(Win win, int x, int y, Pixmap mask, int w, int h)
1534 EShapeCombineMaskTiled(win, ShapeBounding, x, y, mask, ShapeSet, w, h);
1538 EShapeSetRects(Win win, int x, int y, XRectangle * rect, int n_rects)
1540 EShapeCombineRectangles(win, ShapeBounding, x, y, rect, n_rects,
1541 ShapeSet, Unsorted);
1545 EShapeUnionRects(Win win, int x, int y, XRectangle * rect, int n_rects)
1547 EShapeCombineRectangles(win, ShapeBounding, x, y, rect, n_rects,
1548 ShapeUnion, Unsorted);
1552 EShapeSetShape(Win win, int x, int y, Win src_win)
1554 EShapeCombineShape(win, ShapeBounding, x, y,
1555 src_win, ShapeBounding, ShapeSet);
1556 return win->num_rect != 0;
1559 /* Build mask from window shape rects */
1561 EWindowGetShapePixmap(Win win)
1566 const XRectangle *rect;
1568 if (win->num_rect == 0) /* Not shaped */
1571 mask = ECreatePixmap(win, win->w, win->h, 1);
1572 gc = EXCreateGC(mask, 0, NULL);
1574 XSetForeground(disp, gc, 0);
1575 XFillRectangle(disp, mask, gc, 0, 0, win->w, win->h);
1577 XSetForeground(disp, gc, 1);
1579 for (i = 0; i < win->num_rect; i++)
1580 XFillRectangle(disp, mask, gc, rect[i].x, rect[i].y,
1581 rect[i].width, rect[i].height);
1589 ECreatePixmap(Win win, unsigned int width, unsigned int height,
1597 pmap = XCreatePixmap(disp, win->xwin, width, height, depth);
1599 Eprintf("%s: %#lx\n", __func__, pmap);
1605 EFreePixmap(Pixmap pmap)
1608 Eprintf("%s: %#lx\n", __func__, pmap);
1610 XFreePixmap(disp, pmap);
1614 EXCreatePixmapCopy(Pixmap src, unsigned int w, unsigned int h,
1620 pmap = XCreatePixmap(disp, src, w, h, depth);
1621 gc = EXCreateGC(src, 0, NULL);
1622 XCopyArea(disp, src, pmap, gc, 0, 0, w, h, 0, 0);
1625 Eprintf("%s: %#lx\n", __func__, pmap);
1631 EXCopyArea(Drawable src, Drawable dst, int sx, int sy, unsigned int w,
1632 unsigned int h, int dx, int dy)
1636 gc = EXCreateGC(src, 0, NULL);
1637 XCopyArea(disp, src, dst, gc, sx, sy, w, h, dx, dy);
1642 EXCopyAreaTiled(Drawable src, Pixmap mask, Drawable dst, int sx, int sy,
1643 unsigned int w, unsigned int h, int dx, int dy)
1648 gcv.fill_style = FillTiled;
1650 gcv.ts_x_origin = sx;
1651 gcv.ts_y_origin = sy;
1652 gcv.clip_mask = mask;
1653 gc = EXCreateGC(dst, GCFillStyle |
1654 GCTile | GCTileStipXOrigin | GCTileStipYOrigin | GCClipMask,
1656 XFillRectangle(disp, dst, gc, dx, dy, w, h);
1661 EXCreateGC(Drawable draw, unsigned long mask, XGCValues * val)
1667 mask |= GCGraphicsExposures;
1668 val->graphics_exposures = False;
1672 mask = GCGraphicsExposures;
1674 val->graphics_exposures = False;
1676 return XCreateGC(disp, draw, mask, val);
1682 return XFreeGC(disp, gc);
1686 EXSendEvent(Window xwin, long event_mask, XEvent * ev)
1688 XSendEvent(disp, xwin, False, event_mask, ev);
1692 EAllocColor(Colormap cmap, EColor * pec)
1696 EAllocXColor(cmap, &xc, pec);
1697 pec->pixel = xc.pixel;
1701 EAllocXColor(Colormap cmap, XColor * pxc, EColor * pec)
1703 pxc->red = pec->red << 8;
1704 pxc->green = pec->green << 8;
1705 pxc->blue = pec->blue << 8;
1706 XAllocColor(disp, cmap, pxc);
1714 EDisplayOpen(const char *dstr, int scr)
1720 /* Override screen */
1721 Esnprintf(dbuf, sizeof(dbuf) - 10, "%s", dstr);
1722 s = strchr(dbuf, ':');
1729 Esnprintf(dbuf + strlen(dbuf), 10, ".%d", scr);
1735 disp = ecore_x_display_get();
1737 disp = XOpenDisplay(dstr);
1740 return (disp) ? 0 : -1;
1751 XCloseDisplay(disp);
1753 XSetErrorHandler(NULL);
1754 XSetIOErrorHandler(NULL);
1759 EDisplayDisconnect(void)
1764 ecore_x_disconnect();
1766 close(ConnectionNumber(disp));
1768 XSetErrorHandler(NULL);
1769 XSetIOErrorHandler(NULL);
1775 HandleXError(Display * dpy, XErrorEvent * ev)
1781 XGetErrorText(dpy, ev->error_code, buf, 63);
1782 Eprintf("*** ERROR: xid=%#lx error=%i req=%i/%i: %s\n",
1783 ev->resourceid, ev->error_code,
1784 ev->request_code, ev->minor_code, buf);
1787 Dpy.last_error_code = ev->error_code;
1792 static void (*EXIOErrorFunc) (void) = NULL;
1795 HandleXIOError(Display * dpy __UNUSED__)
1806 EDisplaySetErrorHandlers(void (*fatal) (void))
1808 /* set up an error handler for then E would normally have fatal X errors */
1809 XSetErrorHandler(HandleXError);
1811 /* set up a handler for when the X Connection goes down */
1812 EXIOErrorFunc = fatal;
1813 XSetIOErrorHandler(HandleXIOError);
1823 if (Dpy.server_grabbed <= 0)
1825 if (EDebug(EDBUG_TYPE_GRABS))
1826 Eprintf("EGrabServer\n");
1829 Dpy.server_grabbed++;
1835 if (Dpy.server_grabbed == 1)
1837 XUngrabServer(disp);
1839 if (EDebug(EDBUG_TYPE_GRABS))
1840 Eprintf("EUngrabServer\n");
1842 Dpy.server_grabbed--;
1843 if (Dpy.server_grabbed < 0)
1844 Dpy.server_grabbed = 0;
1848 EServerIsGrabbed(void)
1850 return Dpy.server_grabbed;
1860 ESync(unsigned int mask)
1862 if (mask & Conf.testing.no_sync_mask)
1874 EVisualFindARGB(void)
1876 XVisualInfo *xvi, xvit;
1880 xvit.screen = Dpy.screen;
1883 xvit.c_class = TrueColor;
1885 xvit.class = TrueColor;
1888 xvi = XGetVisualInfo(disp,
1889 VisualScreenMask | VisualDepthMask | VisualClassMask,
1894 for (i = 0; i < num; i++)
1896 if (EVisualIsARGB(xvi[i].visual))
1900 vis = (i < num) ? xvi[i].visual : NULL;
1908 EVisualIsARGB(Visual * vis)
1910 XRenderPictFormat *pictfmt;
1912 pictfmt = XRenderFindVisualFormat(disp, vis);
1917 Eprintf("Visual ID=%#lx Type=%d, alphamask=%d\n", vis->visualid,
1918 pictfmt->type, pictfmt->direct.alphaMask);
1920 return pictfmt->type == PictTypeDirect && pictfmt->direct.alphaMask;
1932 static Window win_ts = None;
1933 XSetWindowAttributes attr;
1938 attr.override_redirect = False;
1939 win_ts = XCreateWindow(disp, WinGetXwin(VROOT), -100, -100, 1, 1, 0,
1940 CopyFromParent, InputOnly, CopyFromParent,
1941 CWOverrideRedirect, &attr);
1942 XSelectInput(disp, win_ts, PropertyChangeMask);
1945 XChangeProperty(disp, win_ts, XA_WM_NAME, XA_STRING, 8,
1946 PropModeAppend, (unsigned char *)"", 0);
1947 XWindowEvent(disp, win_ts, PropertyChangeMask, &ev);
1949 return ev.xproperty.time;