cnping

Minimal Graphical Ping Tool
git clone https://git.sinitax.com/cnlohr/cnping
Log | Files | Refs | Submodules | README | LICENSE | sfeed.txt

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:
MDrawFunctions.h | 1+
MWinDriver.c | 7++++++-
MXDriver.c | 28++++++++++++++++++++++------
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 ); }