Can I assume that on android SDL registers main screen as touch device 0? Or else how do I get main screen id? - sdl

As SDL_GetNumTouchDevices() suggests, SDL supports multiple touch devices.
Can I assume that SDL_GetTouchDevice(0) will return an ID of the main screen?
If I can't then how do I figure out which one of them is the main screen?

I used index 1 and it worked.
I was testing on a BlackBerry Key2, which technically has two touch inputs (the keyboard is capacitive as well as the screen) so I don;t know if that might have been the reasn for my success. I gave that function the index 1 - SDL_GetTouchDevice(1) - and it worked. I can succsessfully detect touch inputs!
if (event.type == SDL_FINGERDOWN && SDL_GetNumTouchFingers(1) == 2)
{
interface->getMainMenu().setShowMainMenu();
}
So here SDL_GetNumTouchFingers(1) takes in the DeviceID index. I provided the value of 1 and it worked :)

Related

How to fully/correctly exit a Qt program from the main form?

I'm writing a Qt program (using Qt 5.4) that reads frames from a webcam based on a QTimer, not a separate thread (interval set to 20 ms, of course it takes much longer than 1/50 of a second to read a frame from the webcam and process it, I'd approximate the frame rate is perhaps 20 fps. Anyhow, the function which runs when the timer cycles is a slot and is as follows:
///////////////////////////////////////////////////////////////////////////////////////////////////
void frmMain::processFrameAndUpdateGUI() {
bool blnFrameReadSuccessfully = capWebcam.read(matOriginal); // get next frame from the webcam
if (!blnFrameReadSuccessfully || matOriginal.empty()) { // if we did not get a frame
QMessageBox::information(this, "", "unable to read from webcam \n\n exiting program\n");
QApplication::quit();
}
// process frame here . . .
The idea being if the webcam can be successfully read at the beginning of the program, but then cannot be (webcam stops working, user accidentally disconnects webcam, etc.) the program should show a message box to this effect and then close itself entirely.
With the above, if I unplug the webcam while the program is running for testing purposes, the message box appears as intended, but after choosing OK, a debug error screen appears. If I choose "Abort" the form is still there and will not respond. After attempting to close the form multiple times Windows asks "the program does not seem to be responding, would you like to close?" at which time I can close the form. Clearly this is not achieving the intended effect.
After various Googling I found the suggestion to modify as follows:
///////////////////////////////////////////////////////////////////////////////////////////////////
void frmMain::closeEvent(QCloseEvent *) {
QApplication::quit();
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void frmMain::processFrameAndUpdateGUI() {
bool blnFrameReadSuccessfully = capWebcam.read(matOriginal); // get next frame from the webcam
if (!blnFrameReadSuccessfully || matOriginal.empty()) { // if we did not get a frame
QMessageBox::information(this, "", "unable to read from webcam \n\n exiting program\n");
closeEvent(new QCloseEvent());
}
// process frame here . . .
When I first saw this code I was optimistic, however it gives me the same result as above (program hangs with the form still open). I'm using OpenCV 2.4.11 for my image processing and my program has 4 files:
frmmain.h (.h for the main form, which is a standard QMainWindow made with Qt Creator)
frmmain.cpp (.cpp for the main form, where the above code resides)
main.cpp (which I have not changed from how Qt Creator made it)
frmmain.ui (typical form with a small number of common widgets added via Qt Creator)
Yes, I realize that I could show an error message on one of the widgets that can show text, return from the function, and leave it to the user to close the program, but I'm looking for a more elegant solution. Can anybody offer further advice as to how to fully close a graphical Qt program? Please advise.
Two things that could possible solve your problem:
Before displaying the messagebox, stop the timer with the stop() method.
After the QApplication::quit(); exit the function with return; Your function might be running to the end one last time and accessing invalid objects.
For anybody else's reference Rafael Monteiro's answer was spot on. Here is the updated code (verified working):
///////////////////////////////////////////////////////////////////////////////////////////////////
void frmMain::closeEvent(QCloseEvent *) {
if(qtimer->isActive()) qtimer->stop(); // had to stop timer here !!!!!!!!
QApplication::quit();
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void frmMain::processFrameAndUpdateGUI() {
bool blnFrameReadSuccessfully = capWebcam.read(matOriginal); // get next frame from the webcam
if (!blnFrameReadSuccessfully || matOriginal.empty()) { // if we did not get a frame
QMessageBox::information(this, "", "unable to read from webcam \n\n exiting program\n");
closeEvent(new QCloseEvent());
return; // had to add return here !!!!!!!!!
}
// rest of function here . . .
I should mention I had to add both the return and stop the timer. Thanks Rafael!

SDL_GetRelativeMouseState strange behaviour

I have an application in SDL 2.0.3 that enters relative mouse mode before entering the main game loop. In addition, function mouse_input is called in each step:
int mdltx = 0, mdlty = 0;
void mouse_input () {
auto r = SDL_GetRelativeMouseState(&mdltx, &mdlty);
if (mdltx != 0 || mdlty != 0)
cout << "(" << mdltx << "," << mdlty << ")" << endl;
// Update mouse key presses
mpul = !!(r&SDL_BUTTON(1)) | ((!!(r&SDL_BUTTON(3)))<<1);
}
According to the documentation of SDL_GetRelativeMouseState:
(...) x and y are set to the mouse deltas since the last call to SDL_GetRelativeMouseState() or since event initialization.
I've added the output lines for debugging purposes, because the resulting effect in the application was very awkward. It turns out that each time I move the mouse (and only when I move it), the console prints values in an unreasonable range. Below is a sample from doing simple mouse movements. The affected axis seems correct (moving horizontally will set mdlty to 0 and moving vertically will set mdltx to 0), but the numbers can get much higher than the screen resolution, and all of them are positive, regardless of the direction I move the mouse.
(342,216)
(47290,0)
(23696,0)
(23730,0)
(23764,0)
(23799,0)
(71190,0)
(117970,83397)
(23491,41802)
(23457,0)
(23423,83811)
(0,41871)
(23389,208322)
(23355,82847)
(0,41320)
(46812,0)
I have been looking around the web for people having the same problem, without any success.
Also note that this application was previously made for SDL 1, relying on SDL_GetMouseState and SDL_WarpMouse, but the latter function does not seem to do anything in some platforms. I'm working on the application under an Arch Linux + LXDE installation, which seems to simply ignore the mouse warp. This is the same machine where this other strange behaviour is happening.
The question is: why is this happening and how can I fix it with compatibility in mind, while keeping the advantages of having relative mouse mode? I even wonder if it could be an issue within SDL itself.
For anyone else struggling with this problem, it might help to set:
SDL_SetHintWithPriority(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "1", SDL_HINT_OVERRIDE);
SDL_SetRelativeMouseMode(SDL_TRUE);
This seems to give you relative mouse-output, where the center of the screen is (0,0).
However for me it doesn't currently reset the Cursor-coordinates properly, so while every frame resets this to (0,0), it jumps straight to the previous coord += movement.
This is a lot better than the alternative though, it seems.
The same code is working in a different machine, so this seems to be a bug. And it seems that some people found it too, with a broader range of misbehaviours than the one mentioned.
https://bugzilla.libsdl.org/show_bug.cgi?id=2150

SDL_RenderCopy() has strange behavior on Raspberry PI

This is driving me up the wall..
I've got a very simple SDL2 program.
It has a array of 3 SDL_Texture pointers.
These textures are filled as follows:
SDL_Texture *myarray[15];
SDL_Surface *surface;
for(int i=0;i<3;i++)
{
char filename[] = "X.bmp";
filename[0] = i + '0';
surface = SDL_LoadBMP(filename);
myarray[i] = SDL_CreateTextureFromSurface(myrenderer,surface);
SDL_FreeSurface(surface);
}
This works, no errors.
In the main loop (which is just a standard event loop waiting for SDL_QUIT, keystrokes and a user-event which a SDL_Timer puts in the event queue every second) I just do (for the timer triggered event):
idx = (idx+1) % 3; // idx is global var initially 0.
SDL_RenderClear(myrenderer);
SDL_RenderCopy(myrenderer, myarray[idx], NULL, NULL);
SDL_RendererPresent(myrenderer);
This works fine for 0.bmp and 1.bmp, but the 3rd image (2.bmp) simply shows as a black field.
This is structural.
If I alternate the first 2 images they are both fine.
If I alternate the 2nd and 3rd image the 3rd image doesn't show.
If I use more than 3 images then 3 and upwards show as black.
Loading order doesn't matter. It starts going wrong with the 3rd image loaded from disk.
All images are properly formatted BMP's.
I even saved 2.bmp back to disk under a different name by using SDL_SaveBMP() after it was loaded to make sure it got loaded in memory OK. The new file is bit for bit identical to the original.
This program, without modifications and the same bmp files, works fine on OSX (XCode5) and Windows (VC++ 2012 Express).
The problem only shows on the Raspberry PI.
I have placed explicit error checks on every call that can leave a result/error-code (not shown in the samples above for brevity) but all of them show "no error".
I have used the latest stable source set of www.libsdl.org and compiled as instructed (configure, make, make install, etc.).
Anybody got any idea what could be going on ?
P.S.
Keyboard input doesn't seem to work either on my PI, but I haven't delved into that yet.
Answering myself as I finally figured it out myself...
I finally went back to the README-raspberrypi.txt that came with the SDL2 sources.
I didn't read it carefully enough the first time around...
Problem 1: I'am running on a FULL-HD display. The PI's default GPU memory is 64MB which is not enough for large displays and double-buffering. As suggested in the README I increased this to 128MB and this solved the black image problem.
Problem 2: Text input wasn't working because my user-account was not in the input group. I had added the default "pi" account to the input group initially, but when I later started using another account I forgot to add that user to the group.
In short: Caught by my own (too) quick skimming of the documentation.

Matlab - Closing vision.VideoPlayer handler

First of all, excusme for my bad English. I am working in it.
I am working in a computer vision application. I am using a webcam. The main loop is like this:
while true
get frame
process frame
show frame in figure
end while
And I want something like this:
while figure is open
get frame
process frame
show frame in figure
end while
I used to use figure and imshow for plot the frame, and I used handlers for knowing when the figure is closed by the user.
fig = figure;
set(fig,'KeyPressFcn','exit = true;');
set(fig,'CloseRequestFcn', 'exit = true; delete(gcf)');
But now I am using the vision.VideoPlayer from the Computer System Toolbox because is faster, and I can not find a way to do some similar. I don't want to use a GUI.
The code is this (from this other thread):
vid = videoinput('winvideo', 1, 'RGB24_320x240'); %select input device
hvpc = vision.VideoPlayer; %create video player object
src = getselectedsource(vid);
vid.FramesPerTrigger =1;
vid.TriggerRepeat = Inf;
vid.ReturnedColorspace = 'rgb';
src.FrameRate = '30';
start(vid)
%start main loop for image acquisition
for t=1:500
imgO=getdata(vid,1,'uint8'); %get image from camera
hvpc.step(imgO); %see current image in player
end
Some idea?
You can find the figure handle of vision.VideoPlayer object by turning on "ShowHiddenHandles".
set(0, 'ShowHiddenHandles', 'on') % Revert this back to off after you get the handle
After this gcf can give you the handle. But it is risky to change callbacks for hidden handles. They might already have many of their callbacks set for proper functioning of VideoPlayer object. You might want to check for their validity and visibility to detect whether it is open.
h = gcf;
...
ishandle(h)
get(h, 'Visible') % will return 'off' if the figure is not visible.

GetKeyState doesn't work in Windows 2000 (C++)

I have just tested my DirectX game on a Windows 2000 SP4 system but it won't receive any mouse clicks!
This is how I check for mouse clicks :
unsigned int mButtons = 0;
if (GetKeyState(VK_LBUTTON) < 0) mButtons |= HIDBoss::MOUSE_LEFT;
if (GetKeyState(VK_RBUTTON) < 0) mButtons |= HIDBoss::MOUSE_RIGHT;
if (GetKeyState(VK_MBUTTON) < 0) mButtons |= HIDBoss::MOUSE_MIDDLE;
if (GetKeyState(VK_XBUTTON1) < 0) mButtons |= HIDBoss::MOUSE_4;
if (GetKeyState(VK_XBUTTON2) < 0) mButtons |= HIDBoss::MOUSE_5;
etc...
This code works perfectly on Windows 7 and XP 32/64bit.
The problem is fixed if I use the OIS library instead - which uses DirectX input - but it contains a few bugs so I would rather avoid it.
Can anyone suggest why GetKeyState won't work on W2K? Could it be because the system hasn't been updated - through Windows Update - for the last couple of years..?
Thank you for your time,
Bill
I'm not sure why it doesn't work but I'd recommend using GetAsyncKeyState instead.
Edit: In answer to your comment. It is merely a suggestion but its, equally, pretty easy to find out if the buttons are swapped by calling:
GetSystemMetrics(SM_SWAPBUTTON)
Your big problem arises from the fact that GetKeyState is not supposed to return a value for mouse buttons only keyboard buttons. the fact it DOES work in some OSs is not something you are supposed to be able to rely on across all OSs.
An application calls GetKeyState in
response to a keyboard-input message.
This function retrieves the state of
the key when the input message was
generated.
Its worth noting that it makes specific mention of calling it in response to a keyboard-input message (ie WM_KEY[UP/DOWN]). Equally there is no mention that this should work for mice. As such you really are better off just using GetAsyncKeyState...