Multi & LinuxFb display drivers: Changing frame buffer resolutions at run-time
-
I've seen some unanswered questions similar to this on the net...hoping I can get some insight here.
I'm currently using the Multi display driver with a few LinuxFb's, and need to be able to allow an application user to change the display resolution between a couple different presets. All of the Multi's LinuxFb's will have the same resolution. I assume (1) is the right way to go, but would like to understand why I can't get away with (2).
(1) Is this possible with the current LinuxFb implementation, or will I need to write a custom display driver?
I was hoping that I might be able to subclass the existing LinuxFb implementation, sneak in the FBIOPUT_VSCREENINFO ioctl()'s I need, and roll it up into a display driver plugin. Any advice on where to start here? It'd be nice to re-use as much of the existing LinuxFb functionality as possible...
(2) As a quick (and probably terribly unorthodox) hack to try runtime resolution changes out, I had the following in a test app. This segfaults on the initDevice(). As far as the the Multi driver goes -- are all bets off once you call shutdownDevice() and disconnect()? Is there no way to reconnect and reinitialize?
@
QScreen *screen = QScreen::instance();
screen->shutdownDevice();
screen->disconnect();// Open up our /dev/fb*'s and make the necessary changes reconfigure_fbs(); screen->connect("Multi: LinuxFb:/dev/fb0 LinuxFb:/dev/fb2"); screen->initDevice();
@
I dove in a bit with GDB, and noted was that QMultiScreen::disconnect() doesn't appear to make calls to removeSubScreen() as I would have expected, which seems to result in QMultiScreen keeping around the old (and deinitialized) subscreens. I added removeSubScreen()'s as shown below:
@void QMultiScreen::disconnect()
{
const int n = d_ptr->screens.size();
for (int i = 0; i < n; ++i)
d_ptr->screens.at(i)->disconnect();while(d_ptr->screens.size() > 0) removeSubScreen(d_ptr->screens.at(0));
}
@With that in place, I wind up with some sort of invalid memory access in the LinuxFb init;
@
(gdb)Program received signal SIGSEGV, Segmentation fault.
0x4091b82c in QLinuxFbScreen::initDevice (this=0x122ad0)
at embedded/qscreenlinuxfb_qws.cpp:766
766 shared->fifocount = 0;
(gdb) print *shared
Cannot access memory at address 0x46001701
@Ultimately, I'm guessing (2) is downright wrong....and I suppose I'm using things incorrectly, unaware of the side effects that I'm inducing. Could someone familiar with this code confirm/deny?
Thanks! Hopefully I kept it under the tl;dr theshold ;)
Qt Version info: Currently using 4.7.4
-
[quote author="jonszy" date="1328309045"]
(1) Is this possible with the current LinuxFb implementation, or will I need to write a custom display driver?
[/quote]It appears that I somehow managed to overlook setMode(), which would do the trick in most cases. (In my case, the FB implementation has some non-standard ioctl() implementations that I need work with, so I'm still figuring this out.)
I find it interesting that the QLinuxFbScreen disconnect()'s and then connect()'s with the saved display spec string, but does not shutdown/reinitialize -- still not entirely sure why those steps were causing me trouble...thought I had things in the right order. Back to the docs and source, I suppose!