dsimple.c revision a005d216
1/* $Xorg: dsimple.c,v 1.4 2001/02/09 02:05:54 xorgcvs Exp $ */ 2/* 3 4Copyright 1993, 1998 The Open Group 5 6Permission to use, copy, modify, distribute, and sell this software and its 7documentation for any purpose is hereby granted without fee, provided that 8the above copyright notice appear in all copies and that both that 9copyright notice and this permission notice appear in supporting 10documentation. 11 12The above copyright notice and this permission notice shall be included 13in all copies or substantial portions of the Software. 14 15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 19OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 21OTHER DEALINGS IN THE SOFTWARE. 22 23Except as contained in this notice, the name of The Open Group shall 24not be used in advertising or otherwise to promote the sale, use or 25other dealings in this Software without prior written authorization 26from The Open Group. 27 28*/ 29/* $XFree86: xc/programs/xlsfonts/dsimple.c,v 3.6 2001/12/14 20:02:09 dawes Exp $ */ 30 31#include <X11/Xos.h> 32#include <X11/Xlib.h> 33#include <X11/Xutil.h> 34#include <X11/cursorfont.h> 35#include <stdio.h> 36#include <stdlib.h> 37#include <stdarg.h> 38/* 39 * Other_stuff.h: Definitions of routines in other_stuff. 40 * 41 * Written by Mark Lillibridge. Last updated 7/1/87 42 */ 43 44#include "clientwin.h" 45#include "dsimple.h" 46 47/* 48 * Just_display: A group of routines designed to make the writing of simple 49 * X11 applications which open a display but do not open 50 * any windows much faster and easier. Unless a routine says 51 * otherwise, it may be assumed to require program_name, dpy, 52 * and screen already defined on entry. 53 * 54 * Written by Mark Lillibridge. Last updated 7/1/87 55 */ 56 57 58/* This stuff is defined in the calling program by just_display.h */ 59char *program_name = "unknown_program"; 60Display *dpy = NULL; 61int screen = 0; 62 63 64/* 65 * Get_Display_Name (argc, argv) Look for -display, -d, or host:dpy (obselete) 66 * If found, remove it from command line. Don't go past a lone -. 67 */ 68char *Get_Display_Name( 69 int *pargc, /* MODIFIED */ 70 char **argv) /* MODIFIED */ 71{ 72 int argc = *pargc; 73 char **pargv = argv+1; 74 char *displayname = NULL; 75 int i; 76 77 for (i = 1; i < argc; i++) { 78 char *arg = argv[i]; 79 80 if (!strcmp (arg, "-display") || !strcmp (arg, "-d")) { 81 if (++i >= argc) usage (); 82 83 displayname = argv[i]; 84 *pargc -= 2; 85 continue; 86 } 87 if (!strcmp(arg,"-")) { 88 while (i<argc) 89 *pargv++ = argv[i++]; 90 break; 91 } 92 *pargv++ = arg; 93 } 94 95 *pargv = NULL; 96 return (displayname); 97} 98 99 100 101/* 102 * Open_Display: Routine to open a display with correct error handling. 103 * Does not require dpy or screen defined on entry. 104 */ 105Display *Open_Display(char *display_name) 106{ 107 Display *d; 108 109 d = XOpenDisplay(display_name); 110 if (d == NULL) { 111 fprintf (stderr, "%s: unable to open display '%s'\n", 112 program_name, XDisplayName (display_name)); 113 usage (); 114 /* doesn't return */ 115 } 116 117 return(d); 118} 119 120 121/* 122 * Setup_Display_And_Screen: This routine opens up the correct display (i.e., 123 * it calls Get_Display_Name) and then stores a 124 * pointer to it in dpy. The default screen 125 * for this display is then stored in screen. 126 * Does not require dpy or screen defined. 127 */ 128void Setup_Display_And_Screen( 129 int *argc, /* MODIFIED */ 130 char **argv) /* MODIFIED */ 131{ 132 char *displayname = NULL; 133 134 displayname = Get_Display_Name(argc, argv); 135 dpy = Open_Display (displayname); 136 screen = XDefaultScreen(dpy); 137} 138 139/* 140 * Close_Display: Close display 141 */ 142void Close_Display(void) 143{ 144 if (dpy == NULL) 145 return; 146 147 XCloseDisplay(dpy); 148 dpy = NULL; 149} 150 151 152/* 153 * Select_Window_Args: a rountine to provide a common interface for 154 * applications that need to allow the user to select one 155 * window on the screen for special consideration. 156 * This routine implements the following command line 157 * arguments: 158 * 159 * -root Selects the root window. 160 * -id <id> Selects window with id <id>. <id> may 161 * be either in decimal or hex. 162 * -name <name> Selects the window with name <name>. 163 * 164 * Call as Select_Window_Args(&argc, argv) in main before 165 * parsing any of your program's command line arguments. 166 * Select_Window_Args will remove its arguments so that 167 * your program does not have to worry about them. 168 * The window returned is the window selected or 0 if 169 * none of the above arguments was present. If 0 is 170 * returned, Select_Window should probably be called after 171 * all command line arguments, and other setup is done. 172 * For examples of usage, see xwininfo, xwd, or xprop. 173 */ 174Window Select_Window_Args( 175 int *rargc, 176 char **argv) 177#define ARGC (*rargc) 178{ 179 int nargc=1; 180 int argc; 181 char **nargv; 182 Window w=0; 183 184 nargv = argv+1; argc = ARGC; 185#define OPTION argv[0] 186#define NXTOPTP ++argv, --argc>0 187#define NXTOPT if (++argv, --argc==0) usage() 188#define COPYOPT nargv++[0]=OPTION, nargc++ 189 190 while (NXTOPTP) { 191 if (!strcmp(OPTION, "-")) { 192 COPYOPT; 193 while (NXTOPTP) 194 COPYOPT; 195 break; 196 } 197 if (!strcmp(OPTION, "-root")) { 198 w=RootWindow(dpy, screen); 199 continue; 200 } 201 if (!strcmp(OPTION, "-name")) { 202 NXTOPT; 203 w = Window_With_Name(dpy, RootWindow(dpy, screen), 204 OPTION); 205 if (!w) 206 Fatal_Error("No window with name %s exists!",OPTION); 207 continue; 208 } 209 if (!strcmp(OPTION, "-id")) { 210 NXTOPT; 211 w=0; 212 sscanf(OPTION, "0x%lx", &w); 213 if (!w) 214 sscanf(OPTION, "%lu", &w); 215 if (!w) 216 Fatal_Error("Invalid window id format: %s.", OPTION); 217 continue; 218 } 219 COPYOPT; 220 } 221 ARGC = nargc; 222 223 return(w); 224} 225 226/* 227 * Other_stuff: A group of routines which do common X11 tasks. 228 * 229 * Written by Mark Lillibridge. Last updated 7/1/87 230 */ 231 232 233/* 234 * Routine to let user select a window using the mouse 235 */ 236 237Window Select_Window(Display *dpy, int descend) 238{ 239 int status; 240 Cursor cursor; 241 XEvent event; 242 Window target_win = None, root = RootWindow(dpy,screen); 243 int buttons = 0; 244 245 /* Make the target cursor */ 246 cursor = XCreateFontCursor(dpy, XC_crosshair); 247 248 /* Grab the pointer using target cursor, letting it room all over */ 249 status = XGrabPointer(dpy, root, False, 250 ButtonPressMask|ButtonReleaseMask, GrabModeSync, 251 GrabModeAsync, root, cursor, CurrentTime); 252 if (status != GrabSuccess) Fatal_Error("Can't grab the mouse."); 253 254 /* Let the user select a window... */ 255 while ((target_win == None) || (buttons != 0)) { 256 /* allow one more event */ 257 XAllowEvents(dpy, SyncPointer, CurrentTime); 258 XWindowEvent(dpy, root, ButtonPressMask|ButtonReleaseMask, &event); 259 switch (event.type) { 260 case ButtonPress: 261 if (target_win == None) { 262 target_win = event.xbutton.subwindow; /* window selected */ 263 if (target_win == None) target_win = root; 264 } 265 buttons++; 266 break; 267 case ButtonRelease: 268 if (buttons > 0) /* there may have been some down before we started */ 269 buttons--; 270 break; 271 } 272 } 273 274 XUngrabPointer(dpy, CurrentTime); /* Done with pointer */ 275 276 if (!descend || (target_win == root)) 277 return(target_win); 278 279 target_win = Find_Client(dpy, root, target_win); 280 281 return(target_win); 282} 283 284 285/* 286 * Window_With_Name: routine to locate a window with a given name on a display. 287 * If no window with the given name is found, 0 is returned. 288 * If more than one window has the given name, the first 289 * one found will be returned. Only top and its subwindows 290 * are looked at. Normally, top should be the RootWindow. 291 */ 292Window Window_With_Name( 293 Display *dpy, 294 Window top, 295 char *name) 296{ 297 Window *children, dummy; 298 unsigned int nchildren; 299 int i; 300 Window w=0; 301 char *window_name; 302 303 if (XFetchName(dpy, top, &window_name) && !strcmp(window_name, name)) 304 return(top); 305 306 if (!XQueryTree(dpy, top, &dummy, &dummy, &children, &nchildren)) 307 return(0); 308 309 for (i=0; i<nchildren; i++) { 310 w = Window_With_Name(dpy, children[i], name); 311 if (w) 312 break; 313 } 314 if (children) XFree ((char *)children); 315 return(w); 316} 317 318 319/* 320 * Standard fatal error routine - call like printf 321 * Does not require dpy or screen defined. 322 */ 323void Fatal_Error(char *msg, ...) 324{ 325 va_list args; 326 fflush(stdout); 327 fflush(stderr); 328 fprintf(stderr, "%s: error: ", program_name); 329 va_start(args, msg); 330 vfprintf(stderr, msg, args); 331 va_end(args); 332 fprintf(stderr, "\n"); 333 Close_Display(); 334 exit(EXIT_FAILURE); 335} 336