summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Coopersmith <alan.coopersmith@oracle.com>2010-06-13 12:42:34 -0700
committerAlan Coopersmith <alan.coopersmith@oracle.com>2010-07-07 10:46:47 -0700
commit96f19bade9ce4940642d580f4c52e2bc0e3539ab (patch)
tree5e3ecda97f424e670437a05a085efa9caa8e51fe
parent123ff05c2e2bbdb9d7d6d958d9f096cf854b8360 (diff)
Convert from Xlib to xcb
Testing was done with a simple GNOME 2.28 session with a number of applications open (gnome-terminal, VirtualBox, Firefox). Primary test case was xwininfo -root -all, which listed 114 children of the root window. Output was identical to Xlib version (after applying the fix to libxcb_icccm for always null-terminating wm_class properties). Over a local connection on the same machine: Xlib: 0.00u 0.01s 0:00.05 20.0% xcb: 0.00u 0.00s 0:00.02 0.0% (i.e. barely measurable difference - I had more variation between repeated runs of the command) Introducing latency by running over ssh -X from California to Beijing and back: Xlib: 0.03u 0.02s 8:19.12 0.0% xcb: 0.00u 0.00s 0:45.26 0.0% Memory size when exit() is called: Xlib: Address Kbytes RSS Anon Locked Mode Mapped File 08043000 20 20 20 - rw--- [ stack ] 08400000 144 144 144 - rw--- [ heap ] total Kb 8972 8640 316 - xcb: Address Kbytes RSS Anon Locked Mode Mapped File 08045000 12 12 12 - rwx-- [ stack ] 0806C000 100 100 100 - rwx-- [ heap ] total Kb 7980 7692 288 - Bytes sent & received (counted by proxying via xscope): Xlib: Client --> Server: 21380 bytes Client <-- Server: 54124 bytes xcb: Client --> Server: 21114 bytes Client <-- Server: 53160 bytes (The Xlib code didn't save any replies, so re-requested a couple of things when running with -all - I fixed that while porting to xcb, but the same could be done with Xlib easily too.) Not yet handled: WM_NAME properties that need to be converted from another character encoding. Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> Reviewed-by: James Cloos <cloos@jhcloos.com>
-rw-r--r--COPYING2
-rw-r--r--clientwin.c191
-rw-r--r--clientwin.h6
-rw-r--r--configure.ac8
-rw-r--r--dsimple.c506
-rw-r--r--dsimple.h54
-rw-r--r--xwininfo.c1001
7 files changed, 1076 insertions, 692 deletions
diff --git a/COPYING b/COPYING
index 10b416d..687540f 100644
--- a/COPYING
+++ b/COPYING
@@ -1,2 +1,2 @@
-Copyright © 1999 Sun Microsystems, Inc. All rights reserved.
+Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
diff --git a/clientwin.c b/clientwin.c
index cce35ad..fe6bd18 100644
--- a/clientwin.c
+++ b/clientwin.c
@@ -21,4 +21,7 @@
*/
-#include <X11/Xatom.h>
-#include <X11/Xlib.h>
+#include <xcb/xcb.h>
+#include <xcb/xproto.h>
+
+#include <stdlib.h>
+#include <string.h>
@@ -26,3 +29,4 @@
-static Atom atom_wm_state = None;
+static xcb_atom_t atom_wm_state = XCB_ATOM_NONE;
+typedef enum { False = 0, True } Bool;
@@ -32,18 +36,20 @@ static Atom atom_wm_state = None;
static Bool
-Window_Has_Property(Display * dpy, Window win, Atom atom)
+Window_Has_Property(xcb_connection_t * dpy, xcb_window_t win, xcb_atom_t atom)
{
- Atom type_ret;
- int format_ret;
- unsigned char *prop_ret;
- unsigned long bytes_after, num_ret;
-
- type_ret = None;
- prop_ret = NULL;
- XGetWindowProperty(dpy, win, atom, 0, 0, False, AnyPropertyType,
- &type_ret, &format_ret, &num_ret,
- &bytes_after, &prop_ret);
- if (prop_ret)
- XFree(prop_ret);
-
- return (type_ret != None) ? True : False;
+ xcb_get_property_cookie_t prop_cookie;
+ xcb_get_property_reply_t *prop_reply;
+
+ prop_cookie = xcb_get_property (dpy, False, win, atom,
+ XCB_GET_PROPERTY_TYPE_ANY, 0, 0);
+
+ prop_reply = xcb_get_property_reply (dpy, prop_cookie, NULL);
+
+ if (prop_reply) {
+ xcb_atom_t reply_type = prop_reply->type;
+ free (prop_reply);
+ if (reply_type != XCB_NONE)
+ return True;
+ }
+
+ return False;
}
@@ -54,10 +60,16 @@ Window_Has_Property(Display * dpy, Window win, Atom atom)
static Bool
-Window_Is_Viewable(Display * dpy, Window win)
+Window_Is_Viewable(xcb_connection_t * dpy, xcb_window_t win)
{
- Bool ok;
- XWindowAttributes xwa;
+ Bool ok = False;
+ xcb_get_window_attributes_cookie_t attr_cookie;
+ xcb_get_window_attributes_reply_t *xwa;
- XGetWindowAttributes(dpy, win, &xwa);
+ attr_cookie = xcb_get_window_attributes (dpy, win);
+ xwa = xcb_get_window_attributes_reply (dpy, attr_cookie, NULL);
- ok = (xwa.class == InputOutput) && (xwa.map_state == IsViewable);
+ if (xwa) {
+ ok = (xwa->_class == XCB_WINDOW_CLASS_INPUT_OUTPUT) &&
+ (xwa->map_state == XCB_MAP_STATE_VIEWABLE);
+ free (xwa);
+ }
@@ -72,7 +84,8 @@ Window_Is_Viewable(Display * dpy, Window win)
*/
-static Window
-Find_Client_In_Children(Display * dpy, Window win)
+static xcb_window_t
+Find_Client_In_Children(xcb_connection_t * dpy, xcb_window_t win)
{
- Window root, parent;
- Window *children;
+ xcb_query_tree_cookie_t qt_cookie;
+ xcb_query_tree_reply_t *tree;
+ xcb_window_t *children;
unsigned int n_children;
@@ -80,12 +93,19 @@ Find_Client_In_Children(Display * dpy, Window win)
- if (!XQueryTree(dpy, win, &root, &parent, &children, &n_children))
- return None;
- if (!children)
- return None;
+ qt_cookie = xcb_query_tree (dpy, win);
+ tree = xcb_query_tree_reply (dpy, qt_cookie, NULL);
+ if (!tree)
+ return XCB_WINDOW_NONE;
+ n_children = xcb_query_tree_children_length (tree);
+ if (!n_children) {
+ free (tree);
+ return XCB_WINDOW_NONE;
+ }
+ children = xcb_query_tree_children (tree);
/* Check each child for WM_STATE and other validity */
- win = None;
+ win = XCB_WINDOW_NONE;
for (i = (int) n_children - 1; i >= 0; i--) {
if (!Window_Is_Viewable(dpy, children[i])) {
- children[i] = None; /* Don't bother descending into this one */
+ /* Don't bother descending into this one */
+ children[i] = XCB_WINDOW_NONE;
continue;
@@ -102,6 +122,6 @@ Find_Client_In_Children(Display * dpy, Window win)
for (i = (int) n_children - 1; i >= 0; i--) {
- if (children[i] == None)
+ if (children[i] == XCB_WINDOW_NONE)
continue;
win = Find_Client_In_Children(dpy, children[i]);
- if (win != None)
+ if (win != XCB_WINDOW_NONE)
break;
@@ -110,3 +130,3 @@ Find_Client_In_Children(Display * dpy, Window win)
done:
- XFree(children);
+ free (tree); /* includes children */
@@ -118,13 +138,23 @@ Find_Client_In_Children(Display * dpy, Window win)
*/
-static unsigned long *
-Find_Roots(Display * dpy, Window root, unsigned int *num)
+static xcb_window_t *
+Find_Roots(xcb_connection_t * dpy, xcb_window_t root, unsigned int *num)
{
- Atom type_ret;
- int format_ret;
- unsigned char *prop_ret;
- unsigned long bytes_after, num_ret;
- Atom atom;
+ xcb_atom_t atom = XCB_ATOM_NONE;
+ xcb_intern_atom_cookie_t atom_cookie;
+ xcb_intern_atom_reply_t *atom_reply;
+
+ xcb_get_property_cookie_t prop_cookie;
+ xcb_get_property_reply_t *prop_reply;
+
+ xcb_window_t *prop_ret = NULL;
*num = 0;
- atom = XInternAtom(dpy, "_NET_VIRTUAL_ROOTS", False);
+
+ atom_cookie = xcb_intern_atom (dpy, False, strlen("_NET_VIRTUAL_ROOTS"),
+ "_NET_VIRTUAL_ROOTS");
+ atom_reply = xcb_intern_atom_reply (dpy, atom_cookie, NULL);
+ if (atom_reply) {
+ atom = atom_reply->atom;
+ free (atom_reply);
+ }
if (!atom)
@@ -132,17 +162,20 @@ Find_Roots(Display * dpy, Window root, unsigned int *num)
- type_ret = None;
- prop_ret = NULL;
- if (XGetWindowProperty(dpy, root, atom, 0, 0x7fffffff, False,
- XA_WINDOW, &type_ret, &format_ret, &num_ret,
- &bytes_after, &prop_ret) != Success)
+ prop_cookie = xcb_get_property (dpy, False, root, atom, XCB_ATOM_WINDOW,
+ 0, 0x7fffffff);
+ prop_reply = xcb_get_property_reply (dpy, prop_cookie, NULL);
+ if (!prop_reply)
return NULL;
- if (prop_ret && type_ret == XA_WINDOW && format_ret == 32) {
- *num = num_ret;
- return ((unsigned long *) prop_ret);
+ if ((prop_reply->value_len > 0) && (prop_reply->type == XCB_ATOM_WINDOW)
+ && (prop_reply->format == 32)) {
+ int length = xcb_get_property_value_length (prop_reply);
+ prop_ret = malloc(length);
+ if (prop_ret) {
+ memcpy (prop_ret, xcb_get_property_value(prop_reply), length);
+ *num = prop_reply->value_len;
+ }
}
- if (prop_ret)
- XFree(prop_ret);
+ free (prop_reply);
- return NULL;
+ return prop_ret;
}
@@ -152,11 +185,17 @@ Find_Roots(Display * dpy, Window root, unsigned int *num)
*/
-static Window
-Find_Child_At_Pointer(Display * dpy, Window win)
+static xcb_window_t
+Find_Child_At_Pointer(xcb_connection_t * dpy, xcb_window_t win)
{
- Window root_return, child_return;
- int dummyi;
- unsigned int dummyu;
+ xcb_window_t child_return = XCB_WINDOW_NONE;
+
+ xcb_query_pointer_cookie_t qp_cookie;
+ xcb_query_pointer_reply_t *qp_reply;
- XQueryPointer(dpy, win, &root_return, &child_return,
- &dummyi, &dummyi, &dummyi, &dummyi, &dummyu);
+ qp_cookie = xcb_query_pointer (dpy, win);
+ qp_reply = xcb_query_pointer_reply (dpy, qp_cookie, NULL);
+
+ if (qp_reply) {
+ child_return = qp_reply->child;
+ free (qp_reply);
+ }
@@ -177,8 +216,8 @@ Find_Child_At_Pointer(Display * dpy, Window win)
*/
-Window
-Find_Client(Display * dpy, Window root, Window subwin)
+xcb_window_t
+Find_Client(xcb_connection_t * dpy, xcb_window_t root, xcb_window_t subwin)
{
- unsigned long *roots;
+ xcb_window_t *roots;
unsigned int i, n_roots;
- Window win;
+ xcb_window_t win;
@@ -190,3 +229,3 @@ Find_Client(Display * dpy, Window root, Window subwin)
win = Find_Child_At_Pointer(dpy, subwin);
- if (win == None)
+ if (win == XCB_WINDOW_NONE)
return subwin; /* No child - Return virtual root. */
@@ -195,7 +234,15 @@ Find_Client(Display * dpy, Window root, Window subwin)
}
- if (roots)
- XFree(roots);
+ free (roots);
- if (atom_wm_state == None) {
- atom_wm_state = XInternAtom(dpy, "WM_STATE", False);
+ if (atom_wm_state == XCB_ATOM_NONE) {
+ xcb_intern_atom_cookie_t atom_cookie;
+ xcb_intern_atom_reply_t *atom_reply;
+
+ atom_cookie = xcb_intern_atom (dpy, False,
+ strlen("WM_STATE"), "WM_STATE");
+ atom_reply = xcb_intern_atom_reply (dpy, atom_cookie, NULL);
+ if (atom_reply) {
+ atom_wm_state = atom_reply->atom;
+ free (atom_reply);
+ }
if (!atom_wm_state)
@@ -210,3 +257,3 @@ Find_Client(Display * dpy, Window root, Window subwin)
win = Find_Client_In_Children(dpy, subwin);
- if (win != None)
+ if (win != XCB_WINDOW_NONE)
return win; /* Found a client */
diff --git a/clientwin.h b/clientwin.h
index 9fc59b5..05aa202 100644
--- a/clientwin.h
+++ b/clientwin.h
@@ -24,5 +24,7 @@
-#include <X11/Xlib.h>
+#include <xcb/xcb.h>
+#include <xcb/xproto.h>
-extern Window Find_Client(Display * dpy, Window root, Window target_win);
+extern xcb_window_t Find_Client(xcb_connection_t * dpy, xcb_window_t root,
+ xcb_window_t target_win);
diff --git a/configure.ac b/configure.ac
index 7ef640a..3337c6c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -43,5 +43,7 @@ AC_CHECK_FUNCS([strlcat])
# Checks for pkg-config packages
-PKG_CHECK_MODULES(XWININFO, xext x11 [xproto >= 7.0.17])
-AC_SUBST(XWININFO_CFLAGS)
-AC_SUBST(XWININFO_LIBS)
+PKG_CHECK_MODULES(XWININFO, [xcb >= 1.6] xcb-icccm xcb-shape)
+# Even when using xcb, xproto is still required for Xfuncproto.h
+# and libX11 headers for cursorfont.h
+PKG_CHECK_MODULES(XLIB, x11 [xproto >= 7.0.17])
+XWININFO_CFLAGS="${XWININFO_CFLAGS} ${XLIB_CFLAGS}"
diff --git a/dsimple.c b/dsimple.c
index 51df01f..d1accf7 100644
--- a/dsimple.c
+++ b/dsimple.c
@@ -1,2 +1,24 @@
/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+/*
@@ -28,5 +50,5 @@ from The Open Group.
-#include <X11/Xos.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
+#include <xcb/xcb.h>
+#include <xcb/xproto.h>
+#include <xcb/xcb_icccm.h>
#include <X11/cursorfont.h>
@@ -35,8 +57,3 @@ from The Open Group.
#include <stdarg.h>
-/*
- * Other_stuff.h: Definitions of routines in other_stuff.
- *
- * Written by Mark Lillibridge. Last updated 7/1/87
- */
-
+#include <string.h>
#include "clientwin.h"
@@ -48,4 +65,4 @@ from The Open Group.
* any windows much faster and easier. Unless a routine says
- * otherwise, it may be assumed to require program_name, dpy,
- * and screen already defined on entry.
+ * otherwise, it may be assumed to require program_name
+ * to be already defined on entry.
*
@@ -55,61 +72,22 @@ from The Open Group.
-/* This stuff is defined in the calling program by just_display.h */
+/* This stuff is defined in the calling program by dsimple.h */
char *program_name = "unknown_program";
-Display *dpy = NULL;
-int screen = 0;
-
/*
- * Get_Display_Name (argc, argv) Look for -display, -d, or host:dpy (obselete)
- * If found, remove it from command line. Don't go past a lone -.
+ * Get_Display_Name (argc, argv) - return string representing display name
+ * that would be used given the specified argument (i.e. if it's NULL, check
+ * getenv("DISPLAY") - always returns a non-NULL pointer, though it may be
+ * an unwritable constant, so is safe to printf() on platforms that crash
+ * on NULL printf arguments.
*/
-char *Get_Display_Name (
- int *pargc, /* MODIFIED */
- char **argv) /* MODIFIED */
+const char *Get_Display_Name (const char *display_name)
{
- int argc = *pargc;
- char **pargv = argv+1;
- char *displayname = NULL;
- int i;
-
- for (i = 1; i < argc; i++) {
- char *arg = argv[i];
-
- if (!strcmp (arg, "-display") || !strcmp (arg, "-d")) {
- if (++i >= argc) usage ();
+ const char *name = display_name;
- displayname = argv[i];
- *pargc -= 2;
- continue;
- }
- if (!strcmp (arg,"-")) {
- while (i<argc)
- *pargv++ = argv[i++];
- break;
- }
- *pargv++ = arg;
+ if (!name) {
+ name = getenv ("DISPLAY");
+ if (!name)
+ name = "";
}
-
- *pargv = NULL;
- return (displayname);
-}
-
-
-
-/*
- * Open_Display: Routine to open a display with correct error handling.
- * Does not require dpy or screen defined on entry.
- */
-Display *Open_Display (char *display_name)
-{
- Display *d;
-
- d = XOpenDisplay (display_name);
- if (d == NULL) {
- fprintf (stderr, "%s: unable to open display '%s'\n",
- program_name, XDisplayName (display_name));
- exit (1);
- }
-
- return (d);
+ return (name);
}
@@ -122,107 +100,49 @@ Display *Open_Display (char *display_name)
* for this display is then stored in screen.
- * Does not require dpy or screen defined.
*/
void Setup_Display_And_Screen (
- int *argc, /* MODIFIED */
- char **argv) /* MODIFIED */
+ const char *display_name,
+ xcb_connection_t **dpy, /* MODIFIED */
+ xcb_screen_t **screen) /* MODIFIED */
{
- char *displayname = NULL;
+ int screen_number, i;
- displayname = Get_Display_Name (argc, argv);
- dpy = Open_Display (displayname);
- screen = XDefaultScreen (dpy);
-}
+ /* Open Display */
+ *dpy = xcb_connect (display_name, &screen_number);
+ if (xcb_connection_has_error (*dpy)) {
+ Fatal_Error ("unable to open display \"%s\"",
+ Get_Display_Name(display_name) );
+ }
-/*
- * Close_Display: Close display
- */
-void Close_Display (void)
-{
- if (dpy == NULL)
- return;
+ if (screen) {
+ /* find our screen */
+ const xcb_setup_t *setup = xcb_get_setup(*dpy);
+ xcb_screen_iterator_t screen_iter = xcb_setup_roots_iterator(setup);
- XCloseDisplay (dpy);
- dpy = NULL;
+ for (i = 0; i < screen_number; i++)
+ xcb_screen_next(&screen_iter);
+ *screen = screen_iter.data;
+ }
}
-
/*
- * Select_Window_Args: a rountine to provide a common interface for
- * applications that need to allow the user to select one
- * window on the screen for special consideration.
- * This routine implements the following command line
- * arguments:
- *
- * -root Selects the root window.
- * -id <id> Selects window with id <id>. <id> may
- * be either in decimal or hex.
- * -name <name> Selects the window with name <name>.
- *
- * Call as Select_Window_Args(&argc, argv) in main before
- * parsing any of your program's command line arguments.
- * Select_Window_Args will remove its arguments so that
- * your program does not have to worry about them.
- * The window returned is the window selected or 0 if
- * none of the above arguments was present. If 0 is
- * returned, Select_Window should probably be called after
- * all command line arguments, and other setup is done.
- * For examples of usage, see xwininfo, xwd, or xprop.
+ * xcb equivalent of XCreateFontCursor
*/
-Window Select_Window_Args (
- int *rargc,
- char **argv)
-#define ARGC (*rargc)
+static xcb_cursor_t
+Create_Font_Cursor (xcb_connection_t *dpy, uint16_t glyph)
{
- int nargc = 1;
- int argc;
- char **nargv;
- Window w = 0;
-
- nargv = argv+1; argc = ARGC;
-#define OPTION argv[0]
-#define NXTOPTP ++argv, --argc>0
-#define NXTOPT if (++argv, --argc==0) usage()
-#define COPYOPT nargv++[0]=OPTION, nargc++
-
- while (NXTOPTP) {
- if (!strcmp (OPTION, "-")) {
- COPYOPT;
- while (NXTOPTP)
- COPYOPT;
- break;
- }
- if (!strcmp (OPTION, "-root")) {
- w = RootWindow (dpy, screen);
- continue;
- }
- if (!strcmp (OPTION, "-name")) {
- NXTOPT;
- w = Window_With_Name (dpy, RootWindow (dpy, screen), OPTION);
- if (!w)
- Fatal_Error ("No window with name %s exists!", OPTION);
- continue;
- }
- if (!strcmp (OPTION, "-id")) {
- NXTOPT;
- w = 0;
- sscanf (OPTION, "0x%lx", &w);
- if (!w)
- sscanf (OPTION, "%lu", &w);
- if (!w)
- Fatal_Error ("Invalid window id format: %s.", OPTION);
- continue;
- }
- COPYOPT;
- }
- ARGC = nargc;
+ static xcb_font_t cursor_font;
+ xcb_cursor_t cursor;
- return (w);
-}
+ if (!cursor_font) {
+ cursor_font = xcb_generate_id (dpy);
+ xcb_open_font (dpy, cursor_font, strlen ("cursor"), "cursor");
+ }
-/*
- * Other_stuff: A group of routines which do common X11 tasks.
- *
- * Written by Mark Lillibridge. Last updated 7/1/87
- */
+ cursor = xcb_generate_id (dpy);
+ xcb_create_glyph_cursor (dpy, cursor, cursor_font, cursor_font,
+ glyph, glyph + 1,
+ 0, 0, 0, 0xffff, 0xffff, 0xffff); /* rgb, rgb */
+ return cursor;
+}
@@ -232,29 +152,43 @@ Window Select_Window_Args (
-Window Select_Window (Display *dpy, int descend)
+xcb_window_t Select_Window(xcb_connection_t *dpy,
+ const xcb_screen_t *screen,
+ int descend)
{
- int status;
- Cursor cursor;
- XEvent event;
- Window target_win = None, root = RootWindow (dpy,screen);
+ xcb_cursor_t cursor;
+ xcb_generic_event_t *event;
+ xcb_window_t target_win = XCB_WINDOW_NONE;
+ xcb_window_t root = screen->root;
int buttons = 0;
+ xcb_generic_error_t *err;
+ xcb_grab_pointer_cookie_t grab_cookie;
+ xcb_grab_pointer_reply_t *grab_reply;
/* Make the target cursor */
- cursor = XCreateFontCursor (dpy, XC_crosshair);
+ cursor = Create_Font_Cursor (dpy, XC_crosshair);
/* Grab the pointer using target cursor, letting it room all over */
- status = XGrabPointer (dpy, root, False,
- ButtonPressMask|ButtonReleaseMask, GrabModeSync,
- GrabModeAsync, root, cursor, CurrentTime);
- if (status != GrabSuccess) Fatal_Error ("Can't grab the mouse.");
+ grab_cookie = xcb_grab_pointer
+ (dpy, False, root,
+ XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE,
+ XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC,
+ root, cursor, XCB_TIME_CURRENT_TIME);
+ grab_reply = xcb_grab_pointer_reply (dpy, grab_cookie, &err);
+ if (grab_reply->status != XCB_GRAB_STATUS_SUCCESS)
+ Fatal_Error ("Can't grab the mouse.");
/* Let the user select a window... */
- while ((target_win == None) || (buttons != 0)) {
+ while ((target_win == XCB_WINDOW_NONE) || (buttons != 0)) {
/* allow one more event */
- XAllowEvents (dpy, SyncPointer, CurrentTime);
- XWindowEvent (dpy, root, ButtonPressMask|ButtonReleaseMask, &event);
- switch (event.type) {
- case ButtonPress:
- if (target_win == None) {
- target_win = event.xbutton.subwindow; /* window selected */
- if (target_win == None) target_win = root;
+ xcb_allow_events (dpy, XCB_ALLOW_SYNC_POINTER, XCB_TIME_CURRENT_TIME);
+ xcb_flush (dpy);
+ event = xcb_wait_for_event (dpy);
+ switch (event->response_type & 0x7f) {
+ case XCB_BUTTON_PRESS:
+ {
+ xcb_button_press_event_t *bp = (xcb_button_press_event_t *)event;
+
+ if (target_win == XCB_WINDOW_NONE) {
+ target_win = bp->child; /* window selected */
+ if (target_win == XCB_WINDOW_NONE)
+ target_win = root;
}
@@ -262,3 +196,4 @@ Window Select_Window (Display *dpy, int descend)
break;
- case ButtonRelease:
+ }
+ case XCB_BUTTON_RELEASE:
if (buttons > 0) /* there may have been some down before we started */
@@ -266,6 +201,10 @@ Window Select_Window (Display *dpy, int descend)
break;
+ default:
+ /* just discard all other events */
+ break;
}
+ free (event);
}
- XUngrabPointer (dpy, CurrentTime); /* Done with pointer */
+ xcb_ungrab_pointer (dpy, XCB_TIME_CURRENT_TIME); /* Done with pointer */
@@ -287,21 +226,66 @@ Window Select_Window (Display *dpy, int descend)
*/
-Window Window_With_Name (
- Display *dpy,
- Window top,
- char *name)
+
+struct wininfo_cookies {
+ xcb_get_property_cookie_t get_wm_name;
+ xcb_query_tree_cookie_t query_tree;
+};
+
+static xcb_window_t
+recursive_Window_With_Name (
+ xcb_connection_t *dpy,
+ xcb_window_t window,
+ struct wininfo_cookies *cookies,
+ const char *name)
{
- Window *children, dummy;
+ xcb_window_t *children;
unsigned int nchildren;
int i;
- Window w=0;
- char *window_name;
+ xcb_window_t w = 0;
+ xcb_generic_error_t *err;
+ xcb_get_text_property_reply_t prop;
+ xcb_query_tree_reply_t *tree;
+ struct wininfo_cookies *child_cookies;
+
+ if (xcb_get_wm_name_reply (dpy, cookies->get_wm_name, &prop, &err)) {
+ /* can't use strcmp, since prop.name is not null terminated */
+ if (strncmp (prop.name, name, prop.name_len) == 0) {
+ w = window;
+ }
+
+ xcb_get_text_property_reply_wipe (&prop);
- if (XFetchName (dpy, top, &window_name) && !strcmp (window_name, name))
- return (top);
+ if (w)
+ {
+ xcb_discard_reply (dpy, cookies->query_tree.sequence);
+ return w;
+ }
+ } else if (err) {
+ if (err->response_type == 0)
+ Print_X_Error (dpy, err);
+ return 0;
+ }
- if (!XQueryTree (dpy, top, &dummy, &dummy, &children, &nchildren))
- return (0);
+ tree = xcb_query_tree_reply (dpy, cookies->query_tree, &err);
+ if (!tree) {
+ if (err->response_type == 0)
+ Print_X_Error (dpy, err);
+ return 0;
+ }
+
+ nchildren = xcb_query_tree_children_length (tree);
+ children = xcb_query_tree_children (tree);
+ child_cookies = calloc(nchildren, sizeof(struct wininfo_cookies));
+
+ if (child_cookies == NULL)
+ Fatal_Error("Failed to allocate memory in recursive_Window_With_Name");
+
+ for (i = 0; i < nchildren; i++) {
+ child_cookies[i].get_wm_name = xcb_get_wm_name (dpy, children[i]);
+ child_cookies[i].query_tree = xcb_query_tree (dpy, children[i]);
+ }
+ xcb_flush (dpy);
for (i = 0; i < nchildren; i++) {
- w = Window_With_Name (dpy, children[i], name);
+ w = recursive_Window_With_Name (dpy, children[i],
+ &child_cookies[i], name);
if (w)
@@ -309,3 +293,14 @@ Window Window_With_Name (
}
- if (children) XFree ((char *)children);
+
+ if (w)
+ {
+ /* clean up remaining replies */
+ for (/* keep previous i */; i < nchildren; i++) {
+ xcb_discard_reply (dpy, child_cookies[i].get_wm_name.sequence);
+ xcb_discard_reply (dpy, child_cookies[i].query_tree.sequence);
+ }
+ }
+
+ free (child_cookies);
+ free (tree); /* includes storage for children[] */
return (w);
@@ -313,2 +308,15 @@ Window Window_With_Name (
+xcb_window_t
+Window_With_Name (
+ xcb_connection_t *dpy,
+ xcb_window_t top,
+ const char *name)
+{
+ struct wininfo_cookies cookies;
+
+ cookies.get_wm_name = xcb_get_wm_name (dpy, top);
+ cookies.query_tree = xcb_query_tree (dpy, top);
+ return recursive_Window_With_Name(dpy, top, &cookies, name);
+}
+
@@ -316,3 +324,2 @@ Window Window_With_Name (
* Standard fatal error routine - call like printf
- * Does not require dpy or screen defined.
*/
@@ -328,4 +335,125 @@ void Fatal_Error (char *msg, ...)
fprintf (stderr, "\n");
- Close_Display ();
exit (EXIT_FAILURE);
}
+
+/*
+ * Print X error information like the default Xlib error handler
+ */
+void
+Print_X_Error (
+ xcb_connection_t *dpy,
+ xcb_generic_error_t *err
+ )
+{
+ char buffer[256] = "";
+
+ if ((err == NULL) || (err->response_type != 0)) /* not an error */
+ return;
+
+ /* Todo: find a more user friendly way to show request/extension info */
+ if (err->error_code >= 128)
+ {
+ fprintf (stderr, "X Extension Error: Error code %d\n",
+ err->error_code);
+ }
+ else
+ {
+ switch (err->error_code)
+ {
+ case XCB_REQUEST:
+ snprintf (buffer, sizeof(buffer), ": Bad Request");
+ break;
+
+ case XCB_VALUE:
+ snprintf (buffer, sizeof(buffer),
+ ": Bad Value: 0x%x", err->resource_id);
+ break;
+
+ case XCB_WINDOW:
+ snprintf (buffer, sizeof(buffer),
+ ": Bad Window: 0x%x", err->resource_id);
+ break;
+
+ case XCB_PIXMAP:
+ snprintf (buffer, sizeof(buffer),
+ ": Bad Pixmap: 0x%x", err->resource_id);
+ break;
+
+ case XCB_ATOM:
+ snprintf (buffer, sizeof(buffer),
+ ": Bad Atom: 0x%x", err->resource_id);
+ break;
+
+ case XCB_CURSOR:
+ snprintf (buffer, sizeof(buffer),
+ ": Bad Cursor: 0x%x", err->resource_id);
+ break;
+
+ case XCB_FONT:
+ snprintf (buffer, sizeof(buffer),
+ ": Bad Font: 0x%x", err->resource_id);
+ break;
+
+ case XCB_MATCH:
+ snprintf (buffer, sizeof(buffer), ": Bad Match");
+ break;
+
+ case XCB_DRAWABLE:
+ snprintf (buffer, sizeof(buffer),
+ ": Bad Drawable: 0x%x", err->resource_id);
+ break;
+
+ case XCB_ACCESS:
+ snprintf (buffer, sizeof(buffer), ": Access Denied");
+ break;
+
+ case XCB_ALLOC:
+ snprintf (buffer, sizeof(buffer),
+ ": Server Memory Allocation Failure");
+ break;
+
+ case XCB_COLORMAP:
+ snprintf (buffer, sizeof(buffer),
+ ": Bad Color: 0x%x", err->resource_id);
+ break;
+
+ case XCB_G_CONTEXT:
+ snprintf (buffer, sizeof(buffer),
+ ": Bad GC: 0x%x", err->resource_id);
+ break;
+
+ case XCB_ID_CHOICE:
+ snprintf (buffer, sizeof(buffer),
+ ": Bad XID: 0x%x", err->resource_id);
+ break;
+
+ case XCB_NAME:
+ snprintf (buffer, sizeof(buffer),
+ ": Bad Name");
+ break;
+
+ case XCB_LENGTH:
+ snprintf (buffer, sizeof(buffer),
+ ": Bad Request Length");
+ break;
+
+ case XCB_IMPLEMENTATION:
+ snprintf (buffer, sizeof(buffer),
+ ": Server Implementation Failure");
+ break;
+
+ default:
+ snprintf (buffer, sizeof(buffer), ": Unknown error");
+ break;
+ }
+ fprintf (stderr, "X Error: %d%s\n", err->error_code, buffer);
+ }
+
+ fprintf (stderr, " Request Major code: %d\n", err->major_code);
+ if (err->major_code >= 128)
+ {
+ fprintf (stderr, " Request Minor code: %d\n", err->minor_code);
+ }
+
+ fprintf (stderr, " Request serial number: %d\n", err->full_sequence);
+}
diff --git a/dsimple.h b/dsimple.h
index b0d76a5..1a689e0 100644
--- a/dsimple.h
+++ b/dsimple.h
@@ -29,10 +29,8 @@ from The Open Group.
/*
- * Just_display.h: This file contains the definitions needed to use the
- * functions in just_display.c. It also declares the global
- * variables dpy, screen, and program_name which are needed to
- * use just_display.c.
+ * dsimple.h: This file contains the definitions needed to use the
+ * functions in dsimple.c. It also declares the global
+ * variable program_name which is needed to use dsimple.c.
*
- * Written by Mark Lillibridge. Last updated 7/1/87
- *
- * Send bugs, etc. to chariot@athena.mit.edu.
+ * Written by Mark Lillibridge for Xlib. Last updated 7/1/87
+ * Ported to XCB over two decades later.
*/
@@ -40,10 +38,6 @@ from The Open Group.
#include <X11/Xfuncproto.h>
+#include <xcb/xcb.h>
+#include <xcb/xproto.h>
- /* Simple helper macros */
-#ifndef MAX
-#define MAX(a,b) (((a)>(b))?(a):(b))
-#endif /* MAX */
-#ifndef MIN
-#define MIN(a,b) (((a)<(b))?(a):(b))
-#endif /* MIN */
+typedef enum { False = 0, True } Bool;
@@ -52,30 +46,14 @@ from The Open Group.
extern char *program_name; /* Name of this program */
-extern Display *dpy; /* The current display */
-extern int screen; /* The current screen */
-
-#define INIT_NAME program_name=argv[0] /* use this in main to setup
- program_name */
- /* Declaritions for functions in dsimple.c */
+ /* Declarations for functions in dsimple.c */
-char *Get_Display_Name(int *, char **);
-Display *Open_Display(char *);
-void Setup_Display_And_Screen(int *, char **);
-void Close_Display(void);
-Window Select_Window_Args(int *, char **);
-void usage(void);
+const char *Get_Display_Name (const char *displayname);
+void Setup_Display_And_Screen (const char *displayname,
+ xcb_connection_t **dpy, xcb_screen_t **screen);
-#define X_USAGE "[host:display]" /* X arguments handled by
- Get_Display_Name */
-
-/*
- * Other_stuff.h: Definitions of routines in other_stuff.
- *
- * Written by Mark Lillibridge. Last updated 7/1/87
- *
- * Send bugs, etc. to chariot@athena.mit.edu.
- */
+xcb_window_t Select_Window(xcb_connection_t *, const xcb_screen_t *, int);
+xcb_window_t Window_With_Name(xcb_connection_t *, xcb_window_t, const char *);
-Window Select_Window(Display *, int);
-Window Window_With_Name(Display *, Window, char *);
void Fatal_Error(char *, ...) _X_NORETURN _X_ATTRIBUTE_PRINTF(1, 2);
+
+void Print_X_Error (xcb_connection_t *, xcb_generic_error_t *);
diff --git a/xwininfo.c b/xwininfo.c
index 6b2f728..ea1de2d 100644
--- a/xwininfo.c
+++ b/xwininfo.c
@@ -1,3 +1,3 @@
/*
- * Copyright © 1999 Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
*
@@ -66,10 +66,12 @@ of the copyright holder.
#include "config.h"
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xatom.h>
-#include <X11/Xos.h>
-#include <X11/extensions/shape.h>
-#include <X11/Xlocale.h>
+
+#include <xcb/xcb.h>
+#include <xcb/xproto.h>
+#include <xcb/xcb_icccm.h>
+#include <xcb/shape.h>
+
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
@@ -83,3 +85,24 @@ typedef struct {
-static void scale_init (void);
+/* Information we keep track of for each window to allow prefetching/reusing */
+struct wininfo {
+ xcb_window_t window;
+
+ /* cookies for requests we've sent */
+ xcb_get_geometry_cookie_t geometry_cookie;
+ xcb_get_property_cookie_t wm_name_cookie;
+ xcb_get_property_cookie_t wm_class_cookie;
+ xcb_translate_coordinates_cookie_t trans_coords_cookie;
+ xcb_query_tree_cookie_t tree_cookie;
+ xcb_get_window_attributes_cookie_t attr_cookie;
+ xcb_get_property_cookie_t normal_hints_cookie;
+ xcb_get_property_cookie_t hints_cookie;
+ xcb_get_property_cookie_t zoom_cookie;
+
+ /* cached results from previous requests */
+ xcb_get_geometry_reply_t * geometry;
+ xcb_get_window_attributes_reply_t * win_attributes;
+ xcb_size_hints_t * normal_hints;
+};
+
+static void scale_init (xcb_screen_t *scrn);
static char *nscale (int, int, int, char *, size_t);
@@ -88,3 +111,2 @@ static char *yscale (int);
static char *bscale (int);
-static int bad_window_handler (Display *, XErrorEvent *);
int main (int, char **);
@@ -92,13 +114,14 @@ static const char *LookupL (long, const binding *);
static const char *Lookup (int, const binding *);
-static void Display_Window_Id (Window, int);
-static void Display_Stats_Info (Window);
-static void Display_Bits_Info (Window);
+static void Display_Window_Id (struct wininfo *, Bool);
+static void Display_Stats_Info (struct wininfo *);
+static void Display_Bits_Info (struct wininfo *);
static void Display_Event_Mask (long);
-static void Display_Events_Info (Window);
-static void Display_Tree_Info (Window, int);
-static void display_tree_info_1 (Window, int, int);
-static void Display_Hints (XSizeHints *);
-static void Display_Size_Hints (Window);
-static void Display_Window_Shape (Window);
-static void Display_WM_Info (Window);
+static void Display_Events_Info (struct wininfo *);
+static void Display_Tree_Info (struct wininfo *, int);
+static void display_tree_info_1 (struct wininfo *, int, int);
+static void Display_Hints (xcb_size_hints_t *);
+static void Display_Size_Hints (struct wininfo *);
+static void Display_Window_Shape (xcb_window_t);
+static void Display_WM_Info (struct wininfo *);
+static void wininfo_wipe (struct wininfo *);
@@ -106,2 +129,6 @@ static const char *window_id_format = "0x%lx";
+static xcb_connection_t *dpy;
+static xcb_screen_t *screen;
+static xcb_generic_error_t *err;
+
#ifndef HAVE_STRLCAT
@@ -166,3 +193,2 @@ usage (void)
-#define getdsp(var,fn) var = fn (dpy, DefaultScreen (dpy))
static int xp = 0, xmm = 0;
@@ -173,8 +199,8 @@ static int english = 0, metric = 0;
static void
-scale_init (void)
+scale_init (xcb_screen_t *screen)
{
- getdsp (yp, DisplayHeight);
- getdsp (ymm, DisplayHeightMM);
- getdsp (xp, DisplayWidth);
- getdsp (xmm, DisplayWidthMM);
+ xp = screen->width_in_pixels;
+ yp = screen->height_in_pixels;
+ xmm = screen->width_in_millimeters;
+ ymm = screen->height_in_millimeters;
bp = xp + yp;
@@ -252,5 +278,2 @@ xscale (int x)
{
- if (!xp) {
- scale_init ();
- }
return (nscale (x, xp, xmm, xbuf, sizeof(xbuf)));
@@ -262,5 +285,2 @@ yscale (int y)
{
- if (!yp) {
- scale_init ();
- }
return (nscale (y, yp, ymm, ybuf, sizeof(ybuf)));
@@ -272,5 +292,2 @@ bscale (int b)
{
- if (!bp) {
- scale_init ();
- }
return (nscale (b, bp, bmm, bbuf, sizeof(bbuf)));
@@ -280,18 +297,2 @@ bscale (int b)
-/* This handler is enabled when we are checking
- to see if the -id the user specified is valid. */
-
-/* ARGSUSED */
-static int
-bad_window_handler (Display *disp, XErrorEvent *err)
-{
- char badid[20];
-
- snprintf (badid, sizeof(badid), window_id_format, err->resourceid);
- Fatal_Error ("No such window with id %s.", badid);
- exit (1);
- return 0;
-}
-
-
int
@@ -302,5 +303,10 @@ main (int argc, char **argv)
int frame = 0, children = 0;
- Window window;
+ int use_root = 0;
+ xcb_window_t window = 0;
+ char *display_name = NULL;
+ const char *window_name = NULL;
+ struct wininfo wininfo;
+ struct wininfo *w = &wininfo;
- INIT_NAME;
+ program_name = argv[0];
@@ -309,7 +315,3 @@ main (int argc, char **argv)
- /* Open display, handle command line arguments */
- Setup_Display_And_Screen (&argc, argv);
-
- /* Get window selected on command line, if any */
- window = Select_Window_Args (&argc, argv);
+ memset (w, 0, sizeof(struct wininfo));
@@ -319,2 +321,24 @@ main (int argc, char **argv)
usage ();
+ if (!strcmp (argv[i], "-display") || !strcmp (argv[i], "-d")) {
+ if (++i >= argc)
+ Fatal_Error("-display requires argument");
+ display_name = argv[i];
+ continue;
+ }
+ if (!strcmp (argv[i], "-root")) {
+ use_root = 1;
+ continue;
+ }
+ if (!strcmp (argv[i], "-id")) {
+ if (++i >= argc)
+ Fatal_Error("-id requires argument");
+ window = strtoul(argv[i], NULL, 0);
+ continue;
+ }
+ if (!strcmp (argv[i], "-name")) {
+ if (++i >= argc)
+ Fatal_Error("-name requires argument");
+ window_name = argv[i];
+ continue;
+ }
if (!strcmp (argv[i], "-int")) {
@@ -374,2 +398,15 @@ main (int argc, char **argv)
+ Setup_Display_And_Screen (display_name, &dpy, &screen);
+
+ /* initialize scaling data */
+ scale_init(screen);
+
+ if (use_root)
+ window = screen->root;
+ else if (window_name) {
+ window = Window_With_Name (dpy, screen->root, window_name);
+ if (!window)
+ Fatal_Error ("No window with name \"%s\" exists!", window_name);
+ }
+
/* If no window selected on command line, let user pick one the hard way */
@@ -380,3 +417,3 @@ main (int argc, char **argv)
" mouse in that window.\n");
- window = Select_Window (dpy, !frame);
+ window = Select_Window (dpy, screen, !frame);
}
@@ -393,27 +430,54 @@ main (int argc, char **argv)
{
- Window root;
- int x, y;
- unsigned width, height, bw, depth;
- XErrorHandler old_handler;
-
- old_handler = XSetErrorHandler (bad_window_handler);
- XGetGeometry (dpy, window, &root, &x, &y, &width, &height, &bw, &depth);
- XSync (dpy, False);
- (void) XSetErrorHandler (old_handler);
+ xcb_get_geometry_cookie_t gg_cookie =
+ xcb_get_geometry (dpy, window);
+
+ w->geometry = xcb_get_geometry_reply(dpy, gg_cookie, &err);
+
+ if (!w->geometry) {
+ char badid[20];
+
+ if (err)
+ Print_X_Error (dpy, err);
+
+ snprintf (badid, sizeof(badid), window_id_format, window);
+ Fatal_Error ("No such window with id %s.", badid);
+ }
}
+ /* Send requests to prefetch data we'll need */
+ w->window = window;
+ w->wm_name_cookie = xcb_get_wm_name (dpy, window);
+ if (children || tree)
+ w->tree_cookie = xcb_query_tree (dpy, window);
+ if (stats) {
+ w->trans_coords_cookie =
+ xcb_translate_coordinates (dpy, window, w->geometry->root,
+ -(w->geometry->border_width),
+ -(w->geometry->border_width));
+ }
+ if (stats || bits || events)
+ w->attr_cookie = xcb_get_window_attributes (dpy, window);
+ if (stats || size)
+ w->normal_hints_cookie = xcb_get_wm_normal_hints (dpy, window);
+ if (wm)
+ w->hints_cookie = xcb_get_wm_hints(dpy, window);
+ if (size)
+ w->zoom_cookie = xcb_get_wm_size_hints (dpy, window,
+ XCB_ATOM_WM_ZOOM_HINTS);
+ xcb_flush (dpy);
+
printf ("\nxwininfo: Window id: ");
- Display_Window_Id (window, True);
+ Display_Window_Id (w, True);
if (children || tree)
- Display_Tree_Info (window, tree);
+ Display_Tree_Info (w, tree);
if (stats)
- Display_Stats_Info (window);
+ Display_Stats_Info (w);
if (bits)
- Display_Bits_Info (window);
+ Display_Bits_Info (w);
if (events)
- Display_Events_Info (window);
+ Display_Events_Info (w);
if (wm)
- Display_WM_Info (window);
+ Display_WM_Info (w);
if (size)
- Display_Size_Hints (window);
+ Display_Size_Hints (w);
if (shape)
@@ -421,2 +485,5 @@ main (int argc, char **argv)
printf ("\n");
+
+ wininfo_wipe (w);
+ xcb_disconnect (dpy);
exit (0);
@@ -424,2 +491,37 @@ main (int argc, char **argv)
+/* Ensure win_attributes field is filled in */
+static xcb_get_window_attributes_reply_t *
+fetch_win_attributes (struct wininfo *w)
+{
+ if (!w->win_attributes) {
+ w->win_attributes =
+ xcb_get_window_attributes_reply (dpy, w->attr_cookie, &err);
+
+ if (!w->win_attributes) {
+ Print_X_Error (dpy, err);
+ Fatal_Error ("Can't get window attributes.");
+ }
+ }
+ return w->win_attributes;
+}
+
+/* Ensure normal_hints field is filled in */
+static xcb_size_hints_t *
+fetch_normal_hints (struct wininfo *w, xcb_size_hints_t *hints_return)
+{
+ xcb_size_hints_t hints;
+
+ if (!w->normal_hints) {
+ if (xcb_get_wm_normal_hints_reply (dpy, w->normal_hints_cookie,
+ &hints, NULL)) {
+ w->normal_hints = malloc (sizeof(xcb_size_hints_t));
+ if (w->normal_hints)
+ memcpy(w->normal_hints, &hints, sizeof(xcb_size_hints_t));
+ }
+ }
+ if (hints_return && w->normal_hints)
+ memcpy(hints_return, w->normal_hints, sizeof(xcb_size_hints_t));
+ return w->normal_hints;
+}
+
@@ -460,2 +562,4 @@ Lookup (int code, const binding *table)
* Routine to display a window id in dec/hex with name if window has one
+ *
+ * Requires wininfo members initialized: window, wm_name_cookie
*/
@@ -463,34 +567,28 @@ Lookup (int code, const binding *table)
static void
-Display_Window_Id (Window window, Bool newline_wanted)
+Display_Window_Id (struct wininfo *w, Bool newline_wanted)
{
- XTextProperty tp;
+ xcb_get_text_property_reply_t prop;
+ uint8_t got_reply;
- printf (window_id_format, window); /* print id # in hex/dec */
+ printf (window_id_format, w->window); /* print id # in hex/dec */
- if (!window) {
+ if (!w->window) {
printf (" (none)");
} else {
- if (window == RootWindow (dpy, screen)) {
+ if (w->window == screen->root) {
printf (" (the root window)");
}
- if (!XGetWMName (dpy, window, &tp)) { /* Get window name if any */
+ /* Get window name if any */
+ got_reply = xcb_get_wm_name_reply (dpy, w->wm_name_cookie,
+ &prop, NULL);
+ if (!got_reply || prop.name_len == 0) {
printf (" (has no name)");
- } else if (tp.nitems > 0) {
+ } else {
printf (" \"");
- {
- int count = 0, i, ret;
- char **list = NULL;
- ret = XmbTextPropertyToTextList (dpy, &tp, &list, &count);
- if ((ret == Success || ret > 0) && list != NULL){
- for (i = 0; i < count; i++)
- printf ("%s", list[i]);
- XFreeStringList (list);
- } else {
- printf ("%s", tp.value);
- }
- }
+ /* XXX: need to handle encoding */
+ printf ("%.*s", prop.name_len, prop.name);
printf ("\"");
}
- else
- printf (" (has no name)");
+ if (got_reply)
+ xcb_get_text_property_reply_wipe (&prop);
}
@@ -508,4 +606,4 @@ Display_Window_Id (Window window, Bool newline_wanted)
static const binding _window_classes[] = {
- { InputOutput, "InputOutput" },
- { InputOnly, "InputOnly" },
+ { XCB_WINDOW_CLASS_INPUT_OUTPUT, "InputOutput" },
+ { XCB_WINDOW_CLASS_INPUT_ONLY, "InputOnly" },
{ 0, NULL } };
@@ -513,5 +611,5 @@ static const binding _window_classes[] = {
static const binding _map_states[] = {
- { IsUnmapped, "IsUnMapped" },
- { IsUnviewable, "IsUnviewable" },
- { IsViewable, "IsViewable" },
+ { XCB_MAP_STATE_UNMAPPED, "IsUnMapped" },
+ { XCB_MAP_STATE_UNVIEWABLE, "IsUnviewable" },
+ { XCB_MAP_STATE_VIEWABLE, "IsViewable" },
{ 0, NULL } };
@@ -519,5 +617,5 @@ static const binding _map_states[] = {
static const binding _backing_store_states[] = {
- { NotUseful, "NotUseful" },
- { WhenMapped, "WhenMapped" },
- { Always, "Always" },
+ { XCB_BACKING_STORE_NOT_USEFUL, "NotUseful" },
+ { XCB_BACKING_STORE_WHEN_MAPPED,"WhenMapped" },
+ { XCB_BACKING_STORE_ALWAYS, "Always" },
{ 0, NULL } };
@@ -525,13 +623,13 @@ static const binding _backing_store_states[] = {
static const binding _bit_gravity_states[] = {
- { ForgetGravity, "ForgetGravity" },
- { NorthWestGravity, "NorthWestGravity" },
- { NorthGravity, "NorthGravity" },
- { NorthEastGravity, "NorthEastGravity" },
- { WestGravity, "WestGravity" },
- { CenterGravity, "CenterGravity" },
- { EastGravity, "EastGravity" },
- { SouthWestGravity, "SouthWestGravity" },
- { SouthGravity, "SouthGravity" },
- { SouthEastGravity, "SouthEastGravity" },
- { StaticGravity, "StaticGravity" },
+ { XCB_GRAVITY_BIT_FORGET, "ForgetGravity" },
+ { XCB_GRAVITY_NORTH_WEST, "NorthWestGravity" },
+ { XCB_GRAVITY_NORTH, "NorthGravity" },
+ { XCB_GRAVITY_NORTH_EAST, "NorthEastGravity" },
+ { XCB_GRAVITY_WEST, "WestGravity" },
+ { XCB_GRAVITY_CENTER, "CenterGravity" },
+ { XCB_GRAVITY_EAST, "EastGravity" },
+ { XCB_GRAVITY_SOUTH_WEST, "SouthWestGravity" },
+ { XCB_GRAVITY_SOUTH, "SouthGravity" },
+ { XCB_GRAVITY_SOUTH_EAST, "SouthEastGravity" },
+ { XCB_GRAVITY_STATIC, "StaticGravity" },
{ 0, NULL }};
@@ -539,13 +637,13 @@ static const binding _bit_gravity_states[] = {
static const binding _window_gravity_states[] = {
- { UnmapGravity, "UnmapGravity" },
- { NorthWestGravity, "NorthWestGravity" },
- { NorthGravity, "NorthGravity" },
- { NorthEastGravity, "NorthEastGravity" },
- { WestGravity, "WestGravity" },
- { CenterGravity, "CenterGravity" },
- { EastGravity, "EastGravity" },
- { SouthWestGravity, "SouthWestGravity" },
- { SouthGravity, "SouthGravity" },
- { SouthEastGravity, "SouthEastGravity" },
- { StaticGravity, "StaticGravity" },
+ { XCB_GRAVITY_WIN_UNMAP, "UnmapGravity" },
+ { XCB_GRAVITY_NORTH_WEST, "NorthWestGravity" },
+ { XCB_GRAVITY_NORTH, "NorthGravity" },
+ { XCB_GRAVITY_NORTH_EAST, "NorthEastGravity" },
+ { XCB_GRAVITY_WEST, "WestGravity" },
+ { XCB_GRAVITY_CENTER, "CenterGravity" },
+ { XCB_GRAVITY_EAST, "EastGravity" },
+ { XCB_GRAVITY_SOUTH_WEST, "SouthWestGravity" },
+ { XCB_GRAVITY_SOUTH, "SouthGravity" },
+ { XCB_GRAVITY_SOUTH_EAST, "SouthEastGravity" },
+ { XCB_GRAVITY_STATIC, "StaticGravity" },
{ 0, NULL }};
@@ -553,39 +651,40 @@ static const binding _window_gravity_states[] = {
static const binding _visual_classes[] = {
- { StaticGray, "StaticGray" },
- { GrayScale, "GrayScale" },
- { StaticColor, "StaticColor" },
- { PseudoColor, "PseudoColor" },
- { TrueColor, "TrueColor" },
- { DirectColor, "DirectColor" },
+ { XCB_VISUAL_CLASS_STATIC_GRAY, "StaticGray" },
+ { XCB_VISUAL_CLASS_GRAY_SCALE, "GrayScale" },
+ { XCB_VISUAL_CLASS_STATIC_COLOR,"StaticColor" },
+ { XCB_VISUAL_CLASS_PSEUDO_COLOR,"PseudoColor" },
+ { XCB_VISUAL_CLASS_TRUE_COLOR, "TrueColor" },
+ { XCB_VISUAL_CLASS_DIRECT_COLOR,"DirectColor" },
{ 0, NULL }};
+/*
+ * Requires wininfo members initialized:
+ * window, geometry, attr_cookie, trans_coords_cookie, normal_hints_cookie
+ */
static void
-Display_Stats_Info (Window window)
+Display_Stats_Info (struct wininfo *w)
{
- XWindowAttributes win_attributes;
- XVisualInfo vistemplate, *vinfo;
- XSizeHints hints;
- int dw = DisplayWidth (dpy, screen), dh = DisplayHeight (dpy, screen);
+ xcb_translate_coordinates_reply_t *trans_coords;
+ xcb_get_window_attributes_reply_t *win_attributes;
+ xcb_size_hints_t hints;
+
+ int dw = screen->width_in_pixels, dh = screen->height_in_pixels;
int rx, ry, xright, ybelow;
int showright = 0, showbelow = 0;
- Status status;
- Window wmframe;
- int junk;
- long longjunk;
- Window junkwin;
-
- if (!XGetWindowAttributes (dpy, window, &win_attributes))
- Fatal_Error ("Can't get window attributes.");
- vistemplate.visualid = XVisualIDFromVisual (win_attributes.visual);
- vinfo = XGetVisualInfo (dpy, VisualIDMask, &vistemplate, &junk);
-
- (void) XTranslateCoordinates (dpy, window, win_attributes.root,
- -win_attributes.border_width,
- -win_attributes.border_width,
- &rx, &ry, &junkwin);
-
- xright = (dw - rx - win_attributes.border_width * 2 -
- win_attributes.width);
- ybelow = (dh - ry - win_attributes.border_width * 2 -
- win_attributes.height);
+ xcb_window_t wmframe, parent;
+
+ trans_coords =
+ xcb_translate_coordinates_reply (dpy, w->trans_coords_cookie, NULL);
+ if (!trans_coords)
+ Fatal_Error ("Can't get translated coordinates.");
+
+ rx = trans_coords->dst_x;
+ ry = trans_coords->dst_y;
+ free (trans_coords);
+
+ xright = (dw - rx - w->geometry->border_width * 2 -
+ w->geometry->width);
+ ybelow = (dh - ry - w->geometry->border_width * 2 -
+ w->geometry->height);
+
@@ -594,27 +693,51 @@ Display_Stats_Info (Window window)
printf (" Absolute upper-left Y: %s\n", yscale (ry));
- printf (" Relative upper-left X: %s\n", xscale (win_attributes.x));
- printf (" Relative upper-left Y: %s\n", yscale (win_attributes.y));
- printf (" Width: %s\n", xscale (win_attributes.width));
- printf (" Height: %s\n", yscale (win_attributes.height));
- printf (" Depth: %d\n", win_attributes.depth);
- printf (" Visual: 0x%lx\n", vinfo->visualid);
- printf (" Visual Class: %s\n", Lookup (vinfo->class, _visual_classes));
- printf (" Border width: %s\n", bscale (win_attributes.border_width));
+ printf (" Relative upper-left X: %s\n", xscale (w->geometry->x));
+ printf (" Relative upper-left Y: %s\n", yscale (w->geometry->y));
+ printf (" Width: %s\n", xscale (w->geometry->width));
+ printf (" Height: %s\n", yscale (w->geometry->height));
+ printf (" Depth: %d\n", w->geometry->depth);
+
+ win_attributes = fetch_win_attributes (w);
+
+ printf (" Visual: 0x%lx\n", (unsigned long) win_attributes->visual);
+ if (screen)
+ {
+ xcb_depth_iterator_t depth_iter;
+ xcb_visualtype_t *visual_type = NULL;
+
+ depth_iter = xcb_screen_allowed_depths_iterator (screen);
+ for (; depth_iter.rem; xcb_depth_next (&depth_iter)) {
+ xcb_visualtype_iterator_t visual_iter;
+
+ visual_iter = xcb_depth_visuals_iterator (depth_iter.data);
+ for (; visual_iter.rem; xcb_visualtype_next (&visual_iter)) {
+ if (screen->root_visual == visual_iter.data->visual_id) {
+ visual_type = visual_iter.data;
+ break;
+ }
+ }
+ }
+ if (visual_type)
+ printf (" Visual Class: %s\n", Lookup (visual_type->_class,
+ _visual_classes));
+ }
+
+ printf (" Border width: %s\n", bscale (w->geometry->border_width));
printf (" Class: %s\n",
- Lookup (win_attributes.class, _window_classes));
+ Lookup (win_attributes->_class, _window_classes));
printf (" Colormap: 0x%lx (%sinstalled)\n",
- win_attributes.colormap,
- win_attributes.map_installed ? "" : "not ");
+ (unsigned long) win_attributes->colormap,
+ win_attributes->map_is_installed ? "" : "not ");
printf (" Bit Gravity State: %s\n",
- Lookup (win_attributes.bit_gravity, _bit_gravity_states));
+ Lookup (win_attributes->bit_gravity, _bit_gravity_states));
printf (" Window Gravity State: %s\n",
- Lookup (win_attributes.win_gravity, _window_gravity_states));
+ Lookup (win_attributes->win_gravity, _window_gravity_states));
printf (" Backing Store State: %s\n",
- Lookup (win_attributes.backing_store, _backing_store_states));
+ Lookup (win_attributes->backing_store, _backing_store_states));
printf (" Save Under State: %s\n",
- win_attributes.save_under ? "yes" : "no");
+ win_attributes->save_under ? "yes" : "no");
printf (" Map State: %s\n",
- Lookup (win_attributes.map_state, _map_states));
+ Lookup (win_attributes->map_state, _map_states));
printf (" Override Redirect State: %s\n",
- win_attributes.override_redirect ? "yes" : "no");
+ win_attributes->override_redirect ? "yes" : "no");
printf (" Corners: +%d+%d -%d+%d -%d-%d +%d-%d\n",
@@ -622,4 +745,2 @@ Display_Stats_Info (Window window)
- XFree (vinfo);
-
/*
@@ -630,37 +751,41 @@ Display_Stats_Info (Window window)
/* compute size in appropriate units */
- status = XGetWMNormalHints (dpy, window, &hints, &longjunk);
- if (status && hints.flags & PResizeInc &&
- hints.width_inc != 0 && hints.height_inc != 0) {
- if (hints.flags & (PBaseSize|PMinSize)) {
- if (hints.flags & PBaseSize) {
- win_attributes.width -= hints.base_width;
- win_attributes.height -= hints.base_height;
+ if (!fetch_normal_hints (w, &hints))
+ hints.flags = 0;
+
+ if ((hints.flags & XCB_SIZE_HINT_P_RESIZE_INC) &&
+ (hints.width_inc != 0) && (hints.height_inc != 0)) {
+ if (hints.flags & (XCB_SIZE_HINT_BASE_SIZE|XCB_SIZE_HINT_P_MIN_SIZE)) {
+ if (hints.flags & XCB_SIZE_HINT_BASE_SIZE) {
+ w->geometry->width -= hints.base_width;
+ w->geometry->height -= hints.base_height;
} else {
/* ICCCM says MinSize is default for BaseSize */
- win_attributes.width -= hints.min_width;
- win_attributes.height -= hints.min_height;
+ w->geometry->width -= hints.min_width;
+ w->geometry->height -= hints.min_height;
}
}
- printf ("%dx%d", win_attributes.width/hints.width_inc,
- win_attributes.height/hints.height_inc);
+ printf ("%dx%d", w->geometry->width/hints.width_inc,
+ w->geometry->height/hints.height_inc);
} else
- printf ("%dx%d", win_attributes.width, win_attributes.height);
+ printf ("%dx%d", w->geometry->width, w->geometry->height);
- if (!(hints.flags&PWinGravity))
- hints.win_gravity = NorthWestGravity; /* per ICCCM */
+ if (!(hints.flags & XCB_SIZE_HINT_P_WIN_GRAVITY))
+ hints.win_gravity = XCB_GRAVITY_NORTH_WEST; /* per ICCCM */
/* find our window manager frame, if any */
- wmframe = window;
- while (True) {
- Window root, parent;
- Window *childlist;
- unsigned int ujunk;
-
- status = XQueryTree (dpy, wmframe, &root, &parent, &childlist, &ujunk);
- if (parent == root || !parent || !status)
+ for (wmframe = parent = w->window; parent != 0 ; wmframe = parent) {
+ xcb_query_tree_cookie_t qt_cookie;
+ xcb_query_tree_reply_t *tree;
+
+ qt_cookie = xcb_query_tree (dpy, wmframe);
+ tree = xcb_query_tree_reply (dpy, qt_cookie, &err);
+ if (!tree) {
+ Print_X_Error (dpy, err);
+ Fatal_Error ("Can't query window tree.");
+ }
+ parent = tree->parent;
+ free (tree);
+ if (parent == w->geometry->root || !parent)
break;
- wmframe = parent;
- if (status && childlist)
- XFree ((char *)childlist);
}
- if (wmframe != window) {
+ if (wmframe != w->window) {
/* WM reparented, so find edges of the frame */
@@ -669,33 +794,39 @@ Display_Stats_Info (Window window)
of the window to correctly handle the other gravities. */
+ xcb_get_geometry_cookie_t geom_cookie;
+ xcb_get_geometry_reply_t *frame_geometry;
- XWindowAttributes frame_attr;
+ geom_cookie = xcb_get_geometry (dpy, wmframe);
+ frame_geometry = xcb_get_geometry_reply (dpy, geom_cookie, &err);
- if (!XGetWindowAttributes (dpy, wmframe, &frame_attr))
- Fatal_Error ("Can't get frame attributes.");
+ if (!frame_geometry) {
+ Print_X_Error (dpy, err);
+ Fatal_Error ("Can't get frame geometry.");
+ }
switch (hints.win_gravity) {
- case NorthWestGravity: case SouthWestGravity:
- case NorthEastGravity: case SouthEastGravity:
- case WestGravity:
- rx = frame_attr.x;
+ case XCB_GRAVITY_NORTH_WEST: case XCB_GRAVITY_SOUTH_WEST:
+ case XCB_GRAVITY_NORTH_EAST: case XCB_GRAVITY_SOUTH_EAST:
+ case XCB_GRAVITY_WEST:
+ rx = frame_geometry->x;
}
switch (hints.win_gravity) {
- case NorthWestGravity: case SouthWestGravity:
- case NorthEastGravity: case SouthEastGravity:
- case EastGravity:
- xright = dw - frame_attr.x - frame_attr.width -
- 2*frame_attr.border_width;
+ case XCB_GRAVITY_NORTH_WEST: case XCB_GRAVITY_SOUTH_WEST:
+ case XCB_GRAVITY_NORTH_EAST: case XCB_GRAVITY_SOUTH_EAST:
+ case XCB_GRAVITY_EAST:
+ xright = dw - frame_geometry->x - frame_geometry->width -
+ (2 * frame_geometry->border_width);
}
switch (hints.win_gravity) {
- case NorthWestGravity: case SouthWestGravity:
- case NorthEastGravity: case SouthEastGravity:
- case NorthGravity:
- ry = frame_attr.y;
+ case XCB_GRAVITY_NORTH_WEST: case XCB_GRAVITY_SOUTH_WEST:
+ case XCB_GRAVITY_NORTH_EAST: case XCB_GRAVITY_SOUTH_EAST:
+ case XCB_GRAVITY_NORTH:
+ ry = frame_geometry->y;
}
switch (hints.win_gravity) {
- case NorthWestGravity: case SouthWestGravity:
- case NorthEastGravity: case SouthEastGravity:
- case SouthGravity:
- ybelow = dh - frame_attr.y - frame_attr.height -
- 2*frame_attr.border_width;
+ case XCB_GRAVITY_NORTH_WEST: case XCB_GRAVITY_SOUTH_WEST:
+ case XCB_GRAVITY_NORTH_EAST: case XCB_GRAVITY_SOUTH_EAST:
+ case XCB_GRAVITY_SOUTH:
+ ybelow = dh - frame_geometry->y - frame_geometry->height -
+ (2 * frame_geometry->border_width);
}
+ free (frame_geometry);
}
@@ -706,9 +837,9 @@ Display_Stats_Info (Window window)
For CenterGravity, it doesn't matter.) */
- if (hints.win_gravity == EastGravity ||
+ if (hints.win_gravity == XCB_GRAVITY_EAST ||
(abs (xright) <= 100 && abs (xright) < abs (rx)
- && hints.win_gravity != WestGravity))
+ && hints.win_gravity != XCB_GRAVITY_WEST))
showright = 1;
- if (hints.win_gravity == SouthGravity ||
+ if (hints.win_gravity == XCB_GRAVITY_SOUTH ||
(abs (ybelow) <= 100 && abs (ybelow) < abs (ry)
- && hints.win_gravity != NorthGravity))
+ && hints.win_gravity != XCB_GRAVITY_NORTH))
showbelow = 1;
@@ -731,14 +862,15 @@ Display_Stats_Info (Window window)
static const binding _gravities[] = {
- { UnmapGravity, "UnMapGravity" }, /* WARNING: both of these have*/
- { ForgetGravity, "ForgetGravity" }, /* the same value - see code */
- { NorthWestGravity, "NorthWestGravity" },
- { NorthGravity, "NorthGravity" },
- { NorthEastGravity, "NorthEastGravity" },
- { WestGravity, "WestGravity" },
- { CenterGravity, "CenterGravity" },
- { EastGravity, "EastGravity" },
- { SouthWestGravity, "SouthWestGravity" },
- { SouthGravity, "SouthGravity" },
- { SouthEastGravity, "SouthEastGravity" },
- { StaticGravity, "StaticGravity" },
+ /* WARNING: the first two of these have the same value - see code */
+ { XCB_GRAVITY_WIN_UNMAP, "UnMapGravity" },
+ { XCB_GRAVITY_BIT_FORGET, "ForgetGravity" },
+ { XCB_GRAVITY_NORTH_WEST, "NorthWestGravity" },
+ { XCB_GRAVITY_NORTH, "NorthGravity" },
+ { XCB_GRAVITY_NORTH_EAST, "NorthEastGravity" },
+ { XCB_GRAVITY_WEST, "WestGravity" },
+ { XCB_GRAVITY_CENTER, "CenterGravity" },
+ { XCB_GRAVITY_EAST, "EastGravity" },
+ { XCB_GRAVITY_SOUTH_WEST, "SouthWestGravity" },
+ { XCB_GRAVITY_SOUTH, "SouthGravity" },
+ { XCB_GRAVITY_SOUTH_EAST, "SouthEastGravity" },
+ { XCB_GRAVITY_STATIC, "StaticGravity" },
{ 0, NULL } };
@@ -746,5 +878,5 @@ static const binding _gravities[] = {
static const binding _backing_store_hint[] = {
- { NotUseful, "NotUseful" },
- { WhenMapped, "WhenMapped" },
- { Always, "Always" },
+ { XCB_BACKING_STORE_NOT_USEFUL, "NotUseful" },
+ { XCB_BACKING_STORE_WHEN_MAPPED,"WhenMapped" },
+ { XCB_BACKING_STORE_ALWAYS, "Always" },
{ 0, NULL } };
@@ -756,9 +888,11 @@ static const binding _bool[] = {
+/*
+ * Requires wininfo members initialized:
+ * window, attr_cookie (or win_attributes)
+ */
static void
-Display_Bits_Info (Window window)
+Display_Bits_Info (struct wininfo * w)
{
- XWindowAttributes win_attributes;
-
- if (!XGetWindowAttributes (dpy, window, &win_attributes))
- Fatal_Error ("Can't get window attributes.");
+ xcb_get_window_attributes_reply_t *win_attributes
+ = fetch_win_attributes (w);
@@ -766,12 +900,13 @@ Display_Bits_Info (Window window)
printf (" Bit gravity: %s\n",
- Lookup (win_attributes.bit_gravity, _gravities+1));
+ Lookup (win_attributes->bit_gravity, _gravities+1));
printf (" Window gravity: %s\n",
- Lookup (win_attributes.win_gravity, _gravities));
+ Lookup (win_attributes->win_gravity, _gravities));
printf (" Backing-store hint: %s\n",
- Lookup (win_attributes.backing_store, _backing_store_hint));
+ Lookup (win_attributes->backing_store, _backing_store_hint));
printf (" Backing-planes to be preserved: 0x%lx\n",
- win_attributes.backing_planes);
- printf (" Backing pixel: %ld\n", win_attributes.backing_pixel);
+ (unsigned long) win_attributes->backing_planes);
+ printf (" Backing pixel: %ld\n",
+ (unsigned long) win_attributes->backing_pixel);
printf (" Save-unders: %s\n",
- Lookup (win_attributes.save_under, _bool));
+ Lookup (win_attributes->save_under, _bool));
}
@@ -783,27 +918,27 @@ Display_Bits_Info (Window window)
static const binding _event_mask_names[] = {
- { KeyPressMask, "KeyPress" },
- { KeyReleaseMask, "KeyRelease" },
- { ButtonPressMask, "ButtonPress" },
- { ButtonReleaseMask, "ButtonRelease" },
- { EnterWindowMask, "EnterWindow" },
- { LeaveWindowMask, "LeaveWindow" },
- { PointerMotionMask, "PointerMotion" },
- { PointerMotionHintMask, "PointerMotionHint" },
- { Button1MotionMask, "Button1Motion" },
- { Button2MotionMask, "Button2Motion" },
- { Button3MotionMask, "Button3Motion" },
- { Button4MotionMask, "Button4Motion" },
- { Button5MotionMask, "Button5Motion" },
- { ButtonMotionMask, "ButtonMotion" },
- { KeymapStateMask, "KeymapState" },
- { ExposureMask, "Exposure" },
- { VisibilityChangeMask, "VisibilityChange" },
- { StructureNotifyMask, "StructureNotify" },
- { ResizeRedirectMask, "ResizeRedirect" },
- { SubstructureNotifyMask, "SubstructureNotify" },
- { SubstructureRedirectMask, "SubstructureRedirect" },
- { FocusChangeMask, "FocusChange" },
- { PropertyChangeMask, "PropertyChange" },
- { ColormapChangeMask, "ColormapChange" },
- { OwnerGrabButtonMask, "OwnerGrabButton" },
+ { XCB_EVENT_MASK_KEY_PRESS, "KeyPress" },
+ { XCB_EVENT_MASK_KEY_RELEASE, "KeyRelease" },
+ { XCB_EVENT_MASK_BUTTON_PRESS, "ButtonPress" },
+ { XCB_EVENT_MASK_BUTTON_RELEASE, "ButtonRelease" },
+ { XCB_EVENT_MASK_ENTER_WINDOW, "EnterWindow" },
+ { XCB_EVENT_MASK_LEAVE_WINDOW, "LeaveWindow" },
+ { XCB_EVENT_MASK_POINTER_MOTION, "PointerMotion" },
+ { XCB_EVENT_MASK_POINTER_MOTION_HINT, "PointerMotionHint" },
+ { XCB_EVENT_MASK_BUTTON_1_MOTION, "Button1Motion" },
+ { XCB_EVENT_MASK_BUTTON_2_MOTION, "Button2Motion" },
+ { XCB_EVENT_MASK_BUTTON_3_MOTION, "Button3Motion" },
+ { XCB_EVENT_MASK_BUTTON_4_MOTION, "Button4Motion" },
+ { XCB_EVENT_MASK_BUTTON_5_MOTION, "Button5Motion" },
+ { XCB_EVENT_MASK_BUTTON_MOTION, "ButtonMotion" },
+ { XCB_EVENT_MASK_KEYMAP_STATE, "KeymapState" },
+ { XCB_EVENT_MASK_EXPOSURE, "Exposure" },
+ { XCB_EVENT_MASK_VISIBILITY_CHANGE, "VisibilityChange" },
+ { XCB_EVENT_MASK_STRUCTURE_NOTIFY, "StructureNotify" },
+ { XCB_EVENT_MASK_RESIZE_REDIRECT, "ResizeRedirect" },
+ { XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY, "SubstructureNotify" },
+ { XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, "SubstructureRedirect" },
+ { XCB_EVENT_MASK_FOCUS_CHANGE, "FocusChange" },
+ { XCB_EVENT_MASK_PROPERTY_CHANGE, "PropertyChange" },
+ { XCB_EVENT_MASK_COLOR_MAP_CHANGE, "ColormapChange" },
+ { XCB_EVENT_MASK_OWNER_GRAB_BUTTON, "OwnerGrabButton" },
{ 0, NULL } };
@@ -824,10 +959,11 @@ Display_Event_Mask (long mask)
* Display info on events
+ *
+ * Requires wininfo members initialized:
+ * window, attr_cookie (or win_attributes)
*/
static void
-Display_Events_Info (Window window)
+Display_Events_Info (struct wininfo *w)
{
- XWindowAttributes win_attributes;
-
- if (!XGetWindowAttributes (dpy, window, &win_attributes))
- Fatal_Error ("Can't get window attributes.");
+ xcb_get_window_attributes_reply_t *win_attributes
+ = fetch_win_attributes (w);
@@ -835,9 +971,9 @@ Display_Events_Info (Window window)
printf (" Someone wants these events:\n");
- Display_Event_Mask (win_attributes.all_event_masks);
+ Display_Event_Mask (win_attributes->all_event_masks);
printf (" Do not propagate these events:\n");
- Display_Event_Mask (win_attributes.do_not_propagate_mask);
+ Display_Event_Mask (win_attributes->do_not_propagate_mask);
printf (" Override redirection?: %s\n",
- Lookup (win_attributes.override_redirect, _bool));
+ Lookup (win_attributes->override_redirect, _bool));
}
@@ -853,7 +989,9 @@ Display_Events_Info (Window window)
* recurse - true to show children information
+ *
+ * Requires wininfo members initialized: window, tree_cookie
*/
static void
-Display_Tree_Info (Window window, int recurse)
+Display_Tree_Info (struct wininfo *w, int recurse)
{
- display_tree_info_1 (window, recurse, 0);
+ display_tree_info_1 (w, recurse, 0);
}
@@ -864,24 +1002,31 @@ Display_Tree_Info (Window window, int recurse)
static void
-display_tree_info_1 (Window window, int recurse, int level)
+display_tree_info_1 (struct wininfo *w, int recurse, int level)
{
int i, j;
- int rel_x, rel_y, abs_x, abs_y;
- unsigned int width, height, border, depth;
- Window root_win, parent_win;
unsigned int num_children;
- Window *child_list;
- XClassHint classhint;
+ xcb_query_tree_reply_t *tree;
- if (!XQueryTree (dpy, window, &root_win, &parent_win, &child_list,
- &num_children))
+ tree = xcb_query_tree_reply (dpy, w->tree_cookie, &err);
+ if (!tree) {
+ Print_X_Error (dpy, err);
Fatal_Error ("Can't query window tree.");
+ }
if (level == 0) {
+ struct wininfo rw, pw;
+ rw.window = tree->root;
+ rw.wm_name_cookie = xcb_get_wm_name (dpy, rw.window);
+ pw.window = tree->parent;
+ pw.wm_name_cookie = xcb_get_wm_name (dpy, pw.window);
+ xcb_flush (dpy);
+
printf ("\n");
printf (" Root window id: ");
- Display_Window_Id (root_win, True);
+ Display_Window_Id (&rw, True);
printf (" Parent window id: ");
- Display_Window_Id (parent_win, True);
+ Display_Window_Id (&pw, True);
}
+ num_children = xcb_query_tree_children_length (tree);
+
if (level == 0 || num_children > 0) {
@@ -893,38 +1038,86 @@ display_tree_info_1 (Window window, int recurse, int level)
- for (i = (int)num_children - 1; i >= 0; i--) {
- printf (" ");
- for (j = 0; j < level; j++) printf (" ");
- Display_Window_Id (child_list[i], False);
- printf (": (");
- if (XGetClassHint (dpy, child_list[i], &classhint)) {
- if (classhint.res_name) {
- printf ("\"%s\" ", classhint.res_name);
- XFree (classhint.res_name);
- } else
- printf ("(none) ");
- if (classhint.res_class) {
- printf ("\"%s\") ", classhint.res_class);
- XFree (classhint.res_class);
+ if (num_children > 0) {
+ xcb_window_t *child_list = xcb_query_tree_children (tree);
+ struct wininfo *children
+ = calloc (num_children, sizeof(struct wininfo));
+
+ if (children == NULL)
+ Fatal_Error ("Failed to allocate memory in display_tree_info");
+
+ for (i = (int)num_children - 1; i >= 0; i--) {
+ struct wininfo *cw = &children[i];
+
+ cw->window = child_list[i];
+ cw->wm_name_cookie = xcb_get_wm_name (dpy, child_list[i]);
+ cw->wm_class_cookie = xcb_get_wm_class (dpy, child_list[i]);
+ cw->geometry_cookie = xcb_get_geometry (dpy, child_list[i]);
+ cw->trans_coords_cookie = xcb_translate_coordinates
+ (dpy, child_list[i], tree->root, 0, 0);
+ if (recurse)
+ cw->tree_cookie = xcb_query_tree (dpy, child_list[i]);
+ }
+ xcb_flush (dpy);
+
+ for (i = (int)num_children - 1; i >= 0; i--) {
+ struct wininfo *cw = &children[i];
+ xcb_get_wm_class_reply_t classhint;
+ xcb_get_geometry_reply_t *geometry;
+
+ printf (" ");
+ for (j = 0; j < level; j++) printf (" ");
+ Display_Window_Id (cw, False);
+ printf (": (");
+
+ if (xcb_get_wm_class_reply (dpy, cw->wm_class_cookie,
+ &classhint, NULL)) {
+ if (classhint.instance_name)
+ printf ("\"%s\" ", classhint.instance_name);
+ else
+ printf ("(none) ");
+
+ if (classhint.class_name)
+ printf ("\"%s\") ", classhint.class_name);
+ else
+ printf ("(none)) ");
+
+ xcb_get_wm_class_reply_wipe (&classhint);
} else
- printf ("(none)) ");
- } else
- printf (") ");
-
- if (XGetGeometry (dpy, child_list[i], &root_win,
- &rel_x, &rel_y, &width, &height, &border, &depth)) {
- Window child;
-
- printf (" %ux%u+%d+%d", width, height, rel_x, rel_y);
- if (XTranslateCoordinates (dpy, child_list[i], root_win,
- 0 ,0, &abs_x, &abs_y, &child)) {
- printf (" +%d+%d", abs_x - border, abs_y - border);
+ printf (") ");
+
+ geometry = xcb_get_geometry_reply(dpy, cw->geometry_cookie, &err);
+ if (geometry) {
+ xcb_translate_coordinates_reply_t *trans_coords;
+
+ printf (" %ux%u+%d+%d", geometry->width, geometry->height,
+ geometry->x, geometry->y);
+
+ trans_coords = xcb_translate_coordinates_reply
+ (dpy, cw->trans_coords_cookie, &err);
+
+ if (trans_coords) {
+ int16_t abs_x = (int16_t) trans_coords->dst_x;
+ int16_t abs_y = (int16_t) trans_coords->dst_y;
+ int border = geometry->border_width;
+
+ printf (" +%d+%d", abs_x - border, abs_y - border);
+ free (trans_coords);
+ } else if (err) {
+ Print_X_Error (dpy, err);
+ }
+
+ free (geometry);
+ } else if (err) {
+ Print_X_Error (dpy, err);
}
- }
- printf ("\n");
+ printf ("\n");
- if (recurse)
- display_tree_info_1 (child_list[i], 1, level+1);
+ if (recurse)
+ display_tree_info_1 (cw, 1, level+1);
+
+ wininfo_wipe (cw);
+ }
+ free (children);
}
- if (child_list) XFree ((char *)child_list);
+ free (tree); /* includes storage for child_list[] */
}
@@ -936,3 +1129,3 @@ display_tree_info_1 (Window window, int recurse, int level)
static void
-Display_Hints (XSizeHints *hints)
+Display_Hints (xcb_size_hints_t *hints)
{
@@ -942,3 +1135,3 @@ Display_Hints (XSizeHints *hints)
- if (flags & USPosition)
+ if (flags & XCB_SIZE_HINT_US_POSITION)
printf (" User supplied location: %s, %s\n",
@@ -946,3 +1139,3 @@ Display_Hints (XSizeHints *hints)
- if (flags & PPosition)
+ if (flags & XCB_SIZE_HINT_P_POSITION)
printf (" Program supplied location: %s, %s\n",
@@ -950,3 +1143,3 @@ Display_Hints (XSizeHints *hints)
- if (flags & USSize) {
+ if (flags & XCB_SIZE_HINT_US_SIZE) {
printf (" User supplied size: %s by %s\n",
@@ -955,3 +1148,3 @@ Display_Hints (XSizeHints *hints)
- if (flags & PSize)
+ if (flags & XCB_SIZE_HINT_P_SIZE)
printf (" Program supplied size: %s by %s\n",
@@ -959,3 +1152,3 @@ Display_Hints (XSizeHints *hints)
- if (flags & PMinSize)
+ if (flags & XCB_SIZE_HINT_P_MIN_SIZE)
printf (" Program supplied minimum size: %s by %s\n",
@@ -963,3 +1156,3 @@ Display_Hints (XSizeHints *hints)
- if (flags & PMaxSize)
+ if (flags & XCB_SIZE_HINT_P_MAX_SIZE)
printf (" Program supplied maximum size: %s by %s\n",
@@ -967,3 +1160,3 @@ Display_Hints (XSizeHints *hints)
- if (flags & PBaseSize) {
+ if (flags & XCB_SIZE_HINT_BASE_SIZE) {
printf (" Program supplied base size: %s by %s\n",
@@ -972,3 +1165,3 @@ Display_Hints (XSizeHints *hints)
- if (flags & PResizeInc) {
+ if (flags & XCB_SIZE_HINT_P_RESIZE_INC) {
printf (" Program supplied x resize increment: %s\n",
@@ -978,3 +1171,3 @@ Display_Hints (XSizeHints *hints)
if (hints->width_inc != 0 && hints->height_inc != 0) {
- if (flags & USSize)
+ if (flags & XCB_SIZE_HINT_US_SIZE)
printf (" User supplied size in resize increments: %s by %s\n",
@@ -982,3 +1175,3 @@ Display_Hints (XSizeHints *hints)
(yscale (hints->height / hints->height_inc)));
- if (flags & PSize)
+ if (flags & XCB_SIZE_HINT_P_SIZE)
printf (" Program supplied size in resize increments: %s by %s\n",
@@ -986,6 +1179,6 @@ Display_Hints (XSizeHints *hints)
(yscale (hints->height / hints->height_inc)));
- if (flags & PMinSize)
+ if (flags & XCB_SIZE_HINT_P_MIN_SIZE)
printf (" Program supplied minimum size in resize increments: %s by %s\n",
xscale (hints->min_width / hints->width_inc), yscale (hints->min_height / hints->height_inc));
- if (flags & PBaseSize)
+ if (flags & XCB_SIZE_HINT_BASE_SIZE)
printf (" Program supplied base size in resize increments: %s by %s\n",
@@ -996,10 +1189,10 @@ Display_Hints (XSizeHints *hints)
- if (flags & PAspect) {
+ if (flags & XCB_SIZE_HINT_P_ASPECT) {
printf (" Program supplied min aspect ratio: %s/%s\n",
- xscale (hints->min_aspect.x), yscale (hints->min_aspect.y));
+ xscale (hints->min_aspect_num), yscale (hints->min_aspect_den));
printf (" Program supplied max aspect ratio: %s/%s\n",
- xscale (hints->max_aspect.x), yscale (hints->max_aspect.y));
+ xscale (hints->max_aspect_num), yscale (hints->max_aspect_den));
}
- if (flags & PWinGravity) {
+ if (flags & XCB_SIZE_HINT_P_WIN_GRAVITY) {
printf (" Program supplied window gravity: %s\n",
@@ -1014,9 +1207,8 @@ Display_Hints (XSizeHints *hints)
static void
-Display_Size_Hints (Window window)
+Display_Size_Hints (struct wininfo *w)
{
- XSizeHints *hints = XAllocSizeHints ();
- long supplied;
+ xcb_size_hints_t hints;
printf ("\n");
- if (!XGetWMNormalHints (dpy, window, hints, &supplied))
+ if (!fetch_normal_hints (w, &hints))
printf (" No normal window size hints defined\n");
@@ -1024,7 +1216,6 @@ Display_Size_Hints (Window window)
printf (" Normal window size hints:\n");
- hints->flags &= supplied;
- Display_Hints (hints);
+ Display_Hints (&hints);
}
- if (!XGetWMSizeHints (dpy, window, hints, &supplied, XA_WM_ZOOM_HINTS))
+ if (!xcb_get_wm_size_hints_reply (dpy, w->zoom_cookie, &hints, NULL))
printf (" No zoom window size hints defined\n");
@@ -1032,6 +1223,4 @@ Display_Size_Hints (Window window)
printf (" Zoom window size hints:\n");
- hints->flags &= supplied;
- Display_Hints (hints);
+ Display_Hints (&hints);
}
- XFree ((char *)hints);
}
@@ -1040,9 +1229,10 @@ Display_Size_Hints (Window window)
static void
-Display_Window_Shape (Window window)
+Display_Window_Shape (xcb_window_t window)
{
- Bool ws, bs;
- int xws, yws, xbs, ybs;
- unsigned int wws, hws, wbs, hbs;
+ const xcb_query_extension_reply_t *shape_query;
+ xcb_shape_query_extents_cookie_t extents_cookie;
+ xcb_shape_query_extents_reply_t *extents;
- if (!XShapeQueryExtension (dpy, &bs, &ws))
+ shape_query = xcb_get_extension_data (dpy, &xcb_shape_id);
+ if (!shape_query->present)
return;
@@ -1050,5 +1240,18 @@ Display_Window_Shape (Window window)
printf ("\n");
- XShapeQueryExtents (dpy, window, &ws, &xws, &yws, &wws, &hws,
- &bs, &xbs, &ybs, &wbs, &hbs);
- if (!ws)
+
+ extents_cookie = xcb_shape_query_extents (dpy, window);
+ extents = xcb_shape_query_extents_reply (dpy, extents_cookie, &err);
+
+ if (!extents) {
+ if (err)
+ Print_X_Error (dpy, err);
+ else
+ {
+ printf (" No window shape defined\n");
+ printf (" No border shape defined\n");
+ }
+ return;
+ }
+
+ if (!extents->bounding_shaped)
printf (" No window shape defined\n");
@@ -1056,6 +1259,9 @@ Display_Window_Shape (Window window)
printf (" Window shape extents: %sx%s",
- xscale (wws), yscale (hws));
- printf ("+%s+%s\n", xscale (xws), yscale (yws));
+ xscale (extents->bounding_shape_extents_width),
+ yscale (extents->bounding_shape_extents_height));
+ printf ("+%s+%s\n",
+ xscale (extents->bounding_shape_extents_x),
+ yscale (extents->bounding_shape_extents_y));
}
- if (!bs)
+ if (!extents->clip_shaped)
printf (" No border shape defined\n");
@@ -1063,5 +1269,10 @@ Display_Window_Shape (Window window)
printf (" Border shape extents: %sx%s",
- xscale (wbs), yscale (hbs));
- printf ("+%s+%s\n", xscale (xbs), yscale (ybs));
+ xscale (extents->clip_shape_extents_width),
+ yscale (extents->clip_shape_extents_height));
+ printf ("+%s+%s\n",
+ xscale (extents->clip_shape_extents_x),
+ yscale (extents->clip_shape_extents_y));
}
+
+ free (extents);
}
@@ -1070,9 +1281,12 @@ Display_Window_Shape (Window window)
* Display Window Manager Info
+ *
+ * Requires wininfo members initialized:
+ * window, hints_cookie
*/
static const binding _state_hints[] = {
- { DontCareState, "Don't Care State" },
- { NormalState, "Normal State" },
- { ZoomState, "Zoomed State" },
- { IconicState, "Iconic State" },
- { InactiveState, "Inactive State" },
+ { XCB_WM_STATE_WITHDRAWN, "Withdrawn State" },
+ { XCB_WM_STATE_NORMAL, "Normal State" },
+ { XCB_WM_STATE_ICONIC, "Iconic State" },
+/* xwininfo previously also reported the ZoomState & InactiveState,
+ but ICCCM declared those obsolete long ago */
{ 0, NULL } };
@@ -1080,14 +1294,16 @@ static const binding _state_hints[] = {
static void
-Display_WM_Info (Window window)
+Display_WM_Info (struct wininfo *w)
{
- XWMHints *wmhints;
+ xcb_wm_hints_t wmhints;
long flags;
- wmhints = XGetWMHints (dpy, window);
printf ("\n");
- if (!wmhints) {
+ if (!xcb_get_wm_hints_reply(dpy, w->hints_cookie, &wmhints, &err))
+ {
printf (" No window manager hints defined\n");
+ if (err)
+ Print_X_Error (dpy, err);
return;
}
- flags = wmhints->flags;
+ flags = wmhints.flags;
@@ -1095,20 +1311,31 @@ Display_WM_Info (Window window)
- if (flags & InputHint)
+ if (flags & XCB_WM_HINT_INPUT)
printf (" Client accepts input or input focus: %s\n",
- Lookup (wmhints->input, _bool));
+ Lookup (wmhints.input, _bool));
+
+ if (flags & XCB_WM_HINT_ICON_WINDOW) {
+ struct wininfo iw;
+ iw.window = wmhints.icon_window;
+ iw.wm_name_cookie = xcb_get_wm_name (dpy, iw.window);
- if (flags & IconWindowHint) {
printf (" Icon window id: ");
- Display_Window_Id (wmhints->icon_window, True);
+ Display_Window_Id (&iw, True);
}
- if (flags & IconPositionHint)
+ if (flags & XCB_WM_HINT_ICON_POSITION)
printf (" Initial icon position: %s, %s\n",
- xscale (wmhints->icon_x), yscale (wmhints->icon_y));
+ xscale (wmhints.icon_x), yscale (wmhints.icon_y));
- if (flags & StateHint)
+ if (flags & XCB_WM_HINT_STATE)
printf (" Initial state is %s\n",
- Lookup (wmhints->initial_state, _state_hints));
+ Lookup (wmhints.initial_state, _state_hints));
+}
- XFree (wmhints);
+/* Frees all members of a wininfo struct, but not the struct itself */
+static void
+wininfo_wipe (struct wininfo *w)
+{
+ free (w->geometry);
+ free (w->win_attributes);
+ free (w->normal_hints);
}