get xorg.conf serverLayout with c++ - c++

I am currently working on a multi window application that spans over multiple screens. The software is written with xlib and runs on ubuntu 10.10, gnome desktop.
To get the position of every window I'd like to access the /etc/X11/xorg.conf file, expecially the section SeverLayout. It looks somehow like this:
Section "ServerLayout"
Identifier "aticonfig Layout"
Screen "screen0" 0 0
Screen "screen1" 1920 0
Screen "screen2" 3840 0
Screen "screen3" 5760 0
EndSection
I'd like to get the X values of each screen (0, 1920, ... ) Does xlib somehow provide access to this information?
thanks

Information about layout of multiple monitors in X, especially when they're combined into a single logical screen, is available via the libXrandr and libXinerama API's. Unfortunately, the multi-screen API's added to libXrandr in version 1.2 aren't covered in the man page, but require looking at the extension spec and Xrandr.h header file.

You can use XWidthOfScreen and XHeightOfScreen functions.
Use XScreenCount (to get number of screens) and XScreenOfDisplay to get appropriate screen structure.
A better way is to get the root window of a screen and parse it's geometry using XParseGeometry function.

Related

Font Rendering difference in windows and Linux, Qt Cpp

I have,
QFontMetrics m_fm(QFont("Arial",14)); and
m_fm.width("Existing LAN IP Address from Project Network");
returns '297' (on windows)
can anyone tell me what it returns on linux compiler?
and if its different on linux then why so?
and how can we have same font rendering on windows as well as in linux.
Update:
I have a QTableView cell , in which I am writing data from multiple strings collectively, I have to show data in 2 Lines in single row. (using .append("\n")).
Lets say column width is 140,
so I need data to fit in 140 pixels of the cell for one line
Therefore , i need to have data whose pixel width is less than 140, so that it can be shown properly. in such case, depending on font(Arial) I am computing m_fm.width("Existing LAN IP Address from Project Network"); but it differs in Linux, as windows Arial font is not available. By any chance can I get proper pixel width , without installing Arial font in Linux system ?
Thanks in Advance !
Try to load font on main.cpp QFontDatabase. Maybe You havent got the same font. Add font to resource file. Check DPI on screen or enable High antyaliasing on start app.

C++ - How to screen-capture, except for some windows

Situation: I have a software that performs screen sharing over the Internet, where one user acts as a presenter, and other users act as viewers/attendees.
Besides the presentation windows, the presenter also has a set of NON-SHARING-WINDOWS that appear on the screen (a button bar for start sharing/stop sharing/etc., a Skype window etc.).
The presenter can configure from the setup of the screen sharing software to make these NON-SHARING-WINDOWS invisible (i.e. they will not appear in the screen sharing that is being sent to the attendees, but the window content behind them will appear in the screenshot).
The screenshots are sent at approximately 10 frames-per-second, or faster.
Question: how can I programmatically capture the screen, except for these NON-SHARING-WINDOWS windows?
Notes:
Because of the higher frames-per-second value, I cannot minimize/maximize/set alpha for these windows, because then the windows will flicker. The application is written in Win32 C++.
I would use layered windows, but because of the Windows 7 Desktop Composition feature, this is not usable out-of-the-box (and in Windows 8, you cannot use DwmEnableComposition anymore to temporarily and programmatically disable composition)
I could use the layered window approach for Windows XP/2000/7 etc., and a different approach for Windows 8 (if there is one), though I would prefer a single process that works on all systems
I could also try to "compose" the screenshots by capturing individual images (of the desktop, the windows that need to be captured) and using their z-index to create the final image, but because of the required frames-per-second value, this process would be too slow.
In windows even the desktop is considered a window and has its own HWND.
It seems however, not easily possible to only copy the "wallpaper" on its own.
So i basically see two ways to do that.
1. Copy the entire desktop e.g. BitBlt(GetWindowDC(GetDesktopWindow()),...)
OR
Use GetWindow and traverse the window list in backward direction starting from the Desktop-Window whose HWND you just can determine with GetDesktopWindow(), Like this:
// paint on a black DC
hwnd=GetDesktopWindow()
while (hwnd = GetWindow(hwnd, GW_HWNDPREV))
{
// is this window not shared? continue
// else bitblt it into our dc
}
Hope i gave some inspiration :-)
If someone knows a way how to copy ONLY the desktop without its child windows please let me know.
You can use Magnifier API.
There is a function in magnifier API that allows you to exclude specific windows from your target window (your window with 1x magnification where magnifier renders).
You can set this window to full screen and make it transparent and then use PrintWindow function.
The function: https://learn.microsoft.com/en-us/windows/desktop/api/magnification/nf-magnification-magsetwindowfilterlist
Sample projects:
https://www.codeproject.com/Articles/607288/Screenshot-using-the-Magnification-library
https://code.msdn.microsoft.com/windowsdesktop/Magnification-API-Sample-14269fd2
I'm aware this question is pretty old, but I ran into the same problem and it was very, very hard to find any information at all regarding this.
Since Windows 10 version 2004 (build 10.0.19041), the SetWindowDisplayAffinity API has been expanded to include a flag called WDA_EXCLUDEFROMCAPTURE (0x00000011). This will remove the window from images captured with BitBlt
The window is displayed only on a monitor. Everywhere else, the window does not appear at all.
One use for this affinity is for windows that show video recording controls, so that the controls are not included in the capture.
Introduced in Windows 10 Version 2004. See remarks about compatibility regarding previous versions of Windows.
For versions before 2004, it will use the existing WDA_MONITOR flag.
I have tested this with a screen capture of the desktop and I am unsure what would happen if you were to use a window DC.
So I guess a possible solution would be:
// get window handle
hWnd = (...)
BOOL result = SetWindowDisplayAffinity(m_hWnd, WDA_EXCLUDEFROMCAPTURE);
// do bitblt stuff
mabye you can use Magnification API, even Microsoft said The MagImageScalingCallback function is deprecated in Windows 7 and later, and should not be used in new applications. There is no alternate functionality., but it still work on Windows 10;
Here is the overview of this API : https://learn.microsoft.com/en-us/previous-versions/windows/desktop/magapi/magapi-intro
The sample code of Microsoft is here : https://github.com/microsoft/Windows-classic-samples/tree/main/Samples/Magnification
If you want to get the screenshot rgb data, you can use this api MagSetImageScalingCallback to set callback of Magnifier window, every time you use MagSetWindowSource or InvalidRect of magnifer window, this callback function MagImageScalingCallback will be called, so you can get screenshot rgb data here.
I think that to limit the capture content within a big window will be more simple. otherwise you will need to cut some windows from the screen capture.

Creating a program that creates a full screen overlay

I want to write a program that would create a transparent overlay filling the entire screen in Windows 7, preferably with C++ and OpenGL. Though, if there is an API written in another language that makes this super easy, I would be more than willing to use that too. In general, I assume I would have to be able to read the pixels that are already on the screen somehow.
Using the same method screen capture software uses to get the pixels from the screen and then redrawing them would work initially, but the problem would then be if the screen updates. My program would then have to minimize/close and reappear in order for me to be able to read the underlying pixels.
Windows Vista introduced a new flag into the PIXELFORMATDESCRIPTOR: PFD_SUPPORT_COMPOSITION. If the OpenGL context is created with an alpha channel, i.e. AlphaBits of the PFD is nonzero, the alpha channel of the OpenGL framebuffer is respected by the Windows compositor.
Then by creating a full screen, borderless, undecorated window you get this exakt kind of overlay you desire. However this window will still receive all input events, so you'll have to do some grunt work and pass on all input events to the underlying windows manually.

Is it possible to modify the origin of a display? (win32)

I have a number of applications which I cannot modify(no source), they are hard coded to draw at 0,0. Normally this is not a problem however a new project(kiosk) has come along where I need to draw a boarder around the outside of these applications. I am looking for a way to change display range from:
X: 0 to 1200
Y: 0 to 900
to something like:
X: -100 to 1100
Y: -100 to 800
I've seen a couple functions on MSDN like SetViewportExtEx, SetWorldTransform which fit the need however if I understand them correctly they don't do a system wide change. They are for the current process only.
I am programming in C++ but if there are settings in the registry/control panel/etc that would also work.
Has anyone else done anything like this before?
Edit 1: Window position is hard coded to 0,0
This might be overkill, but if it's something you really want to have complete control over, you could always use API hooking to intercept the Window creation by hooking CreateWindow, CreateWindowEx in the target process and altering the X Y coordinates before passing control back to the system.
Popular API hooking libraries include: Microsoft Detours, Madshi's madCodeHook, and the free, open source EasyHook.
Could you clarify what you mean by 'the applications are hard coded to draw at 0,0'? Does this mean that the position of their windows is set to 0,0, or do they have code to paint at 0,0?
Solution #1
One possible solution would be to use SetWindowPosition to simply move each of the applications to whatever position you desire.
All you would need to do is enumerate the list of HWNDS calling SetWindowPosition on each as necessary.
Solution #2
Set the working area of the desktop to be smaller. This should cause your applications to take up the working area, not the entire screen. You would then be free to put up any additional windows you need, manually position them, and draw your border.
In fact you might consider registering your border windows as 'app bars' which would automatically resize the working area.
The route I might take is making a shell application with a window and then setting the parent of the other using "SetParent"
for instance, in C# I did this...
var info = new ProcessStartInfo {FileName = "NotePad.exe", WindowStyle = ProcessWindowStyle.Normal};
var runProcess = Process.Start(info);
Thread.Sleep(1000); // ugly, but more just proving a point
SetParent(runProcess.MainWindowHandle, Handle);
and it hosted notepad in my forms window
So, Simply host the window, resize your host to the clients size + a bit, position the client in your host window where you want, and then draw around the outside.
easy peasy :)

Displaying graphics on top of another full screen application; hardware overlay?

On Windows (Vista32), I want to display some simple graphics on top of a fullscreen flash window (an overlay of useful information while using the flash application). What's the fastest way to accomplish it?
I think I may be able to achieve it using DirectX with the DDSCAPS_OVERLAY flag but with the only example I've found I get an exception:
E_NOTIMPL
The function called is not supported at this time
on
m_direct_draw->CreateSurface(&ddsd, &m_overlay_surface, 0)
(full code here: http://nexe.gamedev.net/files/Overlay-2005-11-21.zip)
Something relevant to C/++ or Python would help me. I'm using the latest DirectX SDK.
Thank you
Just create a Layered Window and draw to it with an alpha channel - in WPF, this is as easy as setting the AllowsTransparency bit on the Window
While the transparent layered window is useful, it doesn't appear on top of the fullscreen flash with WS_EX_TOPMOST set.
Note sure how to reply to Paul sadly.
Overlaying on a 3D fullscreen application is very relevant but while it works and flash appears to load dx9, it doesn't show on flash.