Get screen size

Archives Forums/Linux Discussion/Get screen size

Jur(Posted 2009) [#1]
I would like to get the size of desktop. I found some information here: http://www.opengl.org/wiki/Programming_OpenGL_in_Linux:_Changing_the_Screen_Resolution

From that info I prepared the following code:



But I get a bunch of "undefined reference" errors. Has anybody has a clue what could be wrong or has a working solution for obtaining screen size in Linux?


dawlane(Posted 2009) [#2]
Are all the necessary development libraries installed? And are you linking to them?
For Ubuntu you would need libxrandr-dev,libxrender1-dev,libext-dev,libx11-dev and libc6-dev


xlsior(Posted 2009) [#3]
the Chaos.desktopext module will return information like the width, height, depth and refresh rate of your primary screen under Windows, Linux and Mac... (On windows it can also do additional screens)

http://www.chaos-interactive.de/en/desktopextension/


Jur(Posted 2009) [#4]
dawlane,
I have Ubuntu 9.04 and all libraries are installed except libext.dev which is not listed in the package manager. I think that all needed libraries are in place, because I can build this program ( http://www.opengl.org/wiki/Programming_OpenGL_in_Linux:_Changing_the_Screen_Resolution ) with cpp. It seems that blitzmax manage to compile my code, but "undefined reference" errors appear in the linking phase.

xlsior,
That is a nice module, but linux is not (no longer?) supported.


dawlane(Posted 2009) [#5]
oops the should have been libxext-dev: libxrandr-dev should automatically install it as its a dependency.
Whats the "undefined reference" error you keep getting?
I can get the code that you linked to from the wikki working but theres a big bug in the code, so it will get the screen size but wont change the the resolution (it crashes)


Jur(Posted 2009) [#6]
Yes, the code from that link doesnt work, but I need only screen size information.
Well, maybe I am doing a stupid mistake because I dont know much about c++ and linux. Can you see anything problematic in my code?

This is my testing blitzmax code:


Imported "ext_func.cpp":



And here is the Blitzmax output:

Building test
Compiling:test.bmx
flat assembler version 1.67.36 (32768 kilobytes memory)
3 passes, 3023 bytes.
Linking:test.debug
/home/jure/misc/.bmx/ext_func.cpp.debug.linux.x86.o: In function `GetScreenSize(int&, int&)':
ext_func.cpp:(.text+0x26): undefined reference to `XRRSizes'
ext_func.cpp:(.text+0x31): undefined reference to `XRRGetScreenInfo'
ext_func.cpp:(.text+0x3b): undefined reference to `XRRConfigCurrentRate'
ext_func.cpp:(.text+0x47): undefined reference to `XRRConfigCurrentConfiguration'
/home/jure/misc/.bmx/test.bmx.gui.debug.linux.x86.o: In function `_bb_main':
(code+0x118): undefined reference to `GetScreenSize'
collect2: ld returned 1 exit status
Build Error: Failed to link /home/jure/misc/test.debug
Process complete


dawlane(Posted 2009) [#7]
To solve your link problem for the Xrandr stuff just add to your blitzmax file at the top.
import "-lXrandr"

Not sure why the GetScreenSize function is causing problems.


dawlane(Posted 2009) [#8]
Problem solved. As it was late at night so I did it this morning.

The bmx file

SuperStrict

Import "-lXrandr"       'let the linker know it needs to include libXrandr
Import "ext_func.cpp"

'The function is an int so it can return a int value back to the calling code. 
'This can be used to see if the function was successful.
'As C/C++ is a strong "typed" language make sure that a function passes that data type.

Extern
	Function GetScreenSize:Int(width:Int Var,height:Int Var) 
End Extern

Local width:Int
Local height:Int

Local error:Int = GetScreenSize(width, height)

Print "width:"+ width
Print "height:"+ height
Print "exit code:"+ error


The C++ file
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<X11/Xlib.h>
#include<X11/extensions/Xrandr.h>

extern "C" int GetScreenSize(int&,int&);  // Makes the function visable to other files

int GetScreenSize(int& width, int& height)
{

 		int num_sizes;
 		Rotation original_rotation;

 		Display *dpy = XOpenDisplay(NULL);
 		Window root = RootWindow(dpy, 0);
 		XRRScreenSize *xrrs = XRRSizes(dpy, 0, &num_sizes);
 		//
 		//     GET CURRENT RESOLUTION AND FREQUENCY
 		//
 		XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
 		short original_rate = XRRConfigCurrentRate(conf);
 		SizeID original_size_id = XRRConfigCurrentConfiguration(conf, &original_rotation);

  		width = xrrs[original_size_id].width;
  		height = xrrs[original_size_id].height;
 
 		XCloseDisplay(dpy);
		return 0;    //Return a value that can be used for error checking. 
	}




Jur(Posted 2009) [#9]
Thanks a lot! I believe this code should work also on other linux distross beside Ubuntu. If somebody would like to test it without engaging Blitzmax, here is a small application, which shows the desktop size.


dawlane(Posted 2009) [#10]
Your welcome. As long as libXrandr and its dependencies are installed on the target distro then it will work. Dont know about dual monitors though.