dsimple.c revision afe13c8e
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 writting 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 * Open_Display: Routine to open a display with correct error handling. 102 * Does not require dpy or screen defined on entry. 103 */ 104Display *Open_Display(const char *display_name) 105{ 106 Display *d; 107 108 d = XOpenDisplay(display_name); 109 if (d == NULL) { 110 fprintf (stderr, "%s: unable to open display '%s'\n", 111 program_name, XDisplayName (display_name)); 112 usage (); 113 /* doesn't return */ 114 } 115 116 return(d); 117} 118 119 120/* 121 * Setup_Display_And_Screen: This routine opens up the correct display (i.e., 122 * it calls Get_Display_Name) and then stores a 123 * pointer to it in dpy. The default screen 124 * for this display is then stored in screen. 125 * Does not require dpy or screen defined. 126 */ 127void Setup_Display_And_Screen( 128 int *argc, /* MODIFIED */ 129 char **argv) /* MODIFIED */ 130{ 131 char *displayname = NULL; 132 133 displayname = Get_Display_Name(argc, argv); 134 dpy = Open_Display (displayname); 135 screen = XDefaultScreen(dpy); 136} 137 138/* 139 * Close_Display: Close display 140 */ 141void Close_Display(void) 142{ 143 if (dpy == NULL) 144 return; 145 146 XCloseDisplay(dpy); 147 dpy = NULL; 148} 149 150 151/* 152 * Select_Window_Args: a rountine to provide a common interface for 153 * applications that need to allow the user to select one 154 * window on the screen for special consideration. 155 * This routine implements the following command line 156 * arguments: 157 * 158 * -root Selects the root window. 159 * -id <id> Selects window with id <id>. <id> may 160 * be either in decimal or hex. 161 * -name <name> Selects the window with name <name>. 162 * 163 * Call as Select_Window_Args(&argc, argv) in main before 164 * parsing any of your program's command line arguments. 165 * Select_Window_Args will remove its arguments so that 166 * your program does not have to worry about them. 167 * The window returned is the window selected or 0 if 168 * none of the above arguments was present. If 0 is 169 * returned, Select_Window should probably be called after 170 * all command line arguments, and other setup is done. 171 * For examples of usage, see xwininfo, xwd, or xprop. 172 */ 173Window Select_Window_Args( 174 int *rargc, 175 char **argv) 176#define ARGC (*rargc) 177{ 178 int nargc=1; 179 int argc; 180 char **nargv; 181 Window w=0; 182 183 nargv = argv+1; argc = ARGC; 184#define OPTION argv[0] 185#define NXTOPTP ++argv, --argc>0 186#define NXTOPT if (++argv, --argc==0) usage() 187#define COPYOPT nargv++[0]=OPTION, nargc++ 188 189 while (NXTOPTP) { 190 if (!strcmp(OPTION, "-")) { 191 COPYOPT; 192 while (NXTOPTP) 193 COPYOPT; 194 break; 195 } 196 if (!strcmp(OPTION, "-root")) { 197 w=RootWindow(dpy, screen); 198 continue; 199 } 200 if (!strcmp(OPTION, "-name")) { 201 NXTOPT; 202 w = Window_With_Name(dpy, RootWindow(dpy, screen), 203 OPTION); 204 if (!w) 205 Fatal_Error("No window with name %s exists!",OPTION); 206 continue; 207 } 208 if (!strcmp(OPTION, "-id")) { 209 NXTOPT; 210 w=0; 211 sscanf(OPTION, "0x%lx", &w); 212 if (!w) 213 sscanf(OPTION, "%lu", &w); 214 if (!w) 215 Fatal_Error("Invalid window id format: %s.", OPTION); 216 continue; 217 } 218 COPYOPT; 219 } 220 ARGC = nargc; 221 222 return(w); 223} 224 225/* 226 * Other_stuff: A group of routines which do common X11 tasks. 227 * 228 * Written by Mark Lillibridge. Last updated 7/1/87 229 */ 230 231 232/* 233 * Routine to let user select a window using the mouse 234 */ 235 236Window Select_Window(Display *dpy, int descend) 237{ 238 int status; 239 Cursor cursor; 240 XEvent event; 241 Window target_win = None, root = RootWindow(dpy,screen); 242 int buttons = 0; 243 244 /* Make the target cursor */ 245 cursor = XCreateFontCursor(dpy, XC_crosshair); 246 247 /* Grab the pointer using target cursor, letting it room all over */ 248 status = XGrabPointer(dpy, root, False, 249 ButtonPressMask|ButtonReleaseMask, GrabModeSync, 250 GrabModeAsync, root, cursor, CurrentTime); 251 if (status != GrabSuccess) Fatal_Error("Can't grab the mouse."); 252 253 /* Let the user select a window... */ 254 while ((target_win == None) || (buttons != 0)) { 255 /* allow one more event */ 256 XAllowEvents(dpy, SyncPointer, CurrentTime); 257 XWindowEvent(dpy, root, ButtonPressMask|ButtonReleaseMask, &event); 258 switch (event.type) { 259 case ButtonPress: 260 if (target_win == None) { 261 target_win = event.xbutton.subwindow; /* window selected */ 262 if (target_win == None) target_win = root; 263 } 264 buttons++; 265 break; 266 case ButtonRelease: 267 if (buttons > 0) /* there may have been some down before we started */ 268 buttons--; 269 break; 270 } 271 } 272 273 XUngrabPointer(dpy, CurrentTime); /* Done with pointer */ 274 275 if (!descend || (target_win == root)) 276 return(target_win); 277 278 target_win = Find_Client(dpy, root, target_win); 279 280 return(target_win); 281} 282 283 284/* 285 * Window_With_Name: routine to locate a window with a given name on a display. 286 * If no window with the given name is found, 0 is returned. 287 * If more than one window has the given name, the first 288 * one found will be returned. Only top and its subwindows 289 * are looked at. Normally, top should be the RootWindow. 290 */ 291Window Window_With_Name( 292 Display *dpy, 293 Window top, 294 const char *name) 295{ 296 Window *children, dummy; 297 unsigned int nchildren; 298 int i; 299 Window w=0; 300 char *window_name; 301 302 if (XFetchName(dpy, top, &window_name) && !strcmp(window_name, name)) 303 return(top); 304 305 if (!XQueryTree(dpy, top, &dummy, &dummy, &children, &nchildren)) 306 return(0); 307 308 for (i=0; i<nchildren; i++) { 309 w = Window_With_Name(dpy, children[i], name); 310 if (w) 311 break; 312 } 313 if (children) XFree ((char *)children); 314 return(w); 315} 316 317/* 318 * outl: a debugging routine. Flushes stdout then prints a message on stderr 319 * and flushes stderr. Used to print messages when past certain points 320 * in code so we can tell where we are. Outl may be invoked like 321 * printf with up to 7 arguments. 322 */ 323void 324outl(char *msg, ...) 325{ 326 va_list args; 327 fflush(stdout); 328 va_start(args, msg); 329 vfprintf(stderr, msg, args); 330 va_end(args); 331 fprintf(stderr, "\n"); 332 fflush(stderr); 333} 334 335 336/* 337 * Standard fatal error routine - call like printf but maximum of 7 arguments. 338 * Does not require dpy or screen defined. 339 */ 340void Fatal_Error(char *msg, ...) 341{ 342 va_list args; 343 fflush(stdout); 344 fflush(stderr); 345 fprintf(stderr, "%s: error: ", program_name); 346 va_start(args, msg); 347 vfprintf(stderr, msg, args); 348 va_end(args); 349 fprintf(stderr, "\n"); 350 Close_Display(); 351 exit(EXIT_FAILURE); 352} 353