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