accessing windows in X11

This is a discussion on accessing windows in X11 within the Linux Programming forums, part of the Platform Specific Boards category; My C++ program needs to run something from a script and take over control of the resulting window. I know ...

  1. #1
    Registered User
    Join Date
    Nov 2009
    Posts
    6

    accessing windows in X11

    My C++ program needs to run something from a script and take over control of the resulting window. I know how to use XQueryTree() to get a list of children from the root window, but can't find anything on how to interpret these. In what order will the child windows be given and how can I navigate them to find a specific one? Or would it be easier to run the scripts directly inside a window I created earlier?
    Last edited by skyn3t; 04-05-2010 at 11:40 PM.

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    You identify the windows by name. The window name is a property you can fetch via XGetWindowProperty(), they are unsigned char strings. The name is whatever you have set the window title to, so you can do a strcmp() to find it.

    Here's some demo code that fetches a list of all the current windows and prints their names/titles. Nb, I don't use XQueryTree() to get the list, I fetch another property, "_NET_CLIENT_LIST" from the root window.

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <X11/Xlib.h>
    #include <X11/Xatom.h>
    #include <errno.h>
    
    /* compile -lX11 */
    
    Window *winlist (Display *disp, unsigned long *len);
    char *winame (Display *disp, Window win); 
    
    int main(int argc, char *argv[]) {
    	int i;
    	unsigned long len;
    	Display *disp = XOpenDisplay(NULL);
    	Window *list;
    	char *name;
    
    	if (!disp) {
    		puts("no display!");
    		return -1;
    	}
    
    	list = (Window*)winlist(disp,&len);
    
    	for (i=0;i<(int)len;i++) {
    		name = winame(disp,list[i]);
    		printf("-->%s<--\n",name);
    		free(name);
    	}
    
    	XFree(list);
    
    	XCloseDisplay(disp);
    	return 0;
    }
    
    
    Window *winlist (Display *disp, unsigned long *len) {
    	Atom prop = XInternAtom(disp,"_NET_CLIENT_LIST",False), type;
    	int form;
    	unsigned long remain;
    	unsigned char *list;
    
    	errno = 0;
    	if (XGetWindowProperty(disp,XDefaultRootWindow(disp),prop,0,1024,False,XA_WINDOW,
                    &type,&form,len,&remain,&list) != Success) {
    		perror("winlist() -- GetWinProp");
    		return 0;
    	}
    	
    	return (Window*)list;
    }
    
    
    char *winame (Display *disp, Window win) {
    	Atom prop = XInternAtom(disp,"WM_NAME",False), type;
    	int form;
    	unsigned long remain, len;
    	unsigned char *list;
    
    	errno = 0;
    	if (XGetWindowProperty(disp,win,prop,0,1024,False,XA_STRING,
                    &type,&form,&len,&remain,&list) != Success) {
    		perror("winlist() -- GetWinProp");
    		return NULL;
    	}
    
    	return (char*)list;
    }
    Xlib is a tough nut to crack. Here's another function you can throw into the above program to check any property -- the properties are also strings altho they may appear to be defines or macros in the documentation because they are all CAPS (like "_NET_CLIENT_LIST" and "WM_NAME") they are not defined anywhere, you just use them as quoted char strings (this is different than the Atom types, XA_, which are actual defines):
    Code:
    int getprop (Display *disp, char *name, Window win) {
            Atom prop = XInternAtom(disp,name,False), type;
            int form, r = 0;
            unsigned long len, remain;
            unsigned char *list;
            char *tname;
    
            errno = 0;
            if (XGetWindowProperty(disp,win,prop,0,1024,False,AnyPropertyType,
                    &type,&form,&len,&remain,&list) != Success) {
                    perror("GetWinProp");
                    return 0;
            }
            if (type == None) printf("%s is not available.\n",name);
            else {
                    tname = atomtype(type);
                    printf ("%s (type %s, %lu %d-bit items) remaining: %lu\n",name,tname,len,form,remain);
                    XFree(tname);
                    r = 1;
            }
            XFree(list);
            return r;
    }
    
    char *atomtype (Atom x) {
    	char *type = malloc(32);
    	switch (x) {
    		case XA_PRIMARY:
    			strcpy(type,"XA_PRIMARY");
    			break;
    		case XA_SECONDARY:
    			strcpy(type,"XA_SECONDARY");
    			break;
    		case XA_ARC:
    			strcpy(type,"XA_ARC");
    			break;
    		case XA_ATOM:
    			strcpy(type,"XA_ATOM");
    			break;
    		case XA_CARDINAL:
    			strcpy(type,"XA_CARDINAL");
    			break;
    		case XA_INTEGER:
    			strcpy(type,"XA_INTEGER");
    			break;
    		case XA_STRING:
    			strcpy(type,"XA_STRING");
    			break;
    		case XA_WINDOW:
    			strcpy(type,"XA_WINDOW");
    			break;
    		case XA_WM_HINTS:
    			strcpy(type,"XA_WM_HINTS");
    			break;
    		default:
    			sprintf(type,"unlisted (%lu), see Xatom.h",x);
    			break;
    		}
    		return type;
    }
    I turned the Atom type defines into strings here for human readability in the output.
    Last edited by MK27; 04-06-2010 at 08:19 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    Nov 2009
    Posts
    6
    I tried your code but their are errors in the included libraries. I'm using Codeblocks and the GNU GCC Compiler.
    Last edited by skyn3t; 05-03-2010 at 09:03 PM.

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by skyn3t View Post
    I tried your code but their are errors in the included libraries. I'm using Codeblocks and the GNU GCC Compiler.
    If there were errors in the included libraries, you would not be looking a graphical desktop right now, because those are in pretty heavy use there.

    Post the errors. It could be something in my code, altho I have run those functions on a few different systems so I am pretty sure they are okay. Also, hopefully you noticed:

    Code:
    /* compile -lX11 */
    which means you need to do this:

    gcc thecode.c -lX11
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    Registered User
    Join Date
    Nov 2009
    Posts
    6
    This is the error message:
    Code:
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|81|error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘Xtransports’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|132|error: expected ‘)’ before ‘ciptr’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|152|error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|190|error: ‘TRANS’ declared as function returning a function|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c||In function ‘TRANS’:|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|210|warning: implicit declaration of function ‘PRMSG’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|210|error: ‘address’ undeclared (first use in this function)|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|210|error: (Each undeclared identifier is reported only once|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|210|error: for each function it appears in.)|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|214|warning: implicit declaration of function ‘xalloc’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|214|warning: implicit declaration of function ‘strlen’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|214|warning: incompatible implicit declaration of built-in function ‘strlen’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|215|warning: implicit declaration of function ‘strcpy’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|215|warning: incompatible implicit declaration of built-in function ‘strcpy’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|224|warning: implicit declaration of function ‘strchr’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|224|warning: incompatible implicit declaration of built-in function ‘strchr’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|224|error: ‘NULL’ undeclared (first use in this function)|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|225|warning: implicit declaration of function ‘strrchr’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|225|warning: incompatible implicit declaration of built-in function ‘strrchr’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|228|error: ‘protocol’ undeclared (first use in this function)|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|229|error: ‘host’ undeclared (first use in this function)|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|230|error: ‘port’ undeclared (first use in this function)|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|231|warning: implicit declaration of function ‘xfree’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|306|error: ‘GetHostname’ undeclared (first use in this function)|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|306|error: called object ‘TRANS(<erroneous-expression>)’ is not a function|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|416|error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘TRANS’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|686|error: expected ‘)’ before ‘ciptr’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|879|error: expected ‘)’ before ‘ciptr’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|886|error: expected ‘)’ before ‘ciptr’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|893|error: expected ‘)’ before ‘ciptr’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|900|error: expected ‘)’ before ‘ciptr’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|907|error: expected ‘)’ before ‘ciptr’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|914|error: expected ‘)’ before ‘ciptr’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|921|error: expected ‘)’ before ‘ciptr’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|936|error: expected ‘)’ before ‘ciptr’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|951|error: expected ‘)’ before ‘ciptr’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|959|error: expected ‘)’ before ‘ciptr’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|979|error: expected ‘)’ before ‘ciptr’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|1000|error: expected ‘)’ before ‘ciptr’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|1362|error: ‘TRANS’ declared as function returning a function|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|1360|error: redefinition of ‘TRANS’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|190|error: previous definition of ‘TRANS’ was here|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c||In function ‘TRANS’:|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|1369|warning: incompatible implicit declaration of built-in function ‘strlen’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|1370|error: ‘maxlen’ undeclared (first use in this function)|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|1371|warning: implicit declaration of function ‘strncpy’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|1371|warning: incompatible implicit declaration of built-in function ‘strncpy’|
    /home/skynet/marketbot/testrun/testr/include/X11/Xtrans/Xtrans.c|1371|error: ‘buf’ undeclared (first use in this function)|
    ||=== Build finished: 32 errors, 14 warnings ===|

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    I don't even have Xtrans installed. I do not see how or why it should have anything to do with this.

    You should trace where it is being called from, you are using a non-standard include path too.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Registered User
    Join Date
    Nov 2009
    Posts
    6
    It's fixed. I was trying to use the GUI, which I had misconfigured, but it works now in the command prompt.

  8. #8
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875
    That was the basic way (unless you launched the window from your C/C++ code) we had to find wayward windows on Win31 back in the day, just iterate through the available windows until you found the title. Not foolproof but good enough. PITA though. Its easier when you launch the window itself and take the handle or launch the process and track it through the pid...
    C/C++ Environment: GNU CC/Emacs
    Make system: CMake
    Debuggers: Valgrind/GDB

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Just starting Windows Programming, School me!
    By Shamino in forum Windows Programming
    Replies: 17
    Last Post: 02-22-2008, 07:14 AM
  2. how to make a windows application
    By crvenkapa in forum C++ Programming
    Replies: 3
    Last Post: 03-26-2007, 09:59 AM
  3. Script errors - bool unrecognized and struct issues
    By ulillillia in forum Windows Programming
    Replies: 10
    Last Post: 12-18-2006, 03:44 AM
  4. Question..
    By pode in forum Windows Programming
    Replies: 12
    Last Post: 12-19-2004, 06:05 PM
  5. IE 6 status bar
    By DavidP in forum Tech Board
    Replies: 15
    Last Post: 10-23-2002, 05:31 PM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21