I am looking for a way to change the keyboard layout from within my Qt application. The application will run on a Linux kernel that doesn't support keyboard layout files, so Qt has to do everything concerning the mapping of the keyboard input.
In case of Qt for Embedded Linux I have found a good-looking solution here:
Qt Embedded for Linux. Keyboard layout switching
But unfortunately the QKbdDriverFactory class is not available for any other Qt versions, according to the documentation here: http://qt-project.org/doc/qt-4.8/qkbddriverfactory.html
I tried including it anyway (and astonishingly the class was there), but the compiler throws "undefined reference" errors whenever I invoke the create function.
Do I have to manually program huge QMap objects? Please tell me that there's a less tedious way. I don't want to believe that the qmap files can't be used outside of Qt for embedded Linux, because why would the kmap2qmap converter be available in practically any SDK if it's useless most of the time?
Alex
edit: Additional information:
I am using Qt 4.7.4 (32 Bit) and QtCreator 2.4.1.
I work on Ubuntu 12.04, 64 Bit on a Virtual Machine.
The target system is a hardware with a specialized minimal Linux kernel, so trying to use Qt Embedded would be very difficult.
There is no Xcb server, no frame buffer plugin (edit2: But we do use a frame buffer) and I couldn't find out what DE or eglfs means.
Seems like you should implement your own keyboard support layer.
You don't have dumpkeys program, so you can't generate keymap files on device. Use desktop version.
Keycodes generated on desktop PC might be different from keycode generated by your device, so you should adapt them.
After adapting keymap files you can write code to read these files.
Having a map of KEY_CODE=>UTF8_CHARACTER you can intercept key events and translate them to input symbols, according to currently used keymap.
Related
I have two monitors, each connected to a different GPU. Both GPUs are in a single machine, and I want to run a single application. I have two independent views, and I would like to render each one using a GPU/Monitor set. I can create multiple surfaces and devices, but I want to ensure I associate each surface with the GPU its monitor is plugged into, otherwise I suspect I'll suffer performance issues as the frame buffers need to be copied back and forth between cards.
I'm using fullscreen surfaces, and I was thinking this was something vkGetPhysicalDeviceSurfaceSupportKHR would tell me. However, both VkSurfaceKHR appear to be valid targets for each VkPhysicalDevice so I guess this is something the OS and GPU Driver can handle, but is there any hint about which surface is optimal to associate with a device?
From what I can tell the extension VK_KHR_display is one way of doing this, but it's not available on my Windows 10 machine or Nvidia GPU. It seems to be intended for embedded platforms only. However it lets you list attached displays for each device which is pretty much what I'm looking for: https://vulkan.lunarg.com/doc/view/1.0.30.0/linux/vkspec.chunked/ch29s03.html
This quote from the docs makes me belive this may not be supported on Windows:
Issues
1) Does Win32 need a way to query for compatibility between a particular physical device and a specific screen? Compatibility between a physical device and a window generally only depends on what screen the window is on. However, there is not an obvious way to identify a screen without already having a window on the screen.
RESOLVED: No. While it may be useful, there is not a clear way to do this on Win32. However, a method was added to query support for presenting to the windows desktop as a whole.
However, I'm still interested in hearing if there's a work around to achieve a similar effect.
Finally figured out a work around for this:
Direct X actually supports this through use of the IDXGIAdapter::EnumOutputs function. This lets you list the monitors connected to each GPU. Then using these two extensions you can remap this information to Vulkan:
VK_KHR_external_memory_capabilities
VK_KHR_get_physical_device_properties2
You can use these to get the deviceLUID from VkPhysicalDeviceIDPropertiesKHR.
This can then be compared with the Luid from this structure in Direct X DXGI_ADAPTER_DESC
You can also use glfwGetWin32Window to get the HWND of the monitor. This lets you associate a vulkan surface with a direct x monitor.
You now have all the information you need to accociate vulkan surfaces with the devices they're actually connected to.
At least in my application, setting this up correctly results in a significant difference in performance.
This would all be way simpler (and cross platform) if Windows would just support the VK_KHR_display and VK_KHR_display_swapchain extensions as Linux does.
There are two extensions that are useful for such things: the one mentioned by You, VK_KHR_display and the second called VK_KHR_display_swapchain which allows You to create a swapchain directly on a device’s display without any underlying window system.
But these extensions are rarely supported on Windows. In core Vulkan API there is no way to achieve what You want. And I'm afraid You need to use OS-specific functions (You need to rely on the WinAPI functions in this situation).
[EDIT]
Did You saw this question? How can you get the display adapter used for a particular monitor in Windows? If not, maybe it will help You start with Your research.
As you already discovered, on Win32 you need to use the OS windowing system to pick the display you want to use, using the Window API. It can be straight forward.
BUT if you intend to make simple and agnostic OS code, check GLFW project. It has high level functions to handle windows on all major OSs.
Check :
GLFW monitor Guide
GLFW Vulkan integration
GLFW on its own words:
GLFW is a free, Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan application development. It provides a simple, platform-independent API for creating windows, contexts and surfaces, reading input, handling events, etc.
I want to create a framework for automated rendering tests for video games.
I want to test an application that normally renders to a window with OpenGL. Instead, I want it to render into image files for further evaluation. I want to do this on a Linux server with no GPU.
How can I do this with minimal impact on the evaluated application?
Some remarks for clarity:
The OpenGL version is 2.1, so software rendering with Mesa should be possible.
Preferably, I don't want to change any of the application code. If there is a solution that allows me to emulate a X server or something like that, I would prefer it.
I don't want to change any of the rendering code. If it is really necessary, I can change the way I initialize OpenGL, but after that, I want to execute arbitrary OpenGL code.
Ideally, your answer would explain how to set up an environment on a headless Linux server that allows me to start arbitrary OpenGL binaries and render its output into images. If that's not possible, I am open for any suggestions.
Use Xvfb for your X server. The installation of Mesa deployed on any modern Linux distribution should automatically fall back to software rasterization if no supported GPU is found. You can take screenshots with any X11 screen grabber program; heck even ffmpeg -i x11grab will work.
fbdev/miniglx might be something that you are looking for. http://www.mesa3d.org/fbdev-dri.html I haven't used it so I have no idea if it works for your purpose or not.
Alternative is to just start and xserver without any desktop environment with xinit. That setup is using well tested code paths making it better suited for running your test. miniglx might have bugs which none has noticed because it isn't used everyday.
To capture the rendering output to images could be done with LD_PRELOAD trick to wrap glXSwapBuffers. Basic idea is to add your own swapbuffers function in between your application and gl library where you can use glReadPixels to download rendered frame and then use your favorite image library to write that data to image/video files. After the glReadPixels has completed you can call to library glXSwapBuffers to make swap happen like it would happen in real desktop.
The prog subdirectory has been removed from main git repository and you can find it from git://anongit.freedesktop.org/git/mesa/demos instead.
I need to build a command line tool, that will take a 3D model as an argument, and will output photos of it, that may or may not be processed by this application. The tool will be deployed on Linux, but I want to make it as cross-platform as possible.
The program is not supposed to present a window of any kind, or accept any other input apart from the command line arguments.
I was wondering, how would someone approach this? I am currently able to display the 3D model on-screen with the help of GLFW, which actually drives my event handlers to peripheral input, and also my main loop. However, I don't know if using GLFW will help me if I want to make a command-line program with input-output as files.
Does anyone have any indications as to how to approach this?
create invisible/hidden window,
use its gl context to render to FBO and
use readpixels to save that to file
For OpenGL to work you need an OpenGL context. Which used to require some kind of windowing system active, that could produce you some drawable for which the context could be created.
Some OpenGL implementations, like Mesa, actually allow you to create an OpenGL context for drawables that are created without a windowing system; Mesa calls this "off-screen mesa". With Gallium3D drivers on Linux this even may give you GPU acceleration. But usually you end up in the "softpipe" software rasterizer.
Does anyone have any indications as to how to approach this?
Don't use OpenGL for it. OpenGL is mostly meant for creating interactive graphics; but of course if your goal is visualization of complex data, then a GPU would be better suited.
With NVidia hardware you'll need to use an X server for that; the X server must be running and active on the console for this to work. AMD hardware with the open source drivers and Mesa may give you off-screen capabilities without X (but I never tried that).
On Windows Server you don't have proper OpenGL support anyway (just v1.4 and very slow), so don't bother with it.
Can you provide me a surface level knowledge about this.
How can I use linux's latest kernel and X windows GUI to create my own Embedded OS interface?
If you want to learn to make your own distribution, look at linux from scratch. A pre-existing embedded distribution may be more what you are looking for. Some are uclinux-dist, openembedded, poky, ltib, buildroot.
When you say "small" what do you mean by small? Small means reduced functionality.
The smallest is writing your own code that writes to the frame buffer. Your GUI may look like space invaders.
Bigger would be to use a direct to framebuffer toolkit like Nano-X
Bigger again is DirectFB.
Bigger again is a high level toolkit
(GTK or Qt) on top of DirectFB
And the biggest is X with a window
manager and high level toolkit.
Having "learned" already, I would use whatever comes with the platform you are developing on.
End Dump.
First suggestion, code HTML and use a browser. All of the heavy lifting will be done for you. More to the point, most embedded OSen do not live on systems with keyboards, video, and mice. Exporting everything to a remote web client though a web server is the standard way of doing things.
Second suggestion, use a high level toolkit, like Qt, KDE, or Gnome. Coding in low level X is painful.
I'd like to open an OpenGL context without X in Linux. Is there any way at all to do it?
I know it's possible for integrated Intel graphics card hardware, though most people have Nvidia cards in their system. I'd like to get a solution that works with Nvidia cards.
If there's no other way than through integrated Intel hardware, I guess it'd be okay to know how it's done with those.
X11 protocol itself is too large and complex. Mouse/Keyboard/Tablet input multiplexing it provides is too watered-down for modern programs. I think it's the worst roadblock that prevents Linux desktop from improving, which is why I look for alternatives.
Update (Sep. 17, 2017):
NVIDIA recently published an article detailing how to use OpenGL on headless systems, which is a very similar use case as the question describes.
In summary:
Link to libOpenGL.so and libEGL.so instead of libGL.so. (Your linker options should therefore be -lOpenGL -lEGL
Call eglGetDisplay, then eglInitialize to initialize EGL.
Call eglChooseConfig with the config attribute EGL_SURFACE_TYPE followed with EGL_PBUFFER_BIT.
Call eglCreatePbufferSurface, then eglBindApi(EGL_OPENGL_API);, then eglCreateContext and eglMakeCurrent.
From that point on, do your OpenGL rendering as usual, and you can blit your pixel buffer surface wherever you like. This supplementary article from NVIDIA includes a basic example and an example for multiple GPUs. The PBuffer surface can also be replaced with a window surface or pixmap surface, according to the application needs.
I regret not doing more research on this on my previous edit, but oh well. Better answers are better answers.
Since my answer in 2010, there have been a number of major shakeups in the Linux graphics space. So, an updated answer:
Today, nouveau and the other DRI drivers have matured to the point where OpenGL software is stable and performs reasonably well in general. With the introduction of the EGL API in Mesa, it's now possible to write OpenGL and OpenGL ES applications on even Linux desktops.
You can write your application to target EGL, and it can be run without the presence of a window manager or even a compositor. To do so, you would call eglGetDisplay, eglInitialize, and ultimately eglCreateContext and eglMakeCurrent, instead of the usual glx calls to do the same.
I do not know the specific code path for working without a display server, but EGL accepts both X11 displays and Wayland displays, and I do know it is possible for EGL to operate without one. You can create GL ES 1.1, ES 2.0, ES 3.0 (if you have Mesa 9.1 or later), and OpenGL 3.1 (Mesa 9.0 or later) contexts. Mesa has not (as of Sep. 2013) yet implemented OpenGL 3.2 Core.
Notably, on the Raspberry Pi and on Android, EGL and GL ES 2.0 (1.1 on Android < 3.0) are supported by default. On the Raspberry Pi, I don't think Wayland yet works (as of Sep. 2013), but you do get EGL without a display server using the included binary drivers. Your EGL code should also be portable (with minimal modification) to iOS, if that interests you.
Below is the outdated, previously accepted post:
I'd like to open an OpenGL context without X in linux. Is there any way at all to do it?
I believe Mesa provides a framebuffer target. If it provides any hardware acceleration at all, it will only be with hardware for which there are open source drivers that have been adapted to support such a use.
Gallium3D is also immature, and support for this isn't even on the roadmap, as far as I know.
I'd like to get a solution that works with nvidia cards.
There isn't one. Period.
NVIDIA only provides an X driver, and the Nouveau project is still immature, and doesn't support the kind of use that you're looking for, as they are currently focused only on the X11 driver.
You might be interested in a project called Wayland
http://en.wikipedia.org/wiki/Wayland_%28display_server%29
Have you looked at this page?
http://virtuousgeek.org/blog/index.php/jbarnes/2011/10/31/writing_stanalone_programs_with_egl_and_
It is likely a bit outdated. I haven't tried yet, but I would appreciate more documentation of this type.
Probably a good idea, as of today, is to follow Wayland compositor-drm.c implementation:
http://cgit.freedesktop.org/wayland/weston/tree/src/compositor-drm.c
https://gitlab.freedesktop.org/mesa/kmscube/ is a good a reference implementation of OGL (or OGLES) hardware-accelerated rendering without an X11 or wayland dependency.
You can look at how Android has solved this issues. See Android-x86 project.
Android uses mesa with egl and opengles. Android has its own simple Gralloc component for mode setting and graphic allocations. On top of that they have SurfaceFlinger component which is a composition engine, which uses OpenGLES for acceleration.
Cannot see why couldn't you use these components in similar way and even reuse the Android glue code.