| 1 | /** @file
|
|---|
| 2 | * X11 visible window displayer. Uses the same algorithm as VirtualBox's
|
|---|
| 3 | * seamless mode to find windows and their shapes.
|
|---|
| 4 | */
|
|---|
| 5 |
|
|---|
| 6 | /*
|
|---|
| 7 | * Copyright (C) 2008 Oracle Corporation
|
|---|
| 8 | *
|
|---|
| 9 | * This file is part of VirtualBox Open Source Edition (OSE), as
|
|---|
| 10 | * available from http://www.virtualbox.org. This file is free software;
|
|---|
| 11 | * you can redistribute it and/or modify it under the terms of the GNU
|
|---|
| 12 | * General Public License (GPL) as published by the Free Software
|
|---|
| 13 | * Foundation, in version 2 as it comes in the "COPYING" file of the
|
|---|
| 14 | * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
|
|---|
| 15 | * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
|
|---|
| 16 | */
|
|---|
| 17 |
|
|---|
| 18 | #include <limits.h>
|
|---|
| 19 | #include <stdio.h>
|
|---|
| 20 | #include <stdlib.h>
|
|---|
| 21 |
|
|---|
| 22 | #include <set>
|
|---|
| 23 |
|
|---|
| 24 | #include <X11/Xatom.h>
|
|---|
| 25 | #include <X11/Xmu/WinUtil.h>
|
|---|
| 26 | #include <X11/extensions/shape.h>
|
|---|
| 27 |
|
|---|
| 28 | /**
|
|---|
| 29 | * Checks whether a window is a virtual root.
|
|---|
| 30 | * @returns true if it is, false otherwise
|
|---|
| 31 | * @param hWin the window to be examined
|
|---|
| 32 | */
|
|---|
| 33 | bool isVirtualRoot(Display *pDisplay, Window hWin)
|
|---|
| 34 | {
|
|---|
| 35 | unsigned char *pcWinType;
|
|---|
| 36 | Atom *windowType;
|
|---|
| 37 | bool rc = false;
|
|---|
| 38 | Atom actTypeAtom = None;
|
|---|
| 39 | int actFmt = 0;
|
|---|
| 40 | unsigned long nItems = 0, nBytesAfter = 0;
|
|---|
| 41 | unsigned char *propVal = 0;
|
|---|
| 42 |
|
|---|
| 43 | Atom atomNWWT = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE", True);
|
|---|
| 44 | XGetWindowProperty(pDisplay, hWin, atomNWWT, 0, LONG_MAX, False, XA_ATOM,
|
|---|
| 45 | &actTypeAtom, &actFmt, &nItems, &nBytesAfter, &pcWinType);
|
|---|
| 46 | windowType = (Atom *) pcWinType;
|
|---|
| 47 | if ( windowType
|
|---|
| 48 | && ( *windowType
|
|---|
| 49 | == XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE_DESKTOP", True)))
|
|---|
| 50 | rc = true;
|
|---|
| 51 | XFree(pcWinType);
|
|---|
| 52 | return rc;
|
|---|
| 53 | }
|
|---|
| 54 |
|
|---|
| 55 |
|
|---|
| 56 | int main()
|
|---|
| 57 | {
|
|---|
| 58 | Display *pDisplay = XOpenDisplay(NULL);
|
|---|
| 59 | /** Dummy values for XShapeQueryExtension */
|
|---|
| 60 | int error, event;
|
|---|
| 61 | Bool fSupportsShape = XShapeQueryExtension(pDisplay, &event, &error);
|
|---|
| 62 | std::set<Window> windowsFound;
|
|---|
| 63 | if (!pDisplay)
|
|---|
| 64 | {
|
|---|
| 65 | printf("Unable to access the X11 window system. Exiting.\n");
|
|---|
| 66 | exit(1);
|
|---|
| 67 | }
|
|---|
| 68 | Window hRoot, hParent, *phChildren;
|
|---|
| 69 | unsigned cChildren;
|
|---|
| 70 | if (!XQueryTree(pDisplay, DefaultRootWindow(pDisplay), &hRoot, &hParent,
|
|---|
| 71 | &phChildren, &cChildren))
|
|---|
| 72 | {
|
|---|
| 73 | printf("Unable to enumerate active windows. Exiting.\n");
|
|---|
| 74 | exit(1);
|
|---|
| 75 | }
|
|---|
| 76 | for (unsigned i = 0; i < cChildren; ++i)
|
|---|
| 77 | {
|
|---|
| 78 | Window hWin = phChildren[i];
|
|---|
| 79 | Window hClient = XmuClientWindow(pDisplay, hWin);
|
|---|
| 80 | if (!windowsFound.insert(hClient).second)
|
|---|
| 81 | continue;
|
|---|
| 82 | XWindowAttributes winAttrib;
|
|---|
| 83 | if (!XGetWindowAttributes(pDisplay, hWin, &winAttrib))
|
|---|
| 84 | continue;
|
|---|
| 85 | if (winAttrib.map_state == IsUnmapped)
|
|---|
| 86 | continue;
|
|---|
| 87 | XSizeHints dummyHints;
|
|---|
| 88 | long dummyLong;
|
|---|
| 89 | if (!XGetWMNormalHints(pDisplay, hClient, &dummyHints, &dummyLong))
|
|---|
| 90 | continue;
|
|---|
| 91 | if (isVirtualRoot(pDisplay, hClient))
|
|---|
| 92 | continue;
|
|---|
| 93 | XRectangle *pRects = NULL;
|
|---|
| 94 | int cRects = 0, iOrdering;
|
|---|
| 95 | bool hasShape = false;
|
|---|
| 96 | if (fSupportsShape)
|
|---|
| 97 | {
|
|---|
| 98 | pRects = XShapeGetRectangles(pDisplay, hWin, ShapeBounding,
|
|---|
| 99 | &cRects, &iOrdering);
|
|---|
| 100 | if (!pRects)
|
|---|
| 101 | cRects = 0;
|
|---|
| 102 | }
|
|---|
| 103 | char *pszName = NULL;
|
|---|
| 104 | XFetchName(pDisplay, hClient, &pszName);
|
|---|
| 105 | if (pszName)
|
|---|
| 106 | printf("Window %lu (\"%s\"): ", (unsigned long) hWin, pszName);
|
|---|
| 107 | else
|
|---|
| 108 | printf("Window %lu: ", (unsigned long) hWin);
|
|---|
| 109 | printf("position (%d, %d), size (%d, %d)\n", winAttrib.x, winAttrib.y,
|
|---|
| 110 | winAttrib.width, winAttrib.height);
|
|---|
| 111 | for (int j = 0; j < cRects; ++j)
|
|---|
| 112 | printf(" visible rectangle: position (%d, %d), size (%d, %d)\n",
|
|---|
| 113 | pRects[j].x, pRects[j].y, pRects[j].width,
|
|---|
| 114 | pRects[j].height);
|
|---|
| 115 | XFree(pRects);
|
|---|
| 116 | XFree(pszName);
|
|---|
| 117 | }
|
|---|
| 118 | }
|
|---|