commit a444b29eb63c96a064089afcb5de1b7c88f49e80
parent a5b741b57a9b31ba89252a1e156e9d7f4f7a8ca8
Author: Tim Brooks <brooks@cern.ch>
Date: Mon, 17 Oct 2016 20:07:42 +0200
Fix X11 error on exit
Catch WM_DELETE_WINDOW events and close down gracefully.
See: http://www.lemoda.net/c/xlib-wmclose/
Diffstat:
3 files changed, 29 insertions(+), 7 deletions(-)
diff --git a/DrawFunctions.h b/DrawFunctions.h
@@ -34,6 +34,7 @@ void CNFGClearFrame();
void CNFGSwapBuffers();
void CNFGGetDimensions( short * x, short * y );
+void CNFGTearDown();
void CNFGSetup( const char * WindowName, int w, int h );
void CNFGSetupFullscreen( const char * WindowName, int screen_number );
void CNFGHandleInput();
diff --git a/WinDriver.c b/WinDriver.c
@@ -123,12 +123,17 @@ LRESULT CALLBACK MyWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
switch(msg)
{
case WM_DESTROY:
- PostQuitMessage(0);
+ CNFGTearDown();
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
+void CNFGTearDown()
+{
+ PostQuitMessage(0);
+}
+
//This was from the article, too... well, mostly.
void CNFGSetup( const char * name_of_window, int width, int height )
{
diff --git a/XDriver.c b/XDriver.c
@@ -127,9 +127,21 @@ void CNFGSetupFullscreen( const char * WindowName, int screen_no )
}
+void CNFGTearDown()
+{
+ if ( CNFGClassHint ) XFree( CNFGClassHint );
+ if ( CNFGGC ) XFreeGC( CNFGDisplay, CNFGGC );
+ if ( CNFGWindowGC ) XFreeGC( CNFGDisplay, CNFGWindowGC );
+ if ( CNFGDisplay ) XCloseDisplay( CNFGDisplay );
+ CNFGDisplay = NULL;
+ CNFGWindowGC = CNFGGC = NULL;
+ CNFGClassHint = NULL;
+}
+
void CNFGSetup( const char * WindowName, int w, int h )
{
CNFGDisplay = XOpenDisplay(NULL);
+ atexit( CNFGTearDown );
XGetWindowAttributes( CNFGDisplay, RootWindow(CNFGDisplay, 0), &CNFGWinAtt );
int depth = CNFGWinAtt.depth;
@@ -138,6 +150,10 @@ void CNFGSetup( const char * WindowName, int w, int h )
XFlush(CNFGDisplay);
InternalLinkScreenAndGo( WindowName );
+
+ Atom WM_DELETE_WINDOW = XInternAtom( CNFGDisplay, "WM_DELETE_WINDOW", False );
+ XSetWMProtocols( CNFGDisplay, CNFGWindow, &WM_DELETE_WINDOW, 1 );
+ XSelectInput( CNFGDisplay, CNFGWindow, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | ExposureMask | PointerMotionMask );
}
void CNFGHandleInput()
@@ -147,13 +163,9 @@ void CNFGHandleInput()
int bKeyDirection = 1;
int r;
- while( (r=XCheckMaskEvent( CNFGDisplay, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | ExposureMask | PointerMotionMask , &report )) )
+ while( XPending( CNFGDisplay ) )
{
-// XEvent nev;
-// XPeekEvent(CNFGDisplay, &nev);
-
- //printf( "EVENT %d\n", report.type );
- //XMaskEvent(CNFGDisplay, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | ExposureMask, &report);
+ r=XNextEvent( CNFGDisplay, &report );
bKeyDirection = 1;
switch (report.type)
@@ -182,6 +194,10 @@ void CNFGHandleInput()
case MotionNotify:
HandleMotion( report.xmotion.x, report.xmotion.y, ButtonsDown>>1 );
break;
+ case ClientMessage:
+ // Only subscribed to WM_DELETE_WINDOW, so just exit
+ exit( 0 );
+ break;
default:
printf( "Event: %d\n", report.type );
}