From: Ian Osgood Date: Wed, 22 Mar 2006 02:29:35 +0000 (-0800) Subject: Support WM_DELETE_WINDOW, WMHints. X-Git-Tag: 0.1~18^2~1 X-Git-Url: http://git.demorecorder.com/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2b62c1acc0f968e75ae2792194230f50b69e10fd;p=free-sw%2Fxcb%2Fdemo Support WM_DELETE_WINDOW, WMHints. --- diff --git a/neko/README b/neko/README index 1902013..e334aff 100644 --- a/neko/README +++ b/neko/README @@ -8,11 +8,12 @@ XCB TODO * -root needs testing (Mac X is rootless) * DEBUG not supported * -geometry not supported -* WM hints, -iconic not supported (don't like the util interfaces) +* -iconic not supported (don't like the util interfaces) XCB ENHANCEMENTS ---------------- * autoconf +* use WM_DELETE_WINDOW protocol * too many globals! refactor * no X resource cleanup. OK? * convert to use threading diff --git a/neko/xcbneko.c b/neko/xcbneko.c index bd7b706..ea12c6e 100644 --- a/neko/xcbneko.c +++ b/neko/xcbneko.c @@ -141,15 +141,14 @@ char *fgColor, *bgColor; static char *ProgramName; -/*Display *theDisplay;*/ XCBConnection *xc; XCBSCREEN *theScreen; /* instead of macro(theDisplay, int theScreen) */ -unsigned int theDepth; unsigned long theBlackPixel; unsigned long theWhitePixel; XCBWINDOW theWindow; XCBCURSOR theCursor; XCBKeySymbols *theKeySyms; +XCBATOM deleteWindowAtom; static unsigned int WindowWidth; static unsigned int WindowHeight; @@ -513,11 +512,25 @@ void InitBitmapAndGCs(void) { /* later: XCBFreeGC( c, gc ); */ } +XCBATOM +GetAtom(XCBConnection *c, const char *atomName) +{ + XCBATOM atom = { XCBNone }; + XCBInternAtomRep *r = XCBInternAtomReply(c, + XCBInternAtom(c, 0, strlen(atomName), atomName), NULL); + if (r) { + atom = r->atom; + free(r); + } + return atom; +} + void InitScreen( char *DisplayName, char *theGeometry, char *theTitle, Bool iconicState ) { XCBPIXMAP theCursorSource; XCBPIXMAP theCursorMask; + unsigned int theDepth; XCBCOLORMAP theColormap; int screen; @@ -629,19 +642,13 @@ InitScreen( char *DisplayName, char *theGeometry, char *theTitle, Bool iconicSta theScreen->root_visual, /* CopyFromParent */ theWindowMask, theWindowAttributes ); + /* new: obey the window-delete protocol, look for XCBClientMessage */ + deleteWindowAtom = GetAtom(xc, "WM_DELETE_WINDOW"); + SetWMProtocols( xc, theWindow, 1, &deleteWindowAtom ); + theIconPixmap = CreateBitmapFromData( xc, theWindow, icon_bits, icon_width, icon_height ); - #ifdef TODO_ICCCM - /* Um... there is no function to send the hints... - WMHints theWMHints; - WMHintsSetIconPixmap( &theHints, theIconPixmap ); - - if ( iconicState ) - WMHintsSetIconic( &theHints ); - else - WMHintsSetNormal( &theHints ); - */ theWMHints.icon_pixmap = theIconPixmap; if ( iconicState ) @@ -652,36 +659,37 @@ InitScreen( char *DisplayName, char *theGeometry, char *theTitle, Bool iconicSta theWMHints.flags = IconPixmapHint | StateHint; XSetWMHints( theDisplay, theWindow, &theWMHints ); -#endif +#else + /* Um... there is no function to send the hints... + WMHints theWMHints; + WMHintsSetIconPixmap( &theHints, theIconPixmap ); -#ifdef TODO_ICCCM - /* - SizeHints *hints = AllocSizeHints(); - SizeHintsSetPosition(hints, WindowPointX, WindowPointY); - SizeHintsSetSize(hints, WindowWidth, WindowHeight); - SetWMNormalHints(xc, theWindow, hints); - FreeSizeHints(hints); - */ - XSizeHints theSizeHints; - - theSizeHints.flags = PPosition | PSize; - theSizeHints.x = WindowPointX; - theSizeHints.y = WindowPointY; - theSizeHints.width = WindowWidth; - theSizeHints.height = WindowHeight; - - XSetNormalHints( theDisplay, theWindow, &theSizeHints ); + if ( iconicState ) + WMHintsSetIconic( &theHints ); + else + WMHintsSetNormal( &theHints ); + + Now what? + */ #endif + /* why hide the structure? */ + SizeHints *theSizeHints = AllocSizeHints(); + + /* need enum for second param (user specified) */ + SizeHintsSetPosition(theSizeHints, 0, WindowPointX, WindowPointY); + SizeHintsSetSize(theSizeHints, 0, WindowWidth, WindowHeight); + + SetWMNormalHints(xc, theWindow, theSizeHints); + + FreeSizeHints(theSizeHints); + /* Um, why do I have to specify the encoding in this API? */ SetWMName( xc, theWindow, STRING, strlen(theTitle), theTitle ); SetWMIconName( xc, theWindow, STRING, strlen(theTitle), theTitle ); XCBMapWindow( xc, theWindow ); - /* moved to the CreateWindow attribute list */ - /* XSelectInput( theDisplay, theWindow, EVENT_MASK ); */ - } #ifdef TODO @@ -1154,6 +1162,11 @@ void NekoAdjust(void) { NekoY = WindowHeight - BITMAP_HEIGHT; } +int IsDeleteMessage(XCBClientMessageEvent *msg) +{ + return msg->data.data32[0] == deleteWindowAtom.xid; +} + Bool ProcessEvent(void) { XCBGenericEvent *theEvent; XCBConfigureNotifyEvent *theConfigureNotification; @@ -1164,8 +1177,9 @@ Bool ProcessEvent(void) { switch ( EventState ) { case NORMAL_STATE: - while ( NULL != (theEvent = XCBPollForEvent( xc, &error )) ) { /*while ( XCheckMaskEvent( theDisplay, EVENT_MASK, &theEvent ) ) {*/ - switch ( theEvent->response_type ) { + while ( ContinueState && + NULL != (theEvent = XCBPollForEvent( xc, &error )) ) { /*while ( XCheckMaskEvent( theDisplay, EVENT_MASK, &theEvent ) ) {*/ + switch ( theEvent->response_type & 0x7f ) { case XCBConfigureNotify: theConfigureNotification = (XCBConfigureNotifyEvent *)theEvent; WindowWidth = theConfigureNotification->width; @@ -1185,26 +1199,24 @@ Bool ProcessEvent(void) { break; case XCBKeyPress: ContinueState = ProcessKeyPress( (XCBKeyPressEvent *)theEvent ); - if ( !ContinueState ) { - free(theEvent); - return( ContinueState ); - } break; case XCBButtonPress: theButtonPress = (XCBButtonPressEvent *)theEvent; - if ( theButtonPress->detail.id == 3 ) { /* xbutton.button */ - free(theEvent); - return( False ); - } + ContinueState = ( theButtonPress->detail.id != 3 ); /* xbutton.button */ break; + /* new: handle ClientMessage */ + case XCBClientMessage: + ContinueState = !IsDeleteMessage((XCBClientMessageEvent *)theEvent); + break; default: /* Unknown Event */ + /*printf("event type:%x\n", (int)theEvent->response_type);*/ break; } free(theEvent); if (error != 0) return False; - } + } /* end while */ break; #ifdef DEBUG case DEBUG_LIST: