2006-11-26 03:43:56 -07:00
|
|
|
/*
|
|
|
|
|
|
|
|
Copyright 1993, 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 OPEN GROUP 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 The Open Group 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 Open Group.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <X11/Xos.h>
|
|
|
|
#include <X11/Xlib.h>
|
|
|
|
#include <X11/Xutil.h>
|
|
|
|
#include <X11/cursorfont.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
/*
|
|
|
|
* Other_stuff.h: Definitions of routines in other_stuff.
|
|
|
|
*
|
|
|
|
* Written by Mark Lillibridge. Last updated 7/1/87
|
|
|
|
*/
|
|
|
|
|
2008-08-27 13:24:47 -06:00
|
|
|
#include "clientwin.h"
|
2006-11-26 03:43:56 -07:00
|
|
|
#include "dsimple.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Just_display: A group of routines designed to make the writting of simple
|
|
|
|
* X11 applications which open a display but do not open
|
|
|
|
* any windows much faster and easier. Unless a routine says
|
|
|
|
* otherwise, it may be assumed to require program_name, dpy,
|
|
|
|
* and screen already defined on entry.
|
|
|
|
*
|
|
|
|
* Written by Mark Lillibridge. Last updated 7/1/87
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/* This stuff is defined in the calling program by just_display.h */
|
2013-08-17 10:38:10 -06:00
|
|
|
const char *program_name = "unknown_program";
|
2006-11-26 03:43:56 -07:00
|
|
|
Display *dpy = NULL;
|
|
|
|
int screen = 0;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get_Display_Name (argc, argv) Look for -display, -d, or host:dpy (obselete)
|
|
|
|
* If found, remove it from command line. Don't go past a lone -.
|
|
|
|
*/
|
2008-08-27 13:24:47 -06:00
|
|
|
char *Get_Display_Name(
|
|
|
|
int *pargc, /* MODIFIED */
|
|
|
|
char **argv) /* MODIFIED */
|
2006-11-26 03:43:56 -07:00
|
|
|
{
|
|
|
|
int argc = *pargc;
|
|
|
|
char **pargv = argv+1;
|
|
|
|
char *displayname = NULL;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 1; i < argc; i++) {
|
|
|
|
char *arg = argv[i];
|
|
|
|
|
|
|
|
if (!strcmp (arg, "-display") || !strcmp (arg, "-d")) {
|
|
|
|
if (++i >= argc) usage ();
|
|
|
|
|
|
|
|
displayname = argv[i];
|
|
|
|
*pargc -= 2;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!strcmp(arg,"-")) {
|
|
|
|
while (i<argc)
|
|
|
|
*pargv++ = argv[i++];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
*pargv++ = arg;
|
|
|
|
}
|
|
|
|
|
|
|
|
*pargv = NULL;
|
|
|
|
return (displayname);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Open_Display: Routine to open a display with correct error handling.
|
|
|
|
* Does not require dpy or screen defined on entry.
|
|
|
|
*/
|
2008-08-27 13:24:47 -06:00
|
|
|
Display *Open_Display(const char *display_name)
|
2006-11-26 03:43:56 -07:00
|
|
|
{
|
|
|
|
Display *d;
|
|
|
|
|
|
|
|
d = XOpenDisplay(display_name);
|
|
|
|
if (d == NULL) {
|
|
|
|
fprintf (stderr, "%s: unable to open display '%s'\n",
|
|
|
|
program_name, XDisplayName (display_name));
|
2009-10-24 09:34:20 -06:00
|
|
|
exit(1);
|
2006-11-26 03:43:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return(d);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Setup_Display_And_Screen: This routine opens up the correct display (i.e.,
|
|
|
|
* it calls Get_Display_Name) and then stores a
|
|
|
|
* pointer to it in dpy. The default screen
|
|
|
|
* for this display is then stored in screen.
|
|
|
|
* Does not require dpy or screen defined.
|
|
|
|
*/
|
2008-08-27 13:24:47 -06:00
|
|
|
void Setup_Display_And_Screen(
|
|
|
|
int *argc, /* MODIFIED */
|
|
|
|
char **argv) /* MODIFIED */
|
2006-11-26 03:43:56 -07:00
|
|
|
{
|
2008-08-27 13:24:47 -06:00
|
|
|
char *displayname = NULL;
|
|
|
|
|
2006-11-26 03:43:56 -07:00
|
|
|
displayname = Get_Display_Name(argc, argv);
|
2008-08-27 13:24:47 -06:00
|
|
|
dpy = Open_Display (displayname);
|
|
|
|
screen = XDefaultScreen(dpy);
|
2006-11-26 03:43:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Close_Display: Close display
|
|
|
|
*/
|
|
|
|
void Close_Display(void)
|
|
|
|
{
|
|
|
|
if (dpy == NULL)
|
|
|
|
return;
|
2013-08-17 10:38:10 -06:00
|
|
|
|
2008-08-27 13:24:47 -06:00
|
|
|
XCloseDisplay(dpy);
|
|
|
|
dpy = NULL;
|
2006-11-26 03:43:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Select_Window_Args: a rountine to provide a common interface for
|
|
|
|
* applications that need to allow the user to select one
|
|
|
|
* window on the screen for special consideration.
|
|
|
|
* This routine implements the following command line
|
|
|
|
* arguments:
|
|
|
|
*
|
|
|
|
* -root Selects the root window.
|
|
|
|
* -id <id> Selects window with id <id>. <id> may
|
|
|
|
* be either in decimal or hex.
|
|
|
|
* -name <name> Selects the window with name <name>.
|
|
|
|
*
|
|
|
|
* Call as Select_Window_Args(&argc, argv) in main before
|
|
|
|
* parsing any of your program's command line arguments.
|
|
|
|
* Select_Window_Args will remove its arguments so that
|
|
|
|
* your program does not have to worry about them.
|
|
|
|
* The window returned is the window selected or 0 if
|
|
|
|
* none of the above arguments was present. If 0 is
|
|
|
|
* returned, Select_Window should probably be called after
|
|
|
|
* all command line arguments, and other setup is done.
|
|
|
|
* For examples of usage, see xwininfo, xwd, or xprop.
|
|
|
|
*/
|
2008-08-27 13:24:47 -06:00
|
|
|
Window Select_Window_Args(
|
|
|
|
int *rargc,
|
|
|
|
char **argv)
|
2006-11-26 03:43:56 -07:00
|
|
|
#define ARGC (*rargc)
|
|
|
|
{
|
|
|
|
int nargc=1;
|
|
|
|
int argc;
|
|
|
|
char **nargv;
|
|
|
|
Window w=0;
|
|
|
|
|
|
|
|
nargv = argv+1; argc = ARGC;
|
|
|
|
#define OPTION argv[0]
|
|
|
|
#define NXTOPTP ++argv, --argc>0
|
|
|
|
#define NXTOPT if (++argv, --argc==0) usage()
|
|
|
|
#define COPYOPT nargv++[0]=OPTION, nargc++
|
|
|
|
|
|
|
|
while (NXTOPTP) {
|
|
|
|
if (!strcmp(OPTION, "-")) {
|
|
|
|
COPYOPT;
|
|
|
|
while (NXTOPTP)
|
|
|
|
COPYOPT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!strcmp(OPTION, "-root")) {
|
|
|
|
w=RootWindow(dpy, screen);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!strcmp(OPTION, "-name")) {
|
|
|
|
NXTOPT;
|
|
|
|
w = Window_With_Name(dpy, RootWindow(dpy, screen),
|
|
|
|
OPTION);
|
|
|
|
if (!w)
|
|
|
|
Fatal_Error("No window with name %s exists!",OPTION);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!strcmp(OPTION, "-id")) {
|
|
|
|
NXTOPT;
|
|
|
|
w=0;
|
|
|
|
sscanf(OPTION, "0x%lx", &w);
|
|
|
|
if (!w)
|
|
|
|
sscanf(OPTION, "%lu", &w);
|
|
|
|
if (!w)
|
|
|
|
Fatal_Error("Invalid window id format: %s.", OPTION);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
COPYOPT;
|
|
|
|
}
|
|
|
|
ARGC = nargc;
|
2013-08-17 10:38:10 -06:00
|
|
|
|
2006-11-26 03:43:56 -07:00
|
|
|
return(w);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Other_stuff: A group of routines which do common X11 tasks.
|
|
|
|
*
|
|
|
|
* Written by Mark Lillibridge. Last updated 7/1/87
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Routine to let user select a window using the mouse
|
|
|
|
*/
|
|
|
|
|
2012-02-28 13:47:43 -07:00
|
|
|
Window Select_Window(Display *disp, int descend)
|
2006-11-26 03:43:56 -07:00
|
|
|
{
|
|
|
|
int status;
|
|
|
|
Cursor cursor;
|
|
|
|
XEvent event;
|
2012-02-28 13:47:43 -07:00
|
|
|
Window target_win = None, root = RootWindow(disp,screen);
|
2006-11-26 03:43:56 -07:00
|
|
|
int buttons = 0;
|
|
|
|
|
|
|
|
/* Make the target cursor */
|
2012-02-28 13:47:43 -07:00
|
|
|
cursor = XCreateFontCursor(disp, XC_crosshair);
|
2006-11-26 03:43:56 -07:00
|
|
|
|
|
|
|
/* Grab the pointer using target cursor, letting it room all over */
|
2012-02-28 13:47:43 -07:00
|
|
|
status = XGrabPointer(disp, root, False,
|
2006-11-26 03:43:56 -07:00
|
|
|
ButtonPressMask|ButtonReleaseMask, GrabModeSync,
|
|
|
|
GrabModeAsync, root, cursor, CurrentTime);
|
|
|
|
if (status != GrabSuccess) Fatal_Error("Can't grab the mouse.");
|
|
|
|
|
|
|
|
/* Let the user select a window... */
|
|
|
|
while ((target_win == None) || (buttons != 0)) {
|
|
|
|
/* allow one more event */
|
2012-02-28 13:47:43 -07:00
|
|
|
XAllowEvents(disp, SyncPointer, CurrentTime);
|
|
|
|
XWindowEvent(disp, root, ButtonPressMask|ButtonReleaseMask, &event);
|
2006-11-26 03:43:56 -07:00
|
|
|
switch (event.type) {
|
|
|
|
case ButtonPress:
|
|
|
|
if (target_win == None) {
|
|
|
|
target_win = event.xbutton.subwindow; /* window selected */
|
|
|
|
if (target_win == None) target_win = root;
|
|
|
|
}
|
|
|
|
buttons++;
|
|
|
|
break;
|
|
|
|
case ButtonRelease:
|
|
|
|
if (buttons > 0) /* there may have been some down before we started */
|
|
|
|
buttons--;
|
|
|
|
break;
|
|
|
|
}
|
2013-08-17 10:38:10 -06:00
|
|
|
}
|
2006-11-26 03:43:56 -07:00
|
|
|
|
2012-02-28 13:47:43 -07:00
|
|
|
XUngrabPointer(disp, CurrentTime); /* Done with pointer */
|
2006-11-26 03:43:56 -07:00
|
|
|
|
2008-08-27 13:24:47 -06:00
|
|
|
if (!descend || (target_win == root))
|
|
|
|
return(target_win);
|
|
|
|
|
2012-02-28 13:47:43 -07:00
|
|
|
target_win = Find_Client(disp, root, target_win);
|
2008-08-27 13:24:47 -06:00
|
|
|
|
2006-11-26 03:43:56 -07:00
|
|
|
return(target_win);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Window_With_Name: routine to locate a window with a given name on a display.
|
|
|
|
* If no window with the given name is found, 0 is returned.
|
|
|
|
* If more than one window has the given name, the first
|
|
|
|
* one found will be returned. Only top and its subwindows
|
|
|
|
* are looked at. Normally, top should be the RootWindow.
|
|
|
|
*/
|
2008-08-27 13:24:47 -06:00
|
|
|
Window Window_With_Name(
|
2012-02-28 13:47:43 -07:00
|
|
|
Display *disp,
|
2008-08-27 13:24:47 -06:00
|
|
|
Window top,
|
|
|
|
const char *name)
|
2006-11-26 03:43:56 -07:00
|
|
|
{
|
|
|
|
Window *children, dummy;
|
|
|
|
unsigned int nchildren;
|
2013-08-17 10:38:10 -06:00
|
|
|
unsigned int i;
|
2006-11-26 03:43:56 -07:00
|
|
|
Window w=0;
|
|
|
|
char *window_name;
|
|
|
|
|
2012-02-28 13:47:43 -07:00
|
|
|
if (XFetchName(disp, top, &window_name) && !strcmp(window_name, name))
|
2006-11-26 03:43:56 -07:00
|
|
|
return(top);
|
|
|
|
|
2012-02-28 13:47:43 -07:00
|
|
|
if (!XQueryTree(disp, top, &dummy, &dummy, &children, &nchildren))
|
2006-11-26 03:43:56 -07:00
|
|
|
return(0);
|
|
|
|
|
|
|
|
for (i=0; i<nchildren; i++) {
|
2012-02-28 13:47:43 -07:00
|
|
|
w = Window_With_Name(disp, children[i], name);
|
2006-11-26 03:43:56 -07:00
|
|
|
if (w)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (children) XFree ((char *)children);
|
|
|
|
return(w);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* outl: a debugging routine. Flushes stdout then prints a message on stderr
|
|
|
|
* and flushes stderr. Used to print messages when past certain points
|
2013-08-17 10:38:10 -06:00
|
|
|
* in code so we can tell where we are. Outl may be invoked like printf.
|
2006-11-26 03:43:56 -07:00
|
|
|
*/
|
|
|
|
void
|
2013-08-17 10:38:10 -06:00
|
|
|
outl(const char *msg, ...)
|
2006-11-26 03:43:56 -07:00
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
fflush(stdout);
|
|
|
|
va_start(args, msg);
|
|
|
|
vfprintf(stderr, msg, args);
|
|
|
|
va_end(args);
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
fflush(stderr);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2013-08-17 10:38:10 -06:00
|
|
|
* Standard fatal error routine - call like printf.
|
2006-11-26 03:43:56 -07:00
|
|
|
* Does not require dpy or screen defined.
|
|
|
|
*/
|
2013-08-17 10:38:10 -06:00
|
|
|
void Fatal_Error(const char *msg, ...)
|
2006-11-26 03:43:56 -07:00
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
fflush(stdout);
|
|
|
|
fflush(stderr);
|
|
|
|
fprintf(stderr, "%s: error: ", program_name);
|
|
|
|
va_start(args, msg);
|
|
|
|
vfprintf(stderr, msg, args);
|
|
|
|
va_end(args);
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
Close_Display();
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|