LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-17-2017, 11:20 AM   #1
BW-userx
Senior Member
 
Registered: Sep 2013
Location: MID-SOUTH USA
Distribution: Void Linux / Slackware 14.2
Posts: 4,622

Rep: Reputation: 856Reputation: 856Reputation: 856Reputation: 856Reputation: 856Reputation: 856Reputation: 856
C programming get VTDs not STD's.


NO or Yes, I have no idea what I am doing.

I am pot shot'ing trying to get the numbers of V desktops and current virtual desktop. Google is returning nothing of use to me. so I am just taking shots in the dark and getting no where.

Code:
/*
 * 
 * July 17, 2017
 * For learing how to get and use Virtual Desktops
 * in Linux via C 
 * 
 * *****/
 

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <xcb/xcb_ewmh.h>


int main (int argc, char **argv)
{
	
	Atom atom_root, type;
	int VT=0;
	
	//try and get current  virtual desktop (VDT)
	VT = Get_NET_NUMBER_OF_DESKTOPS(atom_root,VT);
	
	printf("%d\n", VT);
	
	return 0;
}
Code:
userx%slackwhere š LearningVDTinC š> gcc main.c
main.c: In function 'main':
main.c:26:7: warning: implicit declaration of function 'Get_NET_NUMBER_OF_DESKTOPS' [-Wimplicit-function-declaration]
  VT = Get_NET_NUMBER_OF_DESKTOPS(atom_root,VT);
       ^
/tmp/ccFeTY7v.o: In function `main':
main.c:(.text+0x28): undefined reference to `Get_NET_NUMBER_OF_DESKTOPS'
collect2: error: ld returned 1 exit status
referencing this c code for function calls.

https://github.com/bbidulock/etwm/blob/master/ewmh.c

Get_NET_NUMBER_OF_DESKTOPS


terminal
Code:
userx%slackwhere ⚡ imaging ⚡> xprop -root  _NET_NUMBER_OF_DESKTOPS
_NET_NUMBER_OF_DESKTOPS(CARDINAL) = 6
userx%slackwhere ⚡ imaging ⚡>

Last edited by BW-userx; 07-17-2017 at 11:23 AM.
 
Old 07-17-2017, 01:30 PM   #2
rtmistler
Moderator
 
Registered: Mar 2011
Location: Sutton, MA. USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu
Posts: 5,415
Blog Entries: 12

Rep: Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882
Hi,

Use the getenv(3) call.

Some minor issues are that you need to export new environment variables. For instance, $PATH is very common, or shall we say when you enter a new shell, it has an environment and you get that when you run a compiled program from that shell.

But if you do an experiment like type: ABC=123 you can echo $ABC in that shell and see it works, however it won't be seen by a program using getenv() from that shell unless you export the ABC environment variable.

There are also related functions shown in the man page at the bottom.

getenv() should work for you.
Code:
#include <stdio.h>
#include <stdlib.h>

void main()
{
    const char *s = getenv("PATH");

    if (s == NULL)
        printf("Getenv ret NULL\n");
    else
        printf("PATH is: %s\n", s);
}

Last edited by rtmistler; 07-17-2017 at 01:32 PM.
 
Old 07-17-2017, 02:00 PM   #3
BW-userx
Senior Member
 
Registered: Sep 2013
Location: MID-SOUTH USA
Distribution: Void Linux / Slackware 14.2
Posts: 4,622

Original Poster
Rep: Reputation: 856Reputation: 856Reputation: 856Reputation: 856Reputation: 856Reputation: 856Reputation: 856
Quote:
Originally Posted by rtmistler View Post
Hi,

Use the getenv(3) call.

Some minor issues are that you need to export new environment variables. For instance, $PATH is very common, or shall we say when you enter a new shell, it has an environment and you get that when you run a compiled program from that shell.

But if you do an experiment like type: ABC=123 you can echo $ABC in that shell and see it works, however it won't be seen by a program using getenv() from that shell unless you export the ABC environment variable.

There are also related functions shown in the man page at the bottom.

getenv() should work for you.
Code:
#include <stdio.h>
#include <stdlib.h>

void main()
{
    const char *s = getenv("PATH");

    if (s == NULL)
        printf("Getenv ret NULL\n");
    else
        printf("PATH is: %s\n", s);
}
correct me if I am wrong, but I do not thing that will work.

What I am trying to find or figure out a way to get total count of VDT's and which on I am on or find total current virtual desktops, and then work it into a program I already have to display image to desktop, instead of just root desktop

displayImage->root->vdt[whatever element within total vdts]

like that - though that is the end point concept in C

it is already written in C using x11 and imlib2 I am just wanting to try and expand on what is already there.

Last edited by BW-userx; 07-17-2017 at 02:03 PM.
 
Old 07-17-2017, 02:16 PM   #4
rtmistler
Moderator
 
Registered: Mar 2011
Location: Sutton, MA. USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu
Posts: 5,415
Blog Entries: 12

Rep: Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882
I was thinking it seemed to be an environment variable.

Didn't look at your original link reference.

OK, that's code from someone's project.

You can't call for information from their code, without referencing their code, which you've attempted to do. Where does their code export this function?

I do not see xcb/xcb_ewmh.h in that git repository.
 
Old 07-17-2017, 02:47 PM   #5
BW-userx
Senior Member
 
Registered: Sep 2013
Location: MID-SOUTH USA
Distribution: Void Linux / Slackware 14.2
Posts: 4,622

Original Poster
Rep: Reputation: 856Reputation: 856Reputation: 856Reputation: 856Reputation: 856Reputation: 856Reputation: 856
Quote:
Originally Posted by rtmistler View Post
I was thinking it seemed to be an environment variable.

Didn't look at your original link reference.

OK, that's code from someone's project.

You can't call for information from their code, without referencing their code, which you've attempted to do. Where does their code export this function?

I do not see xcb/xcb_ewmh.h in that git repository.
I just ran
Code:
userx%slackwhere ⚡ ~ ⚡> locate xcb_ewmh.h
/usr/include/xcb/xcb_ewmh.h
userx%slackwhere ⚡ ~ ⚡>
and found it already there on my system. how it go there I have no idea. so I added it

but now I am thinking that came from being in jwm and I can't even remember what lead me to that, but Now I believe I need to stick within x11 https://specifications.freedesktop.o...1.4/index.html

and try and figure out
 
Old 07-17-2017, 05:12 PM   #6
BW-userx
Senior Member
 
Registered: Sep 2013
Location: MID-SOUTH USA
Distribution: Void Linux / Slackware 14.2
Posts: 4,622

Original Poster
Rep: Reputation: 856Reputation: 856Reputation: 856Reputation: 856Reputation: 856Reputation: 856Reputation: 856
with this - test code at the bottom is calling for total desktops,
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char ** argv) {
	
	int i=0;
	
	for (i = 1; i < argc; i++) 
	{
		
		if (strcmp (argv[i], "-alpha") == 0)
			{
				printf("yes i %d\n",i);
			}
		else if (strcmp (argv[i], "-beta") == 0)
			{
				printf("%s and i %d\n",argv[i], i);
			}
		else if (strcmp (argv[i], "-dog") == 0)
		{
			printf("%s i is %d\n", argv[i], i);
			if ((++i) >= argc)
			{
				fprintf (stderr, "Missing color %s i is %d\n", argv[i], i);
				continue;
			} // zero is good anything other than zero is bad
				if (strcmp (argv[i], "poop" ) == 0)
				{
					fprintf (stderr, "i is %d, and you wrote (%s)\n", i, argv[i]);
					continue;
				}
			printf("i %d, %s\n",i, argv[i]);
		}
		else if (strcmp (argv[i], "-good") == 0 )
		{
			((++i));
			if (strcmp (argv[i], "stuff") == 0)
			{
				printf("%s %s\n",argv[i-1],argv[i]);
				continue;
			 }
				
				printf("end of else if\n");
		}
		else if (strcmp (argv[i], "numDis") == 0 )
		{
			printf("in get number desktops\n");
			system("xprop -root  _NET_NUMBER_OF_DESKTOPS");
			
		}
	}
	
	
	
	return 0;
}
get me this
but I just need the int number returned.


Code:
userx%slackwhere ⚡ LearningVDTinC ⚡> ./a.out numDis
in get number desktops
_NET_NUMBER_OF_DESKTOPS(CARDINAL) = 6
 
Old 07-18-2017, 07:20 AM   #7
rtmistler
Moderator
 
Registered: Mar 2011
Location: Sutton, MA. USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu
Posts: 5,415
Blog Entries: 12

Rep: Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882Reputation: 1882
A bit more complicated.

One possible way to do this is to write a script to call your "xprop -root _NET_NUMBER_OF_DESKTOPS", within the script, parse out the number, and then return that number as the script's return value.

What you'd do is fork() a process, exec() this script. And when the script exits, you look at the WIFEXITED() signal to derive the status in your main calling program.

I've done this formerly where I wanted to get the status of a script I ran.

Drawing from a former blog entry of mine, here.

The section titled Creating a Child Process describes the fork() and exec() calls. Just note that a really odd thing I noticed when doing this using a script. If you review it, the exec requires an argument list, but you also give it the application name. Perhaps it was something to do with my paths, however what I found was a script required me to put in the script name in the arg list at position 0 (and you don't need any further args if you construct your script to not require arguments, and then the arg list can terminate with the NULL.) However when you invoke the exec() or one of that family, I found I needed to put in the fully qualified pathname to the script. Must have been the $PATH variable at the time.

The section titled Monitoring Child Processes describes the manners to wait for that child to complete and then check the result.

And you don't have to break it up as I did or be complicated, you can write it all compact:
Code:
#!/bin/sh
# Shell script to extract the number of VIDs - INCOMPLETE AND UNTESTED

#set -xv # for debug if needed

MYSTR=`xprop -root  _NET_NUMBER_OF_DESKTOPS`

RETVAL=`awk '{print $3}'`  # REALLY UNTESTED, I'M NOT AN AWK PERSON ALWAYS LOOK IT UP, BUT YOU NEED THE THIRD FIELD

exit $RETVAL # This returns the number, and you may have to play with it to make it not a string, or maybe the shell will take care of this
Say you call that script, propx.sh, and it is placed in /home/me directory for this example.

Then in your program:
Code:
// Not all inclusive list, just from memory
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>

void myFunction()
{
   pid_t pid;
   int w_status;
   char *args[2] = {
      "propx.sh",
      NULL
   };
   char *newenv[] = { NULL };

   pid = fork();
   if(pid < 0) {
      printf("fork error %d:%s\n", errno, strerror(errno));
      return;
   }
   else if(pid == 0) {
      /* Run script */
      if(execve("/home/me/propx.sh", args, newenv) == -1) {
         printf("Error invoking execve %d:%s\n", errno, strerror(errno));
      }
   }

   waitpid(pid, &w_status, 0);

   if(WIFEXITED(w_status)) {
      printf("Returned value is %d\n", WEXITSTATUS(w_status));
   }
}
Hope it is helpful versus more confusing. And note that it is a potentially messy way to do this. I myself have done this for when I needed something from the shell and knew no better alternative to get it into my program.
 
Old 07-18-2017, 09:46 AM   #8
norobro
Member
 
Registered: Feb 2006
Distribution: Debian Sid
Posts: 647

Rep: Reputation: 249Reputation: 249Reputation: 249
Quote:
Originally Posted by BW-userx View Post
... but Now I believe I need to stick within x11
Yep. Try this:
Code:
// gcc main.c -o filename -lX11

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <stdio.h>

int main() {
    Atom actual_type;
    int actual_format;
    unsigned long nitems, bytes_after;
    unsigned char *prop_return;
    Display *display = XOpenDisplay(NULL);
    Atom number_desktops = XInternAtom(display, "_NET_NUMBER_OF_DESKTOPS", False);
    Window root= DefaultRootWindow(display);
    if(XGetWindowProperty(display, root, number_desktops, 0, 1,False,
              XA_CARDINAL, &actual_type, &actual_format, &nitems, &bytes_after,
              &prop_return) == Success)
    {
        unsigned int num = *((int*)prop_return);
        printf("Number of desktops: %d\n",num);
        XFree(prop_return);
    }
    Atom current_desktop = XInternAtom(display, "_NET_CURRENT_DESKTOP", False);
    if(XGetWindowProperty(display, root, current_desktop, 0, 1,False,
              XA_CARDINAL, &actual_type, &actual_format, &nitems, &bytes_after,
              &prop_return) == Success)
    {
        unsigned int num = *((int*)prop_return);
        printf("Current desktop: %d\n",num);
        XFree(prop_return);
    }
    XCloseDisplay(display);
    return 0;
}
Output:
Code:
Number of desktops: 4
Current desktop: 2

Last edited by norobro; 07-18-2017 at 09:48 AM. Reason: Forgot output
 
1 members found this post helpful.
Old 07-18-2017, 11:16 AM   #9
BW-userx
Senior Member
 
Registered: Sep 2013
Location: MID-SOUTH USA
Distribution: Void Linux / Slackware 14.2
Posts: 4,622

Original Poster
Rep: Reputation: 856Reputation: 856Reputation: 856Reputation: 856Reputation: 856Reputation: 856Reputation: 856
Quote:
Originally Posted by norobro View Post
Yep. Try this:
Code:
// gcc main.c -o filename -lX11

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <stdio.h>

int main() {
    Atom actual_type;
    int actual_format;
    unsigned long nitems, bytes_after;
    unsigned char *prop_return;
    Display *display = XOpenDisplay(NULL);
    Atom number_desktops = XInternAtom(display, "_NET_NUMBER_OF_DESKTOPS", False);
    Window root= DefaultRootWindow(display);
    if(XGetWindowProperty(display, root, number_desktops, 0, 1,False,
              XA_CARDINAL, &actual_type, &actual_format, &nitems, &bytes_after,
              &prop_return) == Success)
    {
        unsigned int num = *((int*)prop_return);
        printf("Number of desktops: %d\n",num);
        XFree(prop_return);
    }
    Atom current_desktop = XInternAtom(display, "_NET_CURRENT_DESKTOP", False);
    if(XGetWindowProperty(display, root, current_desktop, 0, 1,False,
              XA_CARDINAL, &actual_type, &actual_format, &nitems, &bytes_after,
              &prop_return) == Success)
    {
        unsigned int num = *((int*)prop_return);
        printf("Current desktop: %d\n",num);
        XFree(prop_return);
    }
    XCloseDisplay(display);
    return 0;
}
Output:
Code:
Number of desktops: 4
Current desktop: 2
yeeeeaaaaaahhhhhh so where did you gets this information?
my fingers are almost bleeding from googling just about if not every key word and phrase I could think of to pull something like that up even remotely close to it.

now I am going to copy that and see what I it does and what I can make that do for me.

thanks ...

back: results:
Code:
userx%slackwhere š LearningVDTinC š> gcc finddesktopcount.c -lX11
userx%slackwhere š LearningVDTinC š> ./a.out
Number of desktops: 6
Current desktop: 1
now its time to read it and figure it out then play with it to see if I can incorporate it into my existing code .. thanks again !!!

Last edited by BW-userx; 07-18-2017 at 11:24 AM.
 
Old 07-18-2017, 11:17 AM   #10
BW-userx
Senior Member
 
Registered: Sep 2013
Location: MID-SOUTH USA
Distribution: Void Linux / Slackware 14.2
Posts: 4,622

Original Poster
Rep: Reputation: 856Reputation: 856Reputation: 856Reputation: 856Reputation: 856Reputation: 856Reputation: 856
Quote:
Originally Posted by rtmistler View Post
A bit more complicated.

One possible way to do this is to write a script to call your "xprop -root _NET_NUMBER_OF_DESKTOPS", within the script, parse out the number, and then return that number as the script's return value.

What you'd do is fork() a process, exec() this script. And when the script exits, you look at the WIFEXITED() signal to derive the status in your main calling program.

I've done this formerly where I wanted to get the status of a script I ran.

Drawing from a former blog entry of mine, here.

The section titled Creating a Child Process describes the fork() and exec() calls. Just note that a really odd thing I noticed when doing this using a script. If you review it, the exec requires an argument list, but you also give it the application name. Perhaps it was something to do with my paths, however what I found was a script required me to put in the script name in the arg list at position 0 (and you don't need any further args if you construct your script to not require arguments, and then the arg list can terminate with the NULL.) However when you invoke the exec() or one of that family, I found I needed to put in the fully qualified pathname to the script. Must have been the $PATH variable at the time.

The section titled Monitoring Child Processes describes the manners to wait for that child to complete and then check the result.

And you don't have to break it up as I did or be complicated, you can write it all compact:
Code:
#!/bin/sh
# Shell script to extract the number of VIDs - INCOMPLETE AND UNTESTED

#set -xv # for debug if needed

MYSTR=`xprop -root  _NET_NUMBER_OF_DESKTOPS`

RETVAL=`awk '{print $3}'`  # REALLY UNTESTED, I'M NOT AN AWK PERSON ALWAYS LOOK IT UP, BUT YOU NEED THE THIRD FIELD

exit $RETVAL # This returns the number, and you may have to play with it to make it not a string, or maybe the shell will take care of this
Say you call that script, propx.sh, and it is placed in /home/me directory for this example.

Then in your program:
Code:
// Not all inclusive list, just from memory
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>

void myFunction()
{
   pid_t pid;
   int w_status;
   char *args[2] = {
      "propx.sh",
      NULL
   };
   char *newenv[] = { NULL };

   pid = fork();
   if(pid < 0) {
      printf("fork error %d:%s\n", errno, strerror(errno));
      return;
   }
   else if(pid == 0) {
      /* Run script */
      if(execve("/home/me/propx.sh", args, newenv) == -1) {
         printf("Error invoking execve %d:%s\n", errno, strerror(errno));
      }
   }

   waitpid(pid, &w_status, 0);

   if(WIFEXITED(w_status)) {
      printf("Returned value is %d\n", WEXITSTATUS(w_status));
   }
}
Hope it is helpful versus more confusing. And note that it is a potentially messy way to do this. I myself have done this for when I needed something from the shell and knew no better alternative to get it into my program.
NO bash script or script of any kind - wanting to find C code to get this information that it looks like @norobro may have given it to me.
 
Old 07-18-2017, 11:57 AM   #11
norobro
Member
 
Registered: Feb 2006
Distribution: Debian Sid
Posts: 647

Rep: Reputation: 249Reputation: 249Reputation: 249
You're welcome.

Quote:
Originally Posted by BW-userx View Post
yeeeeaaaaaahhhhhh so where did you gets this information?
A while back I had to do some Xlib programming and had the same experience as you: lots of searching and few answers resulting in a lot of coding trial and error.

This is the best reference that I found: https://tronche.com/gui/x/

Last edited by norobro; 07-18-2017 at 12:15 PM. Reason: changed link to up one directory
 
1 members found this post helpful.
Old 07-18-2017, 12:30 PM   #12
BW-userx
Senior Member
 
Registered: Sep 2013
Location: MID-SOUTH USA
Distribution: Void Linux / Slackware 14.2
Posts: 4,622

Original Poster
Rep: Reputation: 856Reputation: 856Reputation: 856Reputation: 856Reputation: 856Reputation: 856Reputation: 856
Quote:
Originally Posted by norobro View Post
You're welcome.

A while back I had to do some Xlib programming and had the same experience as you: lots of searching and few answers resulting in a lot of coding trial and error.

This is the best reference that I found: https://tronche.com/gui/x/
BOOKMARKED - I'm sure that is going to come in handy.
Thanks!
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_allo mohammad taqy bayat Programming 1 11-17-2014 01:37 AM
printf vs std::cout and std::ofstream grob115 Programming 2 01-16-2013 11:49 AM
Perl: suppress std output and std error say_hi_ravi Programming 1 11-01-2012 06:22 AM
Template algorithm for std::vector and std::string CartmanYO Programming 4 09-08-2010 09:56 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:30 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration