SDL event.window.windowID vs GetWindowID() - c++

What is the difference between the output of event.window.windowID and SDL_GetWindowID()?
Why is it that std::cout << m_SDLEvent.window.windowID << std::endl;
outputs 1819558491 in console while std::cout << SDL_GetWindowID(m_SDLWindow) << std::endl; outputs 1 ?
How would I achieve getting the right ID of my SDL_Window* in the method below?
void InputManager::Update()
{
SDL_PollEvent(&m_SDLEvent);
switch (m_SDLEvent.type)
{
case SDL_QUIT:
std::cout << m_SDLEvent.window.windowID << std::endl;
SDL_HideWindow(SDL_GetWindowFromID(m_SDLEvent.window.windowID));
break;
}
}

You're seeing garbage window ID because you access an inactive union field. That's undefined behavior.
You can only access m_SDLEvent.window if m_SDLEvent.type == SDL_WINDOWEVENT.
But if m_SDLEvent.type == SDL_QUIT, you have to use m_SDLEvent.quit structure, which has no field for window id (because SDL_QUIT is not specific to a window, but means that the entire application should be closed).

Okay so HolyBlackCat's answer brought me to the right direction.
Instead of using SDL_QUIT (which is the quit event for the entire app, not one window) I should've checked for SDL_WINDOWEVENT_CLOSE which is an SDL_WINDOWEVENT which can be received by m_SDLEvent.window.event instead of m_SDLEvent.type
So the code now looks like this:
void InputManager::Update()
{
SDL_PollEvent(&m_SDLEvent);
if (m_SDLEvent.type == SDL_WINDOWEVENT)
{
switch (m_SDLEvent.window.event)
{
case SDL_WINDOWEVENT_CLOSE:
std::cout << m_SDLEvent.window.windowID << std::endl;
SDL_HideWindow(SDL_GetWindowFromID(m_SDLEvent.window.windowID));
break;
}
}
}
Now std::cout << m_SDLEvent.window.windowID << std::endl; outputs the correct ID.

Related

Seemingly deadlock in WriteFile on stdout

I am writing a small application which handles a predefined exchange of messages over the serial port(basically a custom application level protocol).
The main 2 parts of it are a state-machine which defines what to respond to a certain expected message, the stop conditions, timeout of an expected message, etc and an "event loop" which listens (through a blocking call) on a separate thread to the communication events and, when it is awaken, it passes it to the state-machine to be processed. This in turn will make the states to flow and the process is repeated until the final state is reached, at which point the main thread is awaken(which was waiting with a std::cond_var) and joins the thread.
My problem arises when, out of the blue, the calls to the operator<< of cout block the event-loop thread indefinitely. The call stack shows that the thread is waiting in a WriteFile call. It seems to be a deadlock. I'm not very documented about windows API and inner workings, but it seems to be it should obviously not put any potential synchronization problem(deadlocks) to the user, even though it might not work as expected(i understand that not excluding access to that section for stdout at least will result in interleaved messages for example - this is not my problem ).
I have attached 2 printscreens in which i captured the thread stacks shown by Visual Studio. I really believe that there should be no application written is user space, no matter how bad, that would induce a deadlock in console output, which is why i'm not pasting code here.
Searched the web for a day and a half and at this point i don't know how to rephrase the search for google to get some useful info. Even if i did get, don't think i would necessarily know. Could you please point me some directions? Maybe common problems with stdout. Or something really bad i could in my code to cause a deadlock of this sort. Thank you in advance.
First operator<< sometimes reproduces the issue
At this point is usually the problem seen. A communication event just came in after a long delay/it timed out
void CSerialConnection::funct(std::tuple<bool, bool, int> args)
{
bool singleByteExpected = get<1>(args), stopped = get<0>(args);
unsigned int timeoutValue = get<2>(args);
bool terminate = false;
DWORD modemStatus;
OVERLAPPED osStatus;
memset(&osStatus, 0, sizeof(OVERLAPPED));
osStatus.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
cout << "Starting communication event loop ... " << endl;
BOOL fWaitingOnStat = FALSE;
BOOL bReadStatus = FALSE;
do
{
if (!fWaitingOnStat)
{
cout << "Listening for " << (singleByteExpected ? "control character .. " : "command payload .. ") << endl;
SetCommMask(mHandle, (singleByteExpected ? EV_RXCHAR : EV_RXFLAG ));
bReadStatus = WaitCommEvent(mHandle, &modemStatus, &osStatus);
}
if (bReadStatus)
{
cout << "Event occured sync" << endl;
mProtocol.processEvent(terminate);
if (terminate)
{
break;
}
}
else
{
if (GetLastError() == ERROR_IO_PENDING)
{
fWaitingOnStat = TRUE;
}
else
{
cout << "Communication event failed with code: " << GetLastError() << endl;
mProtocol.processTermination();
stopped = true;
}
if ( fWaitingOnStat )
{
cout << dec << "WAITING FOR " << ( timeoutValue ? timeoutValue : INFINITE ) << endl;
auto dwRes = WaitForSingleObject(osStatus.hEvent, timeoutValue ? timeoutValue : INFINITE);
cout << "WAIT ENDED :)" << endl;
if (dwRes == WAIT_OBJECT_0)
{
//cout << "Event occured async" << endl;
mProtocol.processEvent(terminate);
fWaitingOnStat = false;
if (terminate)
{
mProtocol.processTermination();
break;
}
}
else if (dwRes == WAIT_TIMEOUT)
{
cout << "Timeout" << endl;
mProtocol.processTimeout();
fWaitingOnStat = false;
}
else
{
cout << "Communication event failed with code: " << GetLastError( ) << endl;
mProtocol.processTermination();
stopped = true;
}
}
}
stopped = mProtocol.getStopRequiredFlag();
singleByteExpected = mProtocol.getWaitingForControlCharFlag();
timeoutValue = mProtocol.getTimeout();
}
while (!stopped);
cout << "Stopped communication event loop ... " << endl;
}
Solved! As per UKMonkey's suggestion, the behaviour was caused by me marking text on the console window. It consistenly works now if i leave it alone and blocks if i mark a character. I need to change these settings :). Thank you for interest in my question and the answers!

Cant acess the values from my sliding window?

I am currently implementing a sliding window functionality for a vector<double>. Problem is I cant seem to cout the values? When I output it i seem to get memeory location, rather than the actual values..
I need to process the data which the window consist of, so having acess to the values would be neat.
typedef double SAMPLE;
std::vector<std::vector<SAMPLES> > loaded_files;
//Some init
std::vector<SAMPLE>::iterator it;
for (it = loaded_file.samples[0].begin() ; (it + (NUM_SECONDS*SAMPLE_RATE)) != loaded_file.samples[0].end(); ++it)
{
auto window = *it;
std::cout << "printing the window!" << std::endl;
std::cout << &(window) << std::endl; // prints out memory location?
}
Each time you print the window contents, you need to iterate over the window itself. This can be done by changing the contents of your for loop like so:
typedef double SAMPLE;
std::vector<<SAMPLES>> loaded_files;
//Some init
std::vector<SAMPLE>::iterator it;
for (it = loaded_file.samples[0].begin(); (it + (NUM_SECONDS*SAMPLE_RATE)) != loaded_file.samples[0].end(); ++it)
{
std::cout << "printing the window!" << std::endl;
std::vector<SAMPLE>::iterator wit; // window iterator
for (wit = it; wit != it + (NUM_SECONDS*SAMPLE_RATE); ++wit)
{
std::cout << *wit << ',';
}
std::cout << std::endl;
}
Note that the width of the window is (NUM_SECONDS*SAMPLE_RATE). This could be stored in a variable like window_widthor similar to help with readability.
It is not clear what window object is holding. But in your below statement you are providing the address of window. Hence it is printing the address instead of value.
std::cout << &(window) << std::endl; // prints out memory location? YES
Try with below statement:-
std::cout << window << std::endl; // prints out value here

Printing name of a key in SDL

My SDL program is returning a memory address which is same for all keys, I'm attempting to print the name of the key, i.e if the user presses 'F' key the console outputs 'F'. How would i go about editing my code to achieve this?
void Game::handleEvents()
{
SDL_Event event;
if(SDL_PollEvent(&event))
{
switch (event.type) {
case SDL_QUIT:
g_bRunning = false;
//SDL_Quit();
break;
case SDL_KEYDOWN:
//this is the line that is not working as expected.
std::cout << &event.key.keysym.sym << std::endl;
default:
break;
}
}
}
The & in std::cout << &event.key.keysym.sym << std::endl; is unnecessary. That is the cause of printing address instead of actual data.
However even with & removed this will not output you 'f' for f keypressed, since value is integer enumeration, and not ASCII code values.
Use SDL_GetKeyName() to get a printable string that represents the key pressed. Since SDL_Keycode (SDLKey in SDL1.2) is implemented as an enumeration, it cannot be simply converted to a printable character, particularly for keys like "shift" and "alt".
Try this:
std::cout << SDL_GetKeyName(event.key.keysym.sym) << std::endl;
The keycode for f is SDLK_f
A simple if statement should do it:
case SDL_KEYDOWN:
if( event.key.keysym.sym == SDLK_f )
std::cout << "f was pressed" << std::endl;
break ; //this was missing
SDL doesn't distinguish cases so you need an extra check for that, if was shift pressed etc.

WINDOWPLACEMENT's showCmd… always 1?

When I do a get GetWindowPlacement, the WINDOWPLACEMENT::showCmd seems to be always 1, which is SW_SHOWNORMAL.
Does anyone know why is this so and if it is updated? Does anyone know if this variable is maintained by the application itself or by the operating system?
I am running this on Windows 7.
I am using this to achieve the same purpose as mentioned in this thread: I am trying to undo hidden windows that were previously shown without storing the hidden windows in memory (hide/show will be called in different run sessions) or on disk.
void hide(const unsigned int pid){
std::list<HWND> windowList = getWindowbyPID(pid);
for(std::list<HWND>::iterator it = windowList.begin(); it != windowList.end(); it++){
if(IsWindowVisible(*it)){ std::cout << "Hid WIN#" << *it << std::endl; ShowWindow(*it,SW_HIDE); }
}
}
void show(const unsigned int pid){
std::list<HWND> windowList = getWindowbyPID(pid);
for(std::list<HWND>::iterator it = windowList.begin(); it != windowList.end(); it++){
//if(IsWindowVisible(*it)){ ShowWindow(*it,SW_SHOW); }
WINDOWPLACEMENT wp;
wp.length = sizeof(wp);
wp.showCmd = 0; // Just to clear showCmd before reading.
std::cout << *it << std::endl;
std::cout << "BEFORE: " << wp.showCmd << std::endl;
GetWindowPlacement(*it,&wp);
std::cout << "AFTER: " << wp.showCmd << std::endl;
}
}
Output of one example that I did (pid of notepad.exe) after hiding hwnd#00060CD0:
003D0642
BEFORE: 0
AFTER: 1
000B0682
BEFORE: 0
AFTER: 1
00060CD0
BEFORE: 0
AFTER: 1
I am trying to use GetWindowPlacement to differentiate the windows that were always hidden and the windows that were previously shown. It never seems to be 0 even for windows that were always hidden.
There are only three possible values of the showCmd after calling GetWindowPlacement.
From the MSDN documentation on GetWindowPlacement (emphasis mine):
The flags member of WINDOWPLACEMENT retrieved by this function is always zero. If the window identified by the hWnd parameter is maximized, the showCmd member is SW_SHOWMAXIMIZED. If the window is minimized, showCmd is SW_SHOWMINIMIZED. Otherwise, it is SW_SHOWNORMAL.
Therefore, it appears that the window you're asking for placement info on is in a state other than maximized or minimized when you're calling GetWindowPlacement.
I'd suspect what you're actually looking for is IsWindowVisible.

C++ OIS Segfault When Almost Identical Functions Work

See important edit below!
Hi all I'm having trouble figuring out why this segfault is happening. I'm using the Ogre and OIS library. Here is the code that causes it:
bool Troll::Application::keyPressed(const OIS::KeyEvent& event) {
//TODO: Segfault here!
Troll::State* state = mStateManager->peek();
state->key_pressed(event); //This causes the SEGFAULT!!!
return true;
};
And the key_pressed function:
void Troll::RootState::key_pressed(const OIS::KeyEvent& event) {
std::cout << "You got here" << std::endl; //this isnt printed!
std::cout << "Key Pressed: " << event.key << std::endl;
};
Because the segfault is happening on key_pressed but the first line of key_pressed isn't being executed, I can only guess that it is passing the const OIS::KeyEvent& that is causing it.
And the weird thing about this is I have three other functions that are almost identical (but for the mouse) which work perfectly.
bool Troll::Application::mouseMoved(const OIS::MouseEvent& event) {
mStateManager->peek()->mouse_moved(event);
return true;
};
void Troll::RootState::mouse_moved(const OIS::MouseEvent& event) {
std::cout << "Mouse Moved: rel x = " << event.state.X.rel << std::endl;
std::cout << " rel y = " << event.state.Y.rel << std::endl;
std::cout << " abs x = " << event.state.X.abs << std::endl;
std::cout << " abs y = " << event.state.Y.abs << std::endl;
};
I'm creating a basic state system so I can start writing applications for Ogre3D using the OIS library for input. I have an Application class which acts as an input listener for the mouse and keyboard. Here is how its setup...
void Troll::Application::setup_ois() {
//create a parameter list for holding the window handle data
OIS::ParamList pl;
size_t windowHnd = 0;
//we need the window handle to setup OIS
std::ostringstream windowHndStr;
mWindow->getCustomAttribute("WINDOW", &windowHnd);
windowHndStr << windowHnd;
//add the handle data into the parameter list
pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
//create the input system with the parameter list (containing handle data)
mInputManager = OIS::InputManager::createInputSystem(pl);
//true in createInputObject means we want buffered input
mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, true ));
mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject( OIS::OISMouse, true ));
//set this as an event handler
mKeyboard->setEventCallback(this);
mMouse->setEventCallback(this);
};
The application class relays the mouse moves, button pressed and key strokes to the Troll::State (the framework I'm making is called Troll) at the top of the state stack which is inside the Troll:: StateManager (which is merely a wrapper for an std::stack with memory allocation and startup() and shutdown() calls)
Sorry for any confusion the difference of the naming conventions causes for some reason I decided to use_underscores_for_some_reason and I haven't got round to changing it. Thanks in advance, ell. Hope you can solve my problem and please inform me if I haven't given enough detail.
EDIT:
After recently upgrading to Ubuntu Natty Narwhal I cannot get the debugger to work properly, it just crashes the computer. I use Code::Blocks and I don't have a clue how to use a debugger or compiler outside the IDE (sad I know, but I'll get round to learning someday). So sorry, I can't use a debugger.
EDIT:
In response to GMan's comment, even if I check for null, I still get segfaults
bool Troll::Application::keyPressed(const OIS::KeyEvent& event) {
//TODO: Segfault here!
Troll::State* state = mStateManager->peek();
if(state == 0) {
std::cout << "State is null!" << std::endl;
};
state->key_pressed(event);
return true;
};
Although I'm not sure thats the correct way to check for null? Also, other methods using peek() work correctly. Thanks again! :)
Important Edit:
It seems that it is in fact the peek function that is causing trouble, but only when called from the keyPressed function. I discovered this by adding a parameter to peek() so that it would print the address of the state object it return as well as the message. By setting the message parameter to the function from where the peek() function is called, I got these results.
Root state is: 0x8fdd470
Peeking state... 0x8fdd470 from: Application::frameRenderingQueued()
Peeking state... 0x8fdd470 from: Application::mouseMoved
Peeking state... 0x8fdd470 from: Application::frameRenderingQueued()
Peeking state... 0x8fdd470 from: Application::frameRenderingQueued()
Peeking state... 0x8fdd470 from: Application::frameRenderingQueued()
Peeking state... 0x936cf88 from: Application::keyPressed
Segmentation fault
Notice that when the keyPressed function calls the peek method, a different address is shown. I cannot see why a different address is being returned only when the keyPress function calls peek? Somebody please help me with this!
What happens when you check for mStateManager being NULL, and for NULL being returned from mStateManager->peek()?
bool Troll::Application::keyPressed(const OIS::KeyEvent& event) {
if (mStateManager == NULL) {
//! set breakpoint on next line
std::cout << "mStateManager is NULL, returning false" << std::endl;
return false;
}
std::cout << "about to call peek" << std::endl;
if (Troll::State* state = mStateManager->peek())
{
std::cout << "about to call key_pressed" << std::endl;
state->key_pressed(event); //Does this still cause a SEGFAULT?
std::cout << "back from key_pressed" << std::endl;
return true;
}
std::cout << "mStateManager->peek() returned NULL, returning false" << std::endl;
return false;
};
EDIT: I edited the code to print each branch, how it was traced through.

Resources