What is the nicest way to close FreeGLUT? - c++

I'm really having trouble closing my console application with FreeGLUT.
I would like to know what the best way is to take every possible closing, because I don't want any memory leaks (I'm pretty afraid of those).
So I already tried the following, which is giving me an exception like this:
First-chance exception at 0x754e6a6f in myProject.exe: 0x40010005: Control-C.
int main(int argc, char **argv)
{
if( SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, true) )
{
// more code here as well ....
glutCloseFunc(close); // set the window closing function of opengl
glutMainLoop();
close(); // close function if coming here somehow
}
else
{
return 1;
}
return 0;
}
void close()
{
// keyboardManager is a pointer to a class
// which I want to delete, so no memory will leak.
if(keyboardManager) // do I need this check?
delete keyboardManager;
}
bool CtrlHandler(DWORD fdwCtrlType)
{
switch(fdwCtrlType)
{
// Handle the CTRL-C signal.
case CTRL_C_EVENT:
// and the close button
case CTRL_CLOSE_EVENT:
close();
return true;
// Pass other signals to the next handler.
case CTRL_BREAK_EVENT:
return false;
// delete the pointer anyway
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
default:
close();
return false;
}
}
So what goes right is:
Closing the window of glut
Closing the console application with the x
Closing my window of glut with my keyboardmanager if(keyboardManager->isKeyDown[27]) glutExit();
What goes wrong is:
Closing the console application with CTRL+C, it gives the exception from above.
This is in Visual Studio 2008 C++.
UPDATE
I found that the exception is thrown, because I'm in debug. So that won't be a problem. But the question is still open: What is the most elegant way to actually close glut?
atexit() seems to work as well, so maybe I can use this?

I use this function:
void glutLeaveMainLoop ( void );
There is more information on their sourceforge page but I never used that functionality:
The glutLeaveMainLoop function causes freeglut to stop the event loop. If the GLUT_ACTION_ON_WINDOW_CLOSE option has been set to GLUT_ACTION_CONTINUE_EXECUTION, control will return to the function which called glutMainLoop; otherwise the application will exit.
http://freeglut.sourceforge.net/docs/api.php#EventProcessing
It is safe to use delete on a null pointer, no need to check.

Thanks to Maarten's post, this works to me:
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,GLUT_ACTION_CONTINUE_EXECUTION);
whenever you want to leave the mainloop without termiante the application use:
glutLeaveMainLoop();
don't forget to include "freeglut.h"

I use glutDestroyWindow(int handle);
or
According to ID: RigidBody at OpenGL forum
void destroy_window()
{
window_valid = -1;
}
void display_func()
{
if(window_valid == -1)
return;
// draw things
}

Try this method:
glutDestroyWindow(glutGetWindow());

Related

Reparenting wm and BadWindow errors

I'm writing a reparenting window manager in XCB and C++:http://ix.io/3yNo
At the moment it works pretty well, but occasionally when I close a window, all the windows of that application close because the process exits with a BadWindow. For example if I have a couple xfce4-terminal windows open, all managed by one process,and I close one, occasionally the application will close and I will get a BadWindow (invalid window parameter) error (in the app, not my wm). The very interesting thing is that this is not reproducible but kind of rare, probably a race condition between reporting the error and closing the window due to X11's asynchoronous nature.I have no clue where to begin debugging this, any tips?I kind of suspect it might be something in the Unmap O
Your link contains almost 500 lines of code. I am not going to try to fully understand that. Instead, I'll just randomly guess.
auto window_manager::handle_unmap_notify(xcb_unmap_notify_event_t *ev) -> void {
if (unmap_ignore > 0) {
unmap_ignore--;
return;
}
client *cl = nullptr;
size_t idx = 0;
for (client &c : clients) {
if (c.window == ev->window) {
cl = &c;
break;
}
idx++;
}
if (not cl)
return;
xcb_destroy_window(conn, cl->frame);
clients.erase(clients.begin() + idx);
}
You are destroying windows that are not yours. When the owner of the window accesses it the next time, it will get a BadWindow error.
Instead, you should check a window's WM_PROTOCOLS property and check for WM_DELETE_WINDOW. If that is present, you are supposed to send a WM_DELETE_WINDOW message to the window. See ICCCM ยง 4.2.8.1: https://tronche.com/gui/x/icccm/sec-4.html#s-4.2.8.1

Sharing opengl resources (OpenGL ES 2.0 Multithreading)

I have developed an OpenGL ES 2.0 win32 application, that works fine in a single thread. But I also understand that UI thread and a rendering thread should be separate.
Currently my game loop looks something like that:
done = 0;
while(!done)
{
msg = GetMessage(..); // getting messages from OS
if(msg == QUIT) // the window has been closed
{
done = 1;
}
DispatchMessage(msg,..); //Calling KeyDown, KeyUp events to handle user input;
DrawCall(...); //Render a frame
Update(..); // Update
}
Please view it as a pseudo code, cause i don't want to bother you with details at this point.
So my next step was to turn done into an std::atomic_int and create a function
RenderThreadMain()
{
while(!done.load())
{
Draw(...);
}
}
and create a std::unique_ptr<std::thread> m_renderThread variable. As you can guess nothing has worked for me so far, so i made my code as stupid and simple as possible in order to make sure i don't break anything with the order i call methods in. So right now my game loop works like this.
done.store(0);
bool created = false;
while(!done)
{
msg = GetMessage(..); // getting messages from OS
if(msg == QUIT) // the window has been closed
{
done.store(1);
}
DispatchMessage(msg,..); //Calling KeyDown, KeyUp events to handle user input;
// to make sure, that my problem is not related to the fact, that i'm rendering too early.
if(!created)
{
m_renderThread = std::make_unique<std::thread>(RenderThreadMain, ...);
created = true;
}
Update(..); // Update
}
But this doesn't work. On every draw call, when i try to somehow access or use my buffers \ textures anything else, i get the GL_INVALID_OPERATION error code.
So my guess would be, that the problem is in me calling glGenBuffers(mk_bufferNumber, m_bufferIds); in the main thread during initialization and then calling glBindBuffer(GL_ARRAY_BUFFER, m_bufferIds[0]); in a render thread during the draw call. (the same applies to every openGL object i have)
But I don't now if i'm right or wrong.

wxWidgets debug assertion failed, xtree not deferencable, when modifying wxTextCtrl value

When I enter a wxDialog and I focus one wxTextCtrl nothing bad happens but as soon as I modify something in that text, like deleting one character, the application crashes with this message:
"debug assertion failed: map/set iterator not dereferencable"
The last method I found out is called before crashing is this one:
bool wxWindowMSW::HandleKillFocus(WXHWND hwnd)
{
#if wxUSE_CARET
// Deal with caret
if ( m_caret )
{
m_caret->OnKillFocus();
}
#endif // wxUSE_CARET
#if wxUSE_TEXTCTRL
// If it's a wxTextCtrl don't send the event as it will be done
// after the control gets to process it.
wxTextCtrl *ctrl = wxDynamicCastThis(wxTextCtrl);
if ( ctrl )
{
return false;
}
#endif
// Don't send the event when in the process of being deleted. This can
// only cause problems if the event handler tries to access the object.
if ( m_isBeingDeleted )
{
return false;
}
wxFocusEvent event(wxEVT_KILL_FOCUS, m_windowId);
event.SetEventObject(this);
// wxFindWinFromHandle() may return NULL, it is ok
event.SetWindow(wxFindWinFromHandle(hwnd));
return GetEventHandler()->ProcessEvent(event);
}
While running the application, this method is called many times; ctrl having a value of 0x00000000 all the time and therefor not returning false in the first IF clause.
While being inside the dialog and modifying the text, the value of ctrl changes to a real value 0x031194b0; then it enters the IF clause, returns false, and crashes.
The problem came from another code modification that I still do not find how it could have this effect. Internal behaviour of wxWidgets library maybe?

How to check if an opencv window is closed

How do you check if an opencv window has been closed?
I would like to do:
cvNamedWindow("main", 1);
while(!cvWindowIsClosed("main"))
{
cvShowImage("main", myImage);
}
but these is no such cvWindowIsClosed(...) function!
What you are trying to do can be achieved with cvGetWindowHandle():
The function cvGetWindowHandle returns the native window handle (HWND in case of Win32 and GtkWidget in case of GTK+). [Qt Backend Only] qt-specific details: The function cvGetWindowHandle returns the native window handle inheriting from the Qt class QWidget.
The idea is to get the handle of the window and then use specific platform API functions to check if that handle is still valid.
EDIT:
Or you could use the tradicional cvWaitKey() approach:
char exit_key_press = 0;
while (exit_key_press != 'q') // or key != ESC
{
// retrieve frame
// display frame
exit_key_press = cvWaitKey(10);
}
Suppose you have only one image window open, then clicking the 'x' button at its corner causes the waitkey() function to return a -1 value.
Then check if the cvGetWindowHandle("name_of_the_window") function returns 0 or not. If it does return 0, then the window is actually closed.
I have tested it in OpenCV3.
But I am still not very clear on the reason why the waitkey() return -. I will much appreciate if anyone explains why this happens.
[I don't know if my answer to this question will be relevant or not after such a long time. But hopefully if anyone else gets stuck with the same issue (like me), this answer might help them out.]
Thanks.
You can use the cv::getWindowProperty method.
Do like that:
cv::namedWindow("main", WINDOW_AUTOSIZE);
while(1)
{
cv::imshow("main", myImage);
// add this IF.
if (cv::getWindowProperty("main", WND_PROP_AUTOSIZE) == -1)
break;
}
When the windows be closed the getWindowProperty will return -1.
This should do
#include <opencv2/opencv.hpp>
std::string mTitle = "title of my window";
while (cvGetWindowHandle(mTitle.c_str()))
{
// ...
}
In Python OpenCV version 3.4.2, Ubuntu Bionic, cv2.getWindowProperty('Main', cv2.WND_PROP_VISIBLE) returns a floating 0.0 (zero) when the window is closed and 1.0 (one) when it's open, whether see-able or not. Yes, still a 1.0 when it's minimized or behind another window or on a different desktop.
Just before the end of the main(), put the following code:
int main(int, char**){
.
.
.
bool visible = true;
while(visible){
waitKey(1000);
visible = getWindowProperty("Main",WND_PROP_VISIBLE) > 0;
}
return 0;
}

FLTK Closing window

I am using FLTK. I have a window with a variety of buttons the user can click to perform some action. In my int main() i have a switch statement to handle all of these. When the user clicks exit the switch statement is setup like so:
case Exit_program:
cout << "save files and exit\n";
do_save_exit(sw);
This goes to the do_save_exit function that creates a exit confirmation window with two buttons yes (exit) and no (don't exit). I got the yes button to work, exits the program, but the no button mean i should just hide the confirmation window. This is the follow functions:
void yes(Address addr, Address)
{
exit(0);
}
void no(Address addr, Address)
{
}
void do_save_exit(Window& w)
{
Window quit(Point(w.x()+100, w.y()+100), 250, 55, "Exit confirmation");
Text conf(Point(15,15),"Do you really want to save and exit?");
Button yes(Point(60, 20),35,30,"Yes",yes);
Button no(Point(140, 20),35,30,"No",no);
quit.attach(conf);
quit.attach(yes);
quit.attach(no);
wait_for_main_window_click();
}
The problem is, when i click the no button it goes to void no, but I can't go anywhere from there. I just want to do quit.hide() but the no function doesn't have sight of the quit window (out of scope). How should I proceed? Thank you
P.S: I have thought about using a pointer to the quit window and then using the pointer to quit the window in the no function but am not sure how to do that exactly.
The Fl_Window callback is called when an attempt is made to close the window. The default callback hides the window (and if all windows are hidden, your application ends). If you set your own window callback, you can override this behaviour, so as not to hide the window:
// This window callback allows the user to save & exit, don't save, or cancel.
static void window_cb (Fl_Widget *widget, void *)
{
Fl_Window *window = (Fl_Window *)widget;
// fl_choice presents a modal dialog window with up to three choices.
int result = fl_choice("Do you want to save before quitting?",
"Don't Save", // 0
"Save", // 1
"Cancel" // 2
);
if (result == 0) { // Close without saving
window->hide();
} else if (result == 1) { // Save and close
save();
window->hide();
} else if (result == 2) { // Cancel / don't close
// don't do anything
}
}
Set your window's callback wherever you set up your Fl_Window, e.g. in your main function:
window->callback( win_cb );
You probably need to look at using a modal (i.e., dialog) window. Look at <FL/fl_ask.h>
if (fl_ask("Do you really want to save and exit?"))
save_and_exit();
The header also has functions for the popup's font, title, etc.
When you build you don't get an error or warning? The problem is probably that you have both global functions names yes and no and also local variables called just the same. Rename either the functions of the variables.
No need to use hide().
You can simply use exit(0); in a callback.