diff options
Diffstat (limited to 'tdm/backend/reset.c')
-rw-r--r-- | tdm/backend/reset.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/tdm/backend/reset.c b/tdm/backend/reset.c new file mode 100644 index 000000000..2c2100870 --- /dev/null +++ b/tdm/backend/reset.c @@ -0,0 +1,111 @@ +/* + +Copyright 1988, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * pseudoReset -- pretend to reset the server by killing all clients + * with windows. It will reset the server most of the time, unless + * a client remains connected with no windows. + */ + +#include "dm.h" +#include "dm_error.h" + +#include <X11/Xlib.h> + +#include <signal.h> + +/*ARGSUSED*/ +static int +ignoreErrors( Display *dspl ATTR_UNUSED, XErrorEvent *event ATTR_UNUSED ) +{ + Debug( "ignoring error\n" ); + return 0; +} + +/* + * this is mostly bogus -- but quite useful. I wish the protocol + * had some way of enumerating and identifying clients, that way + * this code wouldn't have to be this kludgy. + */ + +static void +killWindows( Window window ) +{ + Window root, parent, *children; + unsigned int child, nchildren = 0; + + while (XQueryTree( dpy, window, &root, &parent, &children, &nchildren ) + && nchildren > 0) + { + for (child = 0; child < nchildren; child++) { + Debug( "XKillClient %p\n", children[child] ); + XKillClient( dpy, children[child] ); + } + XFree( (char *)children ); + } +} + +static Jmp_buf resetJmp; + +/* ARGSUSED */ +static void +abortReset( int n ATTR_UNUSED ) +{ + Longjmp( resetJmp, 1 ); +} + +/* + * this display connection better not have any windows... + */ + +void +pseudoReset() +{ + int screen; + + if (Setjmp( resetJmp )) { + LogError( "pseudoReset timeout\n" ); + } else { + (void)Signal( SIGALRM, abortReset ); + (void)alarm( 30 ); + XSetErrorHandler( ignoreErrors ); + for (screen = 0; screen < ScreenCount (dpy); screen++) { + Debug( "pseudoReset screen %d\n", screen ); + killWindows( RootWindow( dpy, screen ) ); + } + Debug( "before XSync\n" ); + XSync( dpy, False ); + (void)alarm( 0 ); + } + Signal( SIGALRM, SIG_DFL ); + XSetErrorHandler( (XErrorHandler)0 ); + Debug( "pseudoReset done\n" ); +} |