/* $Id: selwin.c,v 1.1 91/04/25 15:32:01 sao Exp Locker: sao $ */

/*
 * Copyright (C) 1990 by Digital Equipment Corporation.
 * 
 * Author: Michael P. Altenhofen, CEC Karlsruhe e-mail:
 * Altenhofen@kampus.enet.dec.com
 * 
 * This file ist part of Shared X
 * 
 * Permission to use, copy, modify, and distribute this software and its
 * documentation without fee is hereby granted, but only for non-profit  use
 * and distribution,  and provided  that the copyright notice and this notice
 * is preserved on all copies.
 * 
 * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */

#include <stdio.h>
/*#include <stdlib.h>*/
#include <X11/Xlib.h>
#include <X11/cursorfont.h>

Window
Select_Window (dpy)
  Display *dpy;
{
  int status;
  XEvent event;
  Window target_win = None;
  int buttons = 0;
  char message[256];		/* , *curr_str; */
  Cursor cursor;

  bzero (message, 256);

  /* Make the target cursor */
  cursor = XCreateFontCursor (dpy, XC_crosshair);

  /* Grab the pointer using target cursor, letting it room all over */
  status = XGrabPointer (dpy, RootWindow (dpy, DefaultScreen (dpy)), False,
			 ButtonPressMask | ButtonReleaseMask, GrabModeSync,
			 GrabModeAsync, None, cursor, CurrentTime);
  if (status != GrabSuccess) {
    printf ("Can't grab the mouse.");
    exit (1);
  }

  /* Let the user select a window... */
  while ((target_win == None) || (buttons != 0)) {
    /* allow one more event */
    XAllowEvents (dpy, SyncPointer, CurrentTime);
    XWindowEvent (dpy, RootWindow (dpy, DefaultScreen (dpy)),
		  ButtonPressMask | ButtonReleaseMask, &event);
    switch (event.type) {
    case ButtonPress:
      if (target_win == None) {
	Window child, win, root;
	int rx, ry, x, y, keys;
	char *win_name = NULL;

	child = event.xbutton.subwindow;
	if (!child)
	  child = RootWindow (dpy, DefaultScreen (dpy));

	win = child;
	XFetchName (dpy, child, &win_name);

	/*
	 * Go down the tree: stop at the first toplevel window. A window
	 * manager may fool us by creating a "pseudo root".  That's why we
	 * use the win_name here
	 */
	while (child
	       && child != RootWindow (dpy, DefaultScreen (dpy))
	       && win_name == NULL) {
	  target_win = win;
	  XFetchName (dpy, target_win, &win_name);
	  XQueryPointer (dpy, win, &root, &child, &rx, &ry, &x, &y, &keys);
	  win = child;
	}
	if (target_win == None)
	  target_win = event.xbutton.subwindow
	    ? event.xbutton.subwindow
	    : RootWindow (dpy, DefaultScreen (dpy));
      }
      buttons++;
      break;
    case ButtonRelease:
      if (buttons > 0)		/* there may have been some down before we
				 * started */
	buttons--;
      break;
    }
  }

  XUngrabPointer (dpy, CurrentTime);	/* Done with pointer */
  return (target_win);
}
